diff --git a/dialects_test.go b/dialects_test.go index eafe357..66e3b16 100644 --- a/dialects_test.go +++ b/dialects_test.go @@ -16,12 +16,14 @@ import ( import ( _ "github.com/lib/pq" - _ "github.com/ziutek/mymysql/godrv" + _ "github.com/ziutek/mymysql/godrv" + _ "github.com/mattn/go-sqlite3" ) var toRun = []dialectInfo{ // allDialectInfos[0], // allDialectInfos[1], +//allDialectInfos[2], } var allDialectInfos = []dialectInfo{ @@ -75,6 +77,31 @@ var allDialectInfos = []dialectInfo{ "CREATE INDEX `iname2` ON `itable2` (`d`, `e`)", "DROP INDEX `iname`", }, + dialectInfo{ + NewSQLite3(), + setupSQLite3, + "CREATE TABLE `without_pk` ( `first` text, `last` text, `amount` integer )", + "CREATE TABLE IF NOT EXISTS `without_pk` ( `first` text, `last` text, `amount` integer )", + "CREATE TABLE `with_pk` ( `primary` integer PRIMARY KEY AUTOINCREMENT, `first` text, `last` text, `amount` integer )", + "INSERT INTO `sql_gen_model` (`first`, `last`, `amount`) VALUES (?, ?, ?)", + "UPDATE `sql_gen_model` SET `first` = ?, `last` = ?, `amount` = ? WHERE `prim` = ?", + "DELETE FROM `sql_gen_model` WHERE `prim` = ?", + "DELETE FROM `sql_del_from` WHERE `a` = ? AND `b` > ? OR `c` < ?", + "SELECT * FROM `sql_gen_model`", + "SELECT `col1`, `col2` FROM `sql_gen_model` INNER JOIN `orders` ON `sql_gen_model`.`id1` = `orders`.`id2` WHERE `user`.`id` = `order`.`id` AND `a` > ? OR `b` < ? AND `c` = ? OR `d` = ? GROUP BY `user`.`name` HAVING SUM(price) < ? ORDER BY `user`.`first_name` LIMIT ? OFFSET ?", + "SELECT `col1`, `col2` FROM `sql_gen_model` INNER JOIN `orders` ON `sql_gen_model`.`id1` = `orders`.`id2` WHERE `user`.`id` = `order`.`id` AND `a` > ? OR `b` < ? AND `c` = ? OR `d` = ? GROUP BY `user`.`name` HAVING SUM(price) < ? ORDER BY `user`.`first_name` ASC LIMIT ? OFFSET ?", + "SELECT `col1`, `col2` FROM `sql_gen_model` INNER JOIN `orders` ON `sql_gen_model`.`id1` = `orders`.`id2` WHERE `user`.`id` = `order`.`id` AND `a` > ? OR `b` < ? AND `c` = ? OR `d` = ? GROUP BY `user`.`name` HAVING SUM(price) < ? ORDER BY `user`.`first_name` DESC LIMIT ? OFFSET ?", + "DROP TABLE `drop_table`", + "DROP TABLE IF EXISTS `drop_table`", + "ALTER TABLE `table_a` RENAME TO `table_b`", + "ALTER TABLE `a` ADD COLUMN `c` varchar(100)", + "ALTER TABLE `a` RENAME COLUMN `b` TO `c`", + "ALTER TABLE `a` ALTER COLUMN `b` TYPE varchar(100)", + "ALTER TABLE `a` DROP COLUMN `b`", + "CREATE UNIQUE INDEX `iname` ON `itable` (`a`, `b`, `c`)", + "CREATE INDEX `iname2` ON `itable2` (`d`, `e`)", + "DROP INDEX `iname`", + }, } type dialectInfo struct { @@ -124,6 +151,16 @@ func setupMysql(t *testing.T) *Hood { return hd } +func setupSQLite3(t *testing.T) *Hood { + db, err := sql.Open("sqlite3",":memory:") + if err != nil { + t.Fatal("could not open db", err) + } + hd := New(db, NewSQLite3()) + hd.Log = true + return hd +} + func TestTransaction(t *testing.T) { for _, info := range toRun { DoTestTransaction(t, info) diff --git a/sqlite3.go b/sqlite3.go new file mode 100644 index 0000000..6a0dbcc --- /dev/null +++ b/sqlite3.go @@ -0,0 +1,62 @@ +package hood + +import ( + "fmt" + "reflect" + "time" +) + +func init() { + RegisterDialect("sqlite3", NewSQLite3()) +} + +type sqlite3 struct { + base +} + +func NewSQLite3() Dialect { + d := &sqlite3{} + d.base.Dialect = d + return d +} + +func (d *sqlite3) NextMarker(pos *int) string { + return "?" +} + +func (d *sqlite3) Quote(s string) string { + return fmt.Sprintf("`%s`", s) +} + +func (d *sqlite3) ParseBool(value reflect.Value) bool { + return value.Int() != 0 +} + +func (d *sqlite3) SqlType(f interface{}, size int) string { + switch f.(type) { + case Id: + return "integer" + case time.Time, Created, Updated: + return "datetime" + case bool: + return "integer" + case int, int8, int16, int32, uint, uint8, uint16, uint32: + return "integer" + case int64, uint64: + return "integer" + case float32, float64: + return "real" + case []byte: + return "blob" + case string: + if size > 0 && size < 65532 { + return fmt.Sprintf("varchar(%d)", size) + } + return "text" + } + panic("invalid sql type") +} + +func (d *sqlite3) KeywordAutoIncrement() string { + return "AUTOINCREMENT" +}