Skip to content

Commit

Permalink
Upgrade to Go 1.18, add SQLiteString.
Browse files Browse the repository at this point in the history
Upgrade to Go 1.18, adding a go.mod and go.sum. Change all instances of
`interface{}` to `any`.

Update `Insert` to use generics so we no longer need to convert to a
`[]pan.SQLTableNamer` before passing slices in, slices of any type that
fills the `pan.SQLTableNamer` interface will now work. Should be
backwards-compatible. It also has the benefit of enforcing that all
values need to be of the same type, which was implied by the comment
prior to this, so I'm not considering it a breaking change.

Add an SQLiteString method to Query, returning a string that can be used
for SQLite. Technically, this is the same as MySQLString. But it feels
weird using MySQLString in SQLite code, and now if we discover any
special handling we need to do for SQLite, we can just put it in this
method.

🎵 Now Playing: Better Than That
🎵 Artist: Sub-Radio
🎵 Album: Better Than That
  • Loading branch information
paddycarver committed Feb 12, 2023
1 parent 10eec68 commit 7746bfd
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module darlinggo.co/pan

go 1.18

require github.com/mattn/go-sqlite3 v1.14.16
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
36 changes: 25 additions & 11 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ var (
// goroutines, you need to coordinate that access yourself.
type Query struct {
sql string
args []interface{}
args []any
expressions []string
includesWhere bool
includesOrder bool
Expand All @@ -56,14 +56,13 @@ type Flag int
func New(query string) *Query {
return &Query{
sql: query,
args: []interface{}{},
args: []any{},
}
}

// Insert returns a Query instance containing SQL that will insert the passed `values` into
// the database. All `values` will be inserted into the same table, so invalid SQL will be
// generated if all `values` are not the same type.
func Insert(values ...SQLTableNamer) *Query {
// the database.
func Insert[Type SQLTableNamer](values ...Type) *Query {
columns := Columns(values[0])
query := New("INSERT INTO " + Table(values[0]) + " (" + columns.String() + ") VALUES")

Expand Down Expand Up @@ -106,7 +105,7 @@ func (q *Query) String() string {
var res string
toCheck := q.sql
for i := strings.Index(toCheck, "?"); i >= 0; argPos++ {
var arg interface{}
var arg any
arg = "!{MISSING}"
if len(q.args) > argPos {
arg = q.args[argPos]
Expand Down Expand Up @@ -135,6 +134,21 @@ func (q *Query) MySQLString() (string, error) {
return q.sql + ";", nil
}

// SQLiteString returns a SQL string that can be passed to SQLite to execute
// your query. If the number of placeholders do not match the number of
// arguments provided to your Query, an ErrWrongNumberArgs error will be
// returned. If there are still expressions left in the buffer (meaning the
// Flush method wasn't called) an ErrNeedsFlush error will be returned.
func (q *Query) SQLiteString() (string, error) {
if len(q.expressions) != 0 {
return "", ErrNeedsFlush
}
if err := q.checkCounts(); err != nil {
return "", err
}
return q.sql + ";", nil
}

// PostgreSQLString returns an SQL string that can be passed to PostgreSQL to execute
// your query. If the number of placeholders do not match the number of arguments
// provided to your Query, an ErrWrongNumberArgs error will be returned. If there are
Expand Down Expand Up @@ -176,7 +190,7 @@ func (q *Query) Flush(join string) *Query {
}

// Expression adds a raw string and optional values to the Query’s buffer.
func (q *Query) Expression(key string, values ...interface{}) *Query {
func (q *Query) Expression(key string, values ...any) *Query {
q.expressions = append(q.expressions, key)
q.args = append(q.args, values...)
return q
Expand All @@ -202,22 +216,22 @@ func (q *Query) Where() *Query {
// determined by finding the column name for the passed property on the passed SQLTableNamer.
// The passed property must be a string that matches, identically, the property name; if it
// does not, it will panic.
func (q *Query) Comparison(obj SQLTableNamer, property, operator string, value interface{}) *Query {
func (q *Query) Comparison(obj SQLTableNamer, property, operator string, value any) *Query {
return q.Expression(Column(obj, property)+" "+operator+" ?", value)
}

// In adds an expression to the Query’s buffer in the form of "column IN (value, value, value)".
// `values` are the variables to match against, and `obj` and `property` are used to determine
// the column. `property` must exactly match the name of a property on `obj`, or the call will
// panic.
func (q *Query) In(obj SQLTableNamer, property string, values ...interface{}) *Query {
func (q *Query) In(obj SQLTableNamer, property string, values ...any) *Query {
return q.Expression(Column(obj, property)+" IN("+Placeholders(len(values))+")", values...)
}

// Assign adds an expression to the Query’s buffer in the form of "column = ?", and adds `value`
// to the arguments for this query. `obj` and `property` are used to determine the column.
// `property` must exactly match the name of a property on `obj`, or the call will panic.
func (q *Query) Assign(obj SQLTableNamer, property string, value interface{}) *Query {
func (q *Query) Assign(obj SQLTableNamer, property string, value any) *Query {
return q.Expression(Column(obj, property)+" = ?", value)
}

Expand Down Expand Up @@ -258,6 +272,6 @@ func (q *Query) Offset(offset int64) *Query {
//
// Note that Args returns its internal slice; you should copy the returned slice over before modifying
// it.
func (q *Query) Args() []interface{} {
func (q *Query) Args() []any {
return q.args
}
2 changes: 1 addition & 1 deletion reflect_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func TestUnmarshal(t *testing.T) {
t.Error(err)
}
q := Insert(dummy)
mysql, err := q.MySQLString()
mysql, err := q.SQLiteString()
if err != nil {
t.Error(err)
}
Expand Down

0 comments on commit 7746bfd

Please sign in to comment.