good morning!!!!

Skip to content
Snippets Groups Projects
Commit 1529225d authored by José Carlos Nieto's avatar José Carlos Nieto
Browse files

Query builder's first fully working CRUD test.

parent b53a5a4a
No related branches found
No related tags found
No related merge requests found
...@@ -8,7 +8,8 @@ import ( ...@@ -8,7 +8,8 @@ import (
type QueryBuilder interface { type QueryBuilder interface {
Select(fields ...interface{}) QuerySelector Select(fields ...interface{}) QuerySelector
InsertInto(table string) QueryInserter InsertInto(table string) QueryInserter
//Update(table string) QueryUpdater DeleteFrom(table string) QueryDeleter
Update(table string) QueryUpdater
} }
type QuerySelector interface { type QuerySelector interface {
...@@ -18,11 +19,22 @@ type QuerySelector interface { ...@@ -18,11 +19,22 @@ type QuerySelector interface {
type QueryInserter interface { type QueryInserter interface {
Values(...interface{}) QueryInserter Values(...interface{}) QueryInserter
Columns(...string) QueryInserter Columns(...string) QueryInserter
Exec() (sql.Result, error) QueryExecer
}
type QueryDeleter interface {
Where(...interface{}) QueryDeleter
Limit(int) QueryDeleter
QueryExecer
} }
type QueryUpdater interface { type QueryUpdater interface {
Set() QueryUpdater Set(...interface{}) QueryUpdater
Where(...interface{}) QueryUpdater
Limit(int) QueryUpdater
QueryExecer
}
Do() error type QueryExecer interface {
Exec() (sql.Result, error)
} }
...@@ -25,6 +25,20 @@ func (b *Builder) InsertInto(table string) db.QueryInserter { ...@@ -25,6 +25,20 @@ func (b *Builder) InsertInto(table string) db.QueryInserter {
} }
} }
func (b *Builder) DeleteFrom(table string) db.QueryDeleter {
return &QueryDeleter{
builder: b,
table: table,
}
}
func (b *Builder) Update(table string) db.QueryUpdater {
return &QueryUpdater{
builder: b,
table: table,
}
}
type QuerySelector struct { type QuerySelector struct {
builder *Builder builder *Builder
fields []interface{} fields []interface{}
...@@ -80,3 +94,86 @@ func (qi *QueryInserter) Values(values ...interface{}) db.QueryInserter { ...@@ -80,3 +94,86 @@ func (qi *QueryInserter) Values(values ...interface{}) db.QueryInserter {
qi.values = append(qi.values, sqlgen.NewValueGroup(f...)) qi.values = append(qi.values, sqlgen.NewValueGroup(f...))
return qi return qi
} }
type QueryDeleter struct {
builder *Builder
table string
limit int
where *sqlgen.Where
args []interface{}
}
func (qd *QueryDeleter) Where(terms ...interface{}) db.QueryDeleter {
where, arguments := template.ToWhereWithArguments(terms)
qd.where = &where
qd.args = append(qd.args, arguments...)
return qd
}
func (qd *QueryDeleter) Limit(limit int) db.QueryDeleter {
qd.limit = limit
return qd
}
func (qd *QueryDeleter) Exec() (sql.Result, error) {
stmt := &sqlgen.Statement{
Type: sqlgen.Delete,
Table: sqlgen.TableWithName(qd.table),
}
if qd.Where != nil {
stmt.Where = qd.where
}
if qd.limit != 0 {
stmt.Limit = sqlgen.Limit(qd.limit)
}
return qd.builder.sess.Exec(stmt, qd.args...)
}
type QueryUpdater struct {
builder *Builder
table string
columnValues *sqlgen.ColumnValues
limit int
where *sqlgen.Where
args []interface{}
}
func (qu *QueryUpdater) Set(terms ...interface{}) db.QueryUpdater {
cv, args := template.ToColumnValues(terms)
qu.columnValues = &cv
qu.args = append(qu.args, args...)
return qu
}
func (qu *QueryUpdater) Where(terms ...interface{}) db.QueryUpdater {
where, arguments := template.ToWhereWithArguments(terms)
qu.where = &where
qu.args = append(qu.args, arguments...)
return qu
}
func (qu *QueryUpdater) Exec() (sql.Result, error) {
stmt := &sqlgen.Statement{
Type: sqlgen.Update,
Table: sqlgen.TableWithName(qu.table),
ColumnValues: qu.columnValues,
}
if qu.Where != nil {
stmt.Where = qu.where
}
if qu.limit != 0 {
stmt.Limit = sqlgen.Limit(qu.limit)
}
return qu.builder.sess.Exec(stmt, qu.args...)
}
func (qu *QueryUpdater) Limit(limit int) db.QueryUpdater {
qu.limit = limit
return qu
}
...@@ -2080,9 +2080,37 @@ func TestQueryBuilder(t *testing.T) { ...@@ -2080,9 +2080,37 @@ func TestQueryBuilder(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
// DELETE FROM artist WHERE name = 'Chavela Vargas' LIMIT 1
if _, err = b.DeleteFrom("artist").Where("name = ?", "Chavela Vargas").Limit(1).Exec(); err != nil {
t.Fatal(err)
}
// DELETE FROM artist WHERE id > 5
if _, err = b.DeleteFrom("artist").Where("id > 5").Exec(); err != nil {
t.Fatal(err)
}
// UPDATE artist SET name = ?
if _, err = b.Update("artist").Set("name", "Artist").Exec(); err != nil {
t.Fatal(err)
}
// UPDATE artist SET name = ? WHERE id < 5
if _, err = b.Update("artist").Set("name = ?", "Artist").Where("id < ?", 5).Exec(); err != nil {
t.Fatal(err)
}
// UPDATE artist SET name = ? || ' ' || ? || id, id = id + ? WHERE id > ?
if _, err = b.Update("artist").Set(
"name = ? || ' ' || ? || id", "Artist", "#",
"id = id + ?", 10,
).Where("id > ?", 0).Exec(); err != nil {
t.Fatal(err)
}
/* /*
// INSERT INTO artist (name) VALUES(? || ?) // INSERT INTO artist (name) VALUES(? || ?)
if err = b.InsertInto("artist").Columns("name").Values(db.Raw("(? || ' ' || ?)"), "Tom", "Yorke").Exec(); err != nil { if err = b.InsertInto("artist").Columns("name").Values(db.Expr("? || ' ' || ?", "Tom", "Yorke")).Exec(); err != nil {
t.Fatal(err) t.Fatal(err)
} }
// INSERT INTO artist ("name") VALUES('Michael Jackson') // INSERT INTO artist ("name") VALUES('Michael Jackson')
......
...@@ -148,11 +148,46 @@ func (tu *TemplateWithUtils) ToInterfaceArguments(value interface{}) (args []int ...@@ -148,11 +148,46 @@ func (tu *TemplateWithUtils) ToInterfaceArguments(value interface{}) (args []int
} }
// ToColumnValues converts the given db.Cond into a sqlgen.ColumnValues struct. // ToColumnValues converts the given db.Cond into a sqlgen.ColumnValues struct.
func (tu *TemplateWithUtils) ToColumnValues(cond db.Cond) (ToColumnValues sqlgen.ColumnValues, args []interface{}) { func (tu *TemplateWithUtils) ToColumnValues(term interface{}) (cv sqlgen.ColumnValues, args []interface{}) {
args = []interface{}{} args = []interface{}{}
for column, value := range cond { switch t := term.(type) {
case []interface{}:
l := len(t)
for i := 0; i < l; i++ {
column := t[i].(string)
if !strings.ContainsAny(column, "=") {
column = fmt.Sprintf("%s = ?", column)
}
chunks := strings.SplitN(column, "=", 2)
column = chunks[0]
format := strings.TrimSpace(chunks[1])
columnValue := sqlgen.ColumnValue{
Column: sqlgen.ColumnWithName(column),
Operator: "=",
Value: sqlgen.RawValue(format),
}
ps := strings.Count(format, "?")
if i+ps < l {
for j := 0; j < ps; j++ {
args = append(args, t[i+j+1])
}
i = i + ps
} else {
panic(fmt.Sprintf("Format string %q has more placeholders than given arguments.", format))
}
cv.ColumnValues = append(cv.ColumnValues, &columnValue)
}
return cv, args
// Return error.
case db.Cond:
for column, value := range t {
columnValue := sqlgen.ColumnValue{} columnValue := sqlgen.ColumnValue{}
// Guessing operator from input, or using a default one. // Guessing operator from input, or using a default one.
...@@ -212,10 +247,12 @@ func (tu *TemplateWithUtils) ToColumnValues(cond db.Cond) (ToColumnValues sqlgen ...@@ -212,10 +247,12 @@ func (tu *TemplateWithUtils) ToColumnValues(cond db.Cond) (ToColumnValues sqlgen
} }
} }
ToColumnValues.ColumnValues = append(ToColumnValues.ColumnValues, &columnValue) cv.ColumnValues = append(cv.ColumnValues, &columnValue)
}
return cv, args
} }
return ToColumnValues, args panic("Unknown map type.")
} }
// ToColumnsValuesAndArguments maps the given columnNames and columnValues into // ToColumnsValuesAndArguments maps the given columnNames and columnValues into
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment