diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 15c63f5..9cceb07 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: - name: Setup Go uses: actions/setup-go@v2 with: - go-version: '1.17.0' # The Go version to download (if necessary) and use. + go-version: '1.19.0' # The Go version to download (if necessary) and use. # Install all the dependencies - name: Install dependencies diff --git a/cache_test.go b/cache_test.go index 703af61..c83a687 100644 --- a/cache_test.go +++ b/cache_test.go @@ -11,13 +11,13 @@ func TestSQLCache(t *testing.T) { defer putBuffer(buf) buf.WriteString("test") - _, ok := defaultDialect.getCachedSQL(buf) + _, ok := defaultDialectPointer.Load().getCachedSQL(buf) require.False(t, ok) - defaultDialect.putCachedSQL(buf, "test SQL") - sql, ok := defaultDialect.getCachedSQL(buf) + defaultDialectPointer.Load().putCachedSQL(buf, "test SQL") + sql, ok := defaultDialectPointer.Load().getCachedSQL(buf) require.True(t, ok) require.Equal(t, "test SQL", sql) - defaultDialect.ClearCache() + defaultDialectPointer.Load().ClearCache() } diff --git a/dialect.go b/dialect.go index c935754..d5085d1 100644 --- a/dialect.go +++ b/dialect.go @@ -4,8 +4,6 @@ import ( "strconv" "strings" "sync" - "sync/atomic" - "unsafe" ) // Dialect defines the method SQL statement is to be built. @@ -40,7 +38,7 @@ var ( PostgreSQL *Dialect = &Dialect{} ) -var defaultDialect = NoDialect +var defaultDialectPointer = newAtomicPointer(NoDialect) /* SetDialect selects a Dialect to be used by default. @@ -50,7 +48,7 @@ Dialect can be one of sqlf.NoDialect or sqlf.PostgreSQL sqlf.SetDialect(sqlf.PostgreSQL) */ func SetDialect(newDefaultDialect *Dialect) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(&defaultDialect)), unsafe.Pointer(newDefaultDialect)) + defaultDialectPointer.Store(newDefaultDialect) } /* diff --git a/go.mod b/go.mod index c08b9b8..f93e72d 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,15 @@ module github.com/leporo/sqlf -go 1.13 +go 1.19 require ( github.com/mattn/go-sqlite3 v1.14.16 github.com/stretchr/testify v1.8.2 github.com/valyala/bytebufferpool v1.0.0 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/stmt.go b/stmt.go index a05df7e..36f1fb5 100644 --- a/stmt.go +++ b/stmt.go @@ -26,7 +26,7 @@ Use New for special cases like this: } */ func New(verb string, args ...interface{}) *Stmt { - return defaultDialect.New(verb, args...) + return defaultDialectPointer.Load().New(verb, args...) } /* @@ -43,7 +43,7 @@ From starts a SELECT statement. } */ func From(expr string, args ...interface{}) *Stmt { - return defaultDialect.From(expr, args...) + return defaultDialectPointer.Load().From(expr, args...) } /* @@ -51,7 +51,7 @@ With starts a statement prepended by WITH clause and closes a subquery passed as an argument. */ func With(queryName string, query *Stmt) *Stmt { - return defaultDialect.With(queryName, query) + return defaultDialectPointer.Load().With(queryName, query) } /* @@ -70,7 +70,7 @@ Select starts a SELECT statement. Note that From method can also be used to start a SELECT statement. */ func Select(expr string, args ...interface{}) *Stmt { - return defaultDialect.Select(expr, args...) + return defaultDialectPointer.Load().Select(expr, args...) } /* @@ -85,7 +85,7 @@ Update starts an UPDATE statement. } */ func Update(tableName string) *Stmt { - return defaultDialect.Update(tableName) + return defaultDialectPointer.Load().Update(tableName) } /* @@ -101,7 +101,7 @@ InsertInto starts an INSERT statement. } */ func InsertInto(tableName string) *Stmt { - return defaultDialect.InsertInto(tableName) + return defaultDialectPointer.Load().InsertInto(tableName) } /* @@ -110,7 +110,7 @@ DeleteFrom starts a DELETE statement. err := sqlf.DeleteFrom("table").Where("id = ?", id).ExecAndClose(ctx, db) */ func DeleteFrom(tableName string) *Stmt { - return defaultDialect.DeleteFrom(tableName) + return defaultDialectPointer.Load().DeleteFrom(tableName) } type stmtChunk struct { diff --git a/util.go b/util.go index dcac33c..ea70b9f 100644 --- a/util.go +++ b/util.go @@ -1,6 +1,7 @@ package sqlf import ( + "sync/atomic" "unsafe" ) @@ -25,3 +26,11 @@ func insertAt(dest, src []interface{}, index int) []interface{} { func bufToString(buf *[]byte) string { return *(*string)(unsafe.Pointer(buf)) } + +func newAtomicPointer[T any](initialValue *T) *atomic.Pointer[T] { + var pointer atomic.Pointer[T] + + pointer.Store(initialValue) + + return &pointer +}