Commit 1d4f09bb authored by gwenn's avatar gwenn

Make possible to specify the database name in PRAGMA methods.

parent 6f574615
......@@ -42,7 +42,7 @@ type Backup struct {
dst, src *Conn
}
// Copy up to N pages between the source and destination databases
// Step copies up to N pages between the source and destination databases
// (See http://sqlite.org/c3ref/backup_finish.html#sqlite3backupstep)
func (b *Backup) Step(npage int) error {
if b == nil {
......@@ -61,7 +61,7 @@ type BackupStatus struct {
PageCount int
}
// Return the number of pages still to be backed up and the total number of pages in the source database file.
// Status returns the number of pages still to be backed up and the total number of pages in the source database file.
// (See http://sqlite.org/c3ref/backup_finish.html#sqlite3backupremaining)
func (b *Backup) Status() BackupStatus {
return BackupStatus{int(C.sqlite3_backup_remaining(b.sb)), int(C.sqlite3_backup_pagecount(b.sb))}
......@@ -96,7 +96,7 @@ func (b *Backup) Run(npage int, sleepNs time.Duration, c chan<- BackupStatus) er
return nil
}
// Finish/stop the backup
// Close finishes/stops the backup
// (See http://sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish)
func (b *Backup) Close() error {
if b == nil {
......
......@@ -31,7 +31,7 @@ type BlobReadWriter struct {
// Zeroblobs are used to reserve space for a BLOB that is later written.
type ZeroBlobLength int
// Open a BLOB for incremental I/O
// NewBlobReader opens a BLOB for incremental I/O
//
// (See http://sqlite.org/c3ref/blob_open.html)
func (c *Conn) NewBlobReader(db, table, column string, row int64) (*BlobReader, error) {
......@@ -42,7 +42,7 @@ func (c *Conn) NewBlobReader(db, table, column string, row int64) (*BlobReader,
return &BlobReader{c, bl, 0}, nil
}
// Open a BLOB For incremental I/O
// NewBlobReadWriter open a BLOB for incremental I/O
// (See http://sqlite.org/c3ref/blob_open.html)
func (c *Conn) NewBlobReadWriter(db, table, column string, row int64) (*BlobReadWriter, error) {
bl, err := c.blob_open(db, table, column, row, true)
......@@ -73,7 +73,7 @@ func (c *Conn) blob_open(db, table, column string, row int64, write bool) (*C.sq
return bl, nil
}
// Close a BLOB handle
// Close closes a BLOB handle
// (See http://sqlite.org/c3ref/blob_close.html)
func (r *BlobReader) Close() error {
if r == nil {
......@@ -87,7 +87,7 @@ func (r *BlobReader) Close() error {
return nil
}
// Read data from a BLOB incrementally
// Read reads data from a BLOB incrementally
// (See http://sqlite.org/c3ref/blob_read.html)
func (r *BlobReader) Read(v []byte) (int, error) {
var p *byte
......@@ -102,14 +102,14 @@ func (r *BlobReader) Read(v []byte) (int, error) {
return len(v), nil
}
// Return the size of an open BLOB
// Size returns the size of an opened BLOB
// (See http://sqlite.org/c3ref/blob_bytes.html)
func (r *BlobReader) Size() (int, error) {
s := C.sqlite3_blob_bytes(r.bl)
return int(s), nil
}
// Write data into a BLOB incrementally
// Write writes data into a BLOB incrementally
// (See http://sqlite.org/c3ref/blob_write.html)
func (w *BlobReadWriter) Write(v []byte) (int, error) {
var p *byte
......@@ -124,7 +124,7 @@ func (w *BlobReadWriter) Write(v []byte) (int, error) {
return len(v), nil
}
// Move a BLOB handle to a new row
// Reopen moves a BLOB handle to a new row
// (See http://sqlite.org/c3ref/blob_reopen.html)
func (r *BlobReader) Reopen(rowid int64) error {
rv := C.sqlite3_blob_reopen(r.bl, C.sqlite3_int64(rowid))
......
......@@ -51,7 +51,7 @@ func TestDefaultBusy(t *testing.T) {
checkNoError(t, db1.BeginTransaction(EXCLUSIVE), "couldn't begin transaction: %s")
defer db1.Rollback()
_, err := db2.SchemaVersion()
_, err := db2.SchemaVersion("")
if err == nil {
t.Fatalf("Expected lock but got %v", err)
}
......@@ -75,7 +75,7 @@ func TestBusyTimeout(t *testing.T) {
//join <- true
}()
_, err := db2.SchemaVersion()
_, err := db2.SchemaVersion("")
checkNoError(t, err, "couldn't query schema version: %#v")
//<- join
}
......@@ -104,7 +104,7 @@ func TestBusyHandler(t *testing.T) {
db1.Rollback()
}()
_, err = db2.SchemaVersion()
_, err = db2.SchemaVersion("")
checkNoError(t, err, "couldn't query schema version: %#v")
assert(t, "busy handler not called!", called)
}
......@@ -86,7 +86,7 @@ func (c *cache) flush() {
}
}
// Return (current, max) sizes.
// CacheSize returns (current, max) sizes.
// Cache is turned off when max size is 0
func (c *Conn) CacheSize() (int, int) {
if c.stmtCache.maxSize <= 0 {
......@@ -95,6 +95,7 @@ func (c *Conn) CacheSize() (int, int) {
return c.stmtCache.l.Len(), c.stmtCache.maxSize
}
// SetCacheSize sets the size of prepared statements cache.
// Cache is turned off (and flushed) when size <= 0
func (c *Conn) SetCacheSize(size int) {
stmtCache := c.stmtCache
......
......@@ -13,17 +13,21 @@ const (
DAY_IN_SECONDS = 60 * 60 * 24
)
// JulianDayToUTC transforms a julian day number into an UTC Time.
func JulianDayToUTC(jd float64) time.Time {
jd -= JULIAN_DAY
jd *= DAY_IN_SECONDS
return time.Unix(int64(jd), 0).UTC()
}
// JulianDayToLocalTime transforms a julian day number into a local Time.
func JulianDayToLocalTime(jd float64) time.Time {
jd -= JULIAN_DAY
jd *= DAY_IN_SECONDS
return time.Unix(int64(jd), 0)
}
// JulianDay converts a Time into a julian day number.
func JulianDay(t time.Time) float64 {
ns := float64(t.Unix())
if ns >= 0 {
......
......@@ -21,6 +21,7 @@ func init() {
}
}
// Adapter to database/sql/driver
type Driver struct {
}
type connImpl struct {
......
......@@ -55,7 +55,7 @@ func ExampleConn_Exec() {
err = db.Exec("CREATE TABLE test1 (content TEXT); CREATE TABLE test2 (content TEXT); INSERT INTO test1 VALUES ('DATA')")
check(err)
tables, err := db.Tables()
tables, err := db.Tables("")
check(err)
fmt.Printf("%d tables\n", len(tables))
// Output: 2 tables
......
......@@ -12,6 +12,9 @@ package sqlite
static char *my_mprintf(char *zFormat, char *arg) {
return sqlite3_mprintf(zFormat, arg);
}
static char *my_mprintf2(char *zFormat, char *arg1, char *arg2) {
return sqlite3_mprintf(zFormat, arg1, arg2);
}
// just to get ride of warning
static int my_table_column_metadata(
......@@ -57,9 +60,14 @@ func (c *Conn) Databases() (map[string]string, error) {
}
// Selects tables (no view) from 'sqlite_master' and filters system tables out.
// TODO Make possible to specified the database name (main.sqlite_master)
func (c *Conn) Tables() ([]string, error) {
s, err := c.prepare("SELECT name FROM sqlite_master WHERE type IN ('table') AND name NOT LIKE 'sqlite_%'")
func (c *Conn) Tables(dbName string) ([]string, error) {
var sql string
if len(dbName) == 0 {
sql = "SELECT name FROM sqlite_master WHERE type IN ('table') AND name NOT LIKE 'sqlite_%'"
} else {
sql = Mprintf("SELECT name FROM %Q.sqlite_master WHERE type IN ('table') AND name NOT LIKE 'sqlite_%%'", dbName)
}
s, err := c.prepare(sql)
if err != nil {
return nil, err
}
......@@ -89,9 +97,14 @@ type Column struct {
}
// Executes pragma 'table_info'
// TODO Make possible to specify the database-name (PRAGMA %Q.table_info(%Q))
func (c *Conn) Columns(table string) ([]Column, error) {
s, err := c.prepare(Mprintf("PRAGMA table_info(%Q)", table))
func (c *Conn) Columns(dbName, table string) ([]Column, error) {
var pragma string
if len(dbName) == 0 {
pragma = Mprintf("PRAGMA table_info(%Q)", table)
} else {
pragma = Mprintf2("PRAGMA %Q.table_info(%Q)", dbName, table)
}
s, err := c.prepare(pragma)
if err != nil {
return nil, err
}
......@@ -142,9 +155,14 @@ type ForeignKey struct {
}
// Executes pragma 'foreign_key_list'
// TODO Make possible to specify the database-name (PRAGMA %Q.foreign_key_list(%Q))
func (c *Conn) ForeignKeys(table string) (map[int]*ForeignKey, error) {
s, err := c.prepare(Mprintf("PRAGMA foreign_key_list(%Q)", table))
func (c *Conn) ForeignKeys(dbName, table string) (map[int]*ForeignKey, error) {
var pragma string
if len(dbName) == 0 {
pragma = Mprintf("PRAGMA foreign_key_list(%Q)", table)
} else {
pragma = Mprintf2("PRAGMA %Q.foreign_key_list(%Q)", dbName, table)
}
s, err := c.prepare(pragma)
if err != nil {
return nil, err
}
......@@ -179,9 +197,14 @@ type Index struct {
}
// Executes pragma 'index_list'
// TODO Make possible to specify the database-name (PRAGMA %Q.index_list(%Q))
func (c *Conn) Indexes(table string) ([]Index, error) {
s, err := c.prepare(Mprintf("PRAGMA index_list(%Q)", table))
func (c *Conn) Indexes(dbName, table string) ([]Index, error) {
var pragma string
if len(dbName) == 0 {
pragma = Mprintf("PRAGMA index_list(%Q)", table)
} else {
pragma = Mprintf2("PRAGMA %Q.index_list(%Q)", dbName, table)
}
s, err := c.prepare(pragma)
if err != nil {
return nil, err
}
......@@ -203,8 +226,14 @@ func (c *Conn) Indexes(table string) ([]Index, error) {
// Executes pragma 'index_info'
// Only Column.Cid and Column.Name are specified. All other fields are unspecifed.
func (c *Conn) IndexColumns(index string) ([]Column, error) {
s, err := c.prepare(Mprintf("PRAGMA index_info(%Q)", index))
func (c *Conn) IndexColumns(dbName, index string) ([]Column, error) {
var pragma string
if len(dbName) == 0 {
pragma = Mprintf("PRAGMA index_info(%Q)", index)
} else {
pragma = Mprintf2("PRAGMA %Q.index_info(%Q)", dbName, index)
}
s, err := c.prepare(pragma)
if err != nil {
return nil, err
}
......@@ -234,3 +263,14 @@ func Mprintf(format string, arg string) string {
defer C.sqlite3_free(unsafe.Pointer(zSQL))
return C.GoString(zSQL)
}
func Mprintf2(format string, arg1, arg2 string) string {
cf := C.CString(format)
defer C.free(unsafe.Pointer(cf))
ca1 := C.CString(arg1)
defer C.free(unsafe.Pointer(ca1))
ca2 := C.CString(arg2)
defer C.free(unsafe.Pointer(ca2))
zSQL := C.my_mprintf2(cf, ca1, ca2)
defer C.sqlite3_free(unsafe.Pointer(zSQL))
return C.GoString(zSQL)
}
......@@ -33,11 +33,11 @@ func TestTables(t *testing.T) {
db := open(t)
defer db.Close()
tables, err := db.Tables()
tables, err := db.Tables("")
checkNoError(t, err, "error looking for tables: %s")
assertEquals(t, "expected %d table but got %d", 0, len(tables))
createTable(db, t)
tables, err = db.Tables()
tables, err = db.Tables("main")
checkNoError(t, err, "error looking for tables: %s")
assertEquals(t, "expected %d table but got %d", 1, len(tables))
assertEquals(t, "wrong table name: %q <> %q", "test", tables[0])
......@@ -48,7 +48,7 @@ func TestColumns(t *testing.T) {
defer db.Close()
createTable(db, t)
columns, err := db.Columns("test")
columns, err := db.Columns("", "test")
checkNoError(t, err, "error listing columns: %s")
if len(columns) != 4 {
t.Fatalf("Expected 4 columns <> %d", len(columns))
......@@ -77,7 +77,7 @@ func TestForeignKeys(t *testing.T) {
"CREATE TABLE child (id INTEGER PRIMARY KEY NOT NULL, parentId INTEGER, " +
"FOREIGN KEY (parentId) REFERENCES parent(id));")
checkNoError(t, err, "error creating tables: %s")
fks, err := db.ForeignKeys("child")
fks, err := db.ForeignKeys("", "child")
checkNoError(t, err, "error listing FKs: %s")
if len(fks) != 1 {
t.Fatalf("expected 1 FK <> %d", len(fks))
......@@ -94,7 +94,7 @@ func TestIndexes(t *testing.T) {
createTable(db, t)
createIndex(db, t)
indexes, err := db.Indexes("test")
indexes, err := db.Indexes("", "test")
checkNoError(t, err, "error listing indexes: %s")
if len(indexes) != 1 {
t.Fatalf("Expected one index <> %d", len(indexes))
......@@ -103,7 +103,7 @@ func TestIndexes(t *testing.T) {
assertEquals(t, "wrong index name: %q <> %q", "test_index", index.Name)
assert(t, "index 'test_index' is not unique", !index.Unique)
columns, err := db.IndexColumns("test_index")
columns, err := db.IndexColumns("", "test_index")
checkNoError(t, err, "error listing index columns: %s")
if len(columns) != 1 {
t.Fatalf("expected one column <> %d", len(columns))
......
......@@ -9,10 +9,11 @@ import (
)
// Check database integrity
// Database name is optional
// (See http://www.sqlite.org/pragma.html#pragma_integrity_check
// and http://www.sqlite.org/pragma.html#pragma_quick_check)
// TODO Make possible to specify the database-name (PRAGMA %Q.integrity_check(.))
func (c *Conn) IntegrityCheck(max int, quick bool) error {
func (c *Conn) IntegrityCheck(dbName string, max int, quick bool) error {
var pragma string
if quick {
pragma = "quick"
......@@ -30,23 +31,23 @@ func (c *Conn) IntegrityCheck(max int, quick bool) error {
return nil
}
// Database name is optional
// Returns the text encoding used by the main database
// (See http://sqlite.org/pragma.html#pragma_encoding)
// TODO Make possible to specify the database-name (PRAGMA %Q.encoding)
func (c *Conn) Encoding() (string, error) {
func (c *Conn) Encoding(dbName string) (string, error) {
var encoding string
err := c.OneValue("PRAGMA encoding", &encoding)
err := c.OneValue(pragma(dbName, "PRAGMA encoding", "PRAGMA %Q.encoding"), &encoding)
if err != nil {
return "", err
}
return encoding, nil
}
// Database name is optional
// (See http://sqlite.org/pragma.html#pragma_schema_version)
// TODO Make possible to specify the database-name (PRAGMA %Q.schema_version)
func (c *Conn) SchemaVersion() (int, error) {
func (c *Conn) SchemaVersion(dbName string) (int, error) {
var version int
err := c.OneValue("PRAGMA schema_version", &version)
err := c.OneValue(pragma(dbName, "PRAGMA schema_version", "PRAGMA %Q.schema_version"), &version)
if err != nil {
return -1, err
}
......@@ -58,3 +59,10 @@ func (c *Conn) SchemaVersion() (int, error) {
func (c *Conn) SetRecursiveTriggers(on bool) error {
return c.exec(fmt.Sprintf("PRAGMA recursive_triggers=%t", on))
}
func pragma(dbName, unqualified, qualified string) string {
if len(dbName) == 0 {
return unqualified
}
return Mprintf(qualified, dbName)
}
......@@ -11,13 +11,13 @@ import (
func TestIntegrityCheck(t *testing.T) {
db := open(t)
defer db.Close()
checkNoError(t, db.IntegrityCheck(1, true), "Error checking integrity of database: %s")
checkNoError(t, db.IntegrityCheck("", 1, true), "Error checking integrity of database: %s")
}
func TestEncoding(t *testing.T) {
db := open(t)
defer db.Close()
encoding, err := db.Encoding()
encoding, err := db.Encoding("")
checkNoError(t, err, "Error reading encoding of database: %s")
assertEquals(t, "Expecting %s but got %s", "UTF-8", encoding)
}
......@@ -25,7 +25,7 @@ func TestEncoding(t *testing.T) {
func TestSchemaVersion(t *testing.T) {
db := open(t)
defer db.Close()
version, err := db.SchemaVersion()
version, err := db.SchemaVersion("")
checkNoError(t, err, "Error reading schema version of database: %s")
assertEquals(t, "expecting %d but got %d", 0, version)
}
......@@ -311,7 +311,7 @@ func (s *Stmt) BindByIndex(index int, value interface{}) error {
cstr := C.CString(value)
rv = C.my_bind_text(s.stmt, i, cstr, C.int(len(value)))
C.free(unsafe.Pointer(cstr))
//rv = C.my_bind_text(s.stmt, i, *((**C.char)(unsafe.Pointer(&value))), C.int(len(value)))
//rv = C.my_bind_text(s.stmt, i, (*C.char)(unsafe.Pointer(&value)), C.int(len(value)))
case int:
rv = C.sqlite3_bind_int(s.stmt, i, C.int(value))
case int64:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment