add update statement
This commit is contained in:
@@ -29,6 +29,10 @@ func TestInsert(t *testing.T) {
|
|||||||
Args: []any{1234, "Adam"},
|
Args: []any{1234, "Adam"},
|
||||||
String: "insert or update into customer (id, name) values (?, ?)",
|
String: "insert or update into customer (id, name) values (?, ?)",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
In: Insert("customer").Columns("name").Select(Select("baby_names").Columns("name")),
|
||||||
|
String: "insert into customer (name) select name from baby_names",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
|
|||||||
@@ -30,6 +30,10 @@ func (q *SelectQuery) Args() []any {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *SelectQuery) Columns(defs ...string) *SelectQuery {
|
func (q *SelectQuery) Columns(defs ...string) *SelectQuery {
|
||||||
|
if q.columns == nil {
|
||||||
|
q.columns = []Column{}
|
||||||
|
}
|
||||||
|
|
||||||
for _, def := range defs {
|
for _, def := range defs {
|
||||||
q.columns = append(q.columns, Column(def))
|
q.columns = append(q.columns, Column(def))
|
||||||
}
|
}
|
||||||
@@ -157,6 +161,10 @@ func (q *SelectQuery) String() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (q *SelectQuery) Where(def string, args ...any) *SelectQuery {
|
func (q *SelectQuery) Where(def string, args ...any) *SelectQuery {
|
||||||
|
if q.where == nil {
|
||||||
|
q.where = []Where{}
|
||||||
|
}
|
||||||
|
|
||||||
q.where = append(q.where, Where(def))
|
q.where = append(q.where, Where(def))
|
||||||
|
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
@@ -172,10 +180,7 @@ func (q *SelectQuery) Where(def string, args ...any) *SelectQuery {
|
|||||||
|
|
||||||
func Select(from string) *SelectQuery {
|
func Select(from string) *SelectQuery {
|
||||||
q := &SelectQuery{
|
q := &SelectQuery{
|
||||||
columns: []Column{},
|
|
||||||
tables: []SelectTable{From(from)},
|
tables: []SelectTable{From(from)},
|
||||||
|
|
||||||
where: []Where{},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return q
|
return q
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
insertTableRegexp = regexp.MustCompile("^into ([^ ]+)( (as) ([^ ]+))?$")
|
insertTableRegexp = regexp.MustCompile("^into ([^ ]+)( (as) ([^ ]+))?$")
|
||||||
selectTableRegexp = regexp.MustCompile("^(from|left join|inner join|right join) ([^ ]+)( (as) ([^ ]+))?( (on) ([^ ]+) (=|!=|>|>=|<|<=) ([^ ]+)( (and) ([^ ]+) (=|!=|>|>=|<|<=) ([^ ]+))*)?$")
|
selectTableRegexp = regexp.MustCompile("^(from|left join|inner join|right join) ([^ ]+)( (as) ([^ ]+))?( (on) ([^ ]+) (=|!=|>|>=|<|<=) ([^ ]+)( (and) ([^ ]+) (=|!=|>|>=|<|<=) ([^ ]+))*)?$")
|
||||||
|
updateTableRegexp = regexp.MustCompile("^([^ ]+)( (as) ([^ ]+))?$")
|
||||||
)
|
)
|
||||||
|
|
||||||
type InsertTable string
|
type InsertTable string
|
||||||
@@ -120,3 +121,31 @@ func RightJoin(def string) SelectTable {
|
|||||||
|
|
||||||
return SelectTable(fmt.Sprintf("right join %s", def))
|
return SelectTable(fmt.Sprintf("right join %s", def))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateTable string
|
||||||
|
|
||||||
|
func (t UpdateTable) IsValid() bool {
|
||||||
|
return insertTableRegexp.MatchString(string(t))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t UpdateTable) Parse() (table, as string, ok bool) {
|
||||||
|
if insertTableRegexp.MatchString(string(t)) {
|
||||||
|
ok = true
|
||||||
|
|
||||||
|
result := insertTableRegexp.FindAllStringSubmatch(string(t), -1)
|
||||||
|
|
||||||
|
for _, r := range result {
|
||||||
|
table = r[1]
|
||||||
|
|
||||||
|
if r[3] == "as" {
|
||||||
|
as = r[4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t UpdateTable) String() string {
|
||||||
|
return string(t)
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,126 @@
|
|||||||
|
package sqimple
|
||||||
|
|
||||||
|
import (
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// https://www.sqlite.org/lang_update.html
|
||||||
|
type UpdateStatement struct {
|
||||||
|
table UpdateTable
|
||||||
|
or string
|
||||||
|
|
||||||
|
columns []string
|
||||||
|
set map[string]any
|
||||||
|
|
||||||
|
where []Where
|
||||||
|
args []any
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) Args() []any {
|
||||||
|
args := []any{}
|
||||||
|
|
||||||
|
for _, column := range s.columns {
|
||||||
|
args = append(args, s.set[column])
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, arg := range s.args {
|
||||||
|
args = append(args, arg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return args
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) IsValid() bool {
|
||||||
|
if !s.table.IsValid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, w := range s.where {
|
||||||
|
if !w.IsValid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) Or(or string) *UpdateStatement {
|
||||||
|
s.or = or
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) Set(column string, value any) *UpdateStatement {
|
||||||
|
if s.columns == nil {
|
||||||
|
s.columns = []string{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.set == nil {
|
||||||
|
s.set = map[string]any{}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !slices.Contains(s.columns, column) {
|
||||||
|
s.columns = append(s.columns, column)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.set[column] = value
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) SetMap(data map[string]any) *UpdateStatement {
|
||||||
|
for column, value := range data {
|
||||||
|
s.Set(column, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) String() string {
|
||||||
|
strs := []string{"update"}
|
||||||
|
|
||||||
|
if s.or != "" {
|
||||||
|
strs = append(strs, "or", s.or)
|
||||||
|
}
|
||||||
|
|
||||||
|
strs = append(strs, s.table.String(), "set")
|
||||||
|
|
||||||
|
for i, column := range s.columns {
|
||||||
|
if i < len(s.columns)-1 {
|
||||||
|
strs = append(strs, column, "= ?,")
|
||||||
|
} else {
|
||||||
|
strs = append(strs, column, "= ?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(s.where) > 0 {
|
||||||
|
strs = append(strs, "where")
|
||||||
|
|
||||||
|
for _, w := range s.where {
|
||||||
|
strs = append(strs, w.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strings.Join(strs, " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *UpdateStatement) Where(def string, args ...any) *UpdateStatement {
|
||||||
|
s.where = append(s.where, Where(def))
|
||||||
|
|
||||||
|
if len(args) > 0 {
|
||||||
|
if s.args == nil {
|
||||||
|
s.args = []any{}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.args = append(s.args, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func Update(table string) *UpdateStatement {
|
||||||
|
s := &UpdateStatement{
|
||||||
|
table: UpdateTable(table),
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package sqimple
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/alecthomas/assert/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestUpdate(t *testing.T) {
|
||||||
|
type TestCase struct {
|
||||||
|
In *UpdateStatement
|
||||||
|
Args []any
|
||||||
|
String string
|
||||||
|
}
|
||||||
|
|
||||||
|
testCases := []TestCase{
|
||||||
|
{
|
||||||
|
In: Update("customer").Set("name", "Adam"),
|
||||||
|
Args: []any{"Adam"},
|
||||||
|
String: "update customer set name = ?",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
In: Update("customer").Set("name", "Adam").Where("id = ?", 1234),
|
||||||
|
Args: []any{"Adam", 1234},
|
||||||
|
String: "update customer set name = ? where id = ?",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Same as previous, but backwards
|
||||||
|
In: Update("customer").Where("id = ?", 1234).Set("name", "Adam"),
|
||||||
|
Args: []any{"Adam", 1234},
|
||||||
|
String: "update customer set name = ? where id = ?",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, testCase := range testCases {
|
||||||
|
t.Run(testCase.String, func(t *testing.T) {
|
||||||
|
assert.Equal(t, testCase.Args, testCase.In.Args(), "collected arguments incorrectly")
|
||||||
|
assert.Equal(t, testCase.String, testCase.In.String(), "stringified incorrectly")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user