diff --git a/.github/workflows/go.yaml b/.github/workflows/go.yaml index 1c86d2a..f8001f5 100644 --- a/.github/workflows/go.yaml +++ b/.github/workflows/go.yaml @@ -44,7 +44,7 @@ jobs: run: go-acc . -- -race -v -tags "libsqlite3" - name: 'Tags: full' - run: go-acc . -- -race -v -tags "sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_preupdate_hook sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify" + run: go-acc . -- -race -v -tags "sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_preupdate_hook sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify sqlite_column_metadata" - name: 'Tags: vacuum' run: go-acc . -- -race -v -tags "sqlite_vacuum_full" diff --git a/sqlite3.go b/sqlite3.go index 8d48faa..5ac9570 100644 --- a/sqlite3.go +++ b/sqlite3.go @@ -19,7 +19,6 @@ package sqlite3 #cgo CFLAGS: -DSQLITE_OMIT_DEPRECATED #cgo CFLAGS: -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 #cgo CFLAGS: -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT -#cgo CFLAGS: -DSQLITE_ENABLE_COLUMN_METADATA #cgo CFLAGS: -Wno-deprecated-declarations #cgo linux,!android CFLAGS: -DHAVE_PREAD64=1 -DHAVE_PWRITE64=1 #ifndef USE_LIBSQLITE3 @@ -2015,14 +2014,6 @@ func (s *SQLiteStmt) Readonly() bool { return C.sqlite3_stmt_readonly(s.s) == 1 } -// ColumnTableName returns the table that is the origin of a particular result -// column in a SELECT statement. -// -// See https://www.sqlite.org/c3ref/column_database_name.html -func (s *SQLiteStmt) ColumnTableName(n int) string { - return C.GoString(C.sqlite3_column_table_name(s.s, C.int(n))) -} - // Close the rows. func (rc *SQLiteRows) Close() error { rc.s.mu.Lock() diff --git a/sqlite3_opt_column_metadata.go b/sqlite3_opt_column_metadata.go new file mode 100644 index 0000000..c67fa82 --- /dev/null +++ b/sqlite3_opt_column_metadata.go @@ -0,0 +1,21 @@ +// +build sqlite_column_metadata + +package sqlite3 + +/* +#ifndef USE_LIBSQLITE3 +#cgo CFLAGS: -DSQLITE_ENABLE_COLUMN_METADATA +#include +#else +#include +#endif +*/ +import "C" + +// ColumnTableName returns the table that is the origin of a particular result +// column in a SELECT statement. +// +// See https://www.sqlite.org/c3ref/column_database_name.html +func (s *SQLiteStmt) ColumnTableName(n int) string { + return C.GoString(C.sqlite3_column_table_name(s.s, C.int(n))) +} diff --git a/sqlite3_opt_column_metadata_test.go b/sqlite3_opt_column_metadata_test.go new file mode 100644 index 0000000..28767f1 --- /dev/null +++ b/sqlite3_opt_column_metadata_test.go @@ -0,0 +1,39 @@ +// +build sqlite_column_metadata + +package sqlite3 + +import "testing" + +func TestColumnTableName(t *testing.T) { + d := SQLiteDriver{} + conn, err := d.Open(":memory:") + if err != nil { + t.Fatal("failed to get database connection:", err) + } + defer conn.Close() + sqlite3conn := conn.(*SQLiteConn) + + _, err = sqlite3conn.Exec(`CREATE TABLE foo (name string)`, nil) + if err != nil { + t.Fatal("Failed to create table:", err) + } + _, err = sqlite3conn.Exec(`CREATE TABLE bar (name string)`, nil) + if err != nil { + t.Fatal("Failed to create table:", err) + } + + stmt, err := sqlite3conn.Prepare(`SELECT * FROM foo JOIN bar ON foo.name = bar.name`) + if err != nil { + t.Fatal(err) + } + + if exp, got := "foo", stmt.(*SQLiteStmt).ColumnTableName(0); exp != got { + t.Fatalf("Incorrect table name returned expected: %s, got: %s", exp, got) + } + if exp, got := "bar", stmt.(*SQLiteStmt).ColumnTableName(1); exp != got { + t.Fatalf("Incorrect table name returned expected: %s, got: %s", exp, got) + } + if exp, got := "", stmt.(*SQLiteStmt).ColumnTableName(2); exp != got { + t.Fatalf("Incorrect table name returned expected: %s, got: %s", exp, got) + } +} diff --git a/sqlite3_test.go b/sqlite3_test.go index e74c35e..878ec49 100644 --- a/sqlite3_test.go +++ b/sqlite3_test.go @@ -1604,40 +1604,6 @@ func TestDeclTypes(t *testing.T) { } } -func TestColumnTableName(t *testing.T) { - d := SQLiteDriver{} - conn, err := d.Open(":memory:") - if err != nil { - t.Fatal("failed to get database connection:", err) - } - defer conn.Close() - sqlite3conn := conn.(*SQLiteConn) - - _, err = sqlite3conn.Exec(`CREATE TABLE foo (name string)`, nil) - if err != nil { - t.Fatal("Failed to create table:", err) - } - _, err = sqlite3conn.Exec(`CREATE TABLE bar (name string)`, nil) - if err != nil { - t.Fatal("Failed to create table:", err) - } - - stmt, err := sqlite3conn.Prepare(`SELECT * FROM foo JOIN bar ON foo.name = bar.name`) - if err != nil { - t.Fatal(err) - } - - if exp, got := "foo", stmt.(*SQLiteStmt).ColumnTableName(0); exp != got { - t.Fatalf("Incorrect table name returned expected: %s, got: %s", exp, got) - } - if exp, got := "bar", stmt.(*SQLiteStmt).ColumnTableName(1); exp != got { - t.Fatalf("Incorrect table name returned expected: %s, got: %s", exp, got) - } - if exp, got := "", stmt.(*SQLiteStmt).ColumnTableName(2); exp != got { - t.Fatalf("Incorrect table name returned expected: %s, got: %s", exp, got) - } -} - func TestPinger(t *testing.T) { db, err := sql.Open("sqlite3", ":memory:") if err != nil {