package duckdb_test import ( "os" "testing" "git.fsdpf.net/go/db/engine" "git.fsdpf.net/go/db/schema" "github.com/stretchr/testify/suite" _ "github.com/marcboeker/go-duckdb" ) type duckDBTest struct { suite.Suite schema schema.Schema } var ( tableName = "entry" dropTable = "DROP TABLE IF EXISTS entry;" createTable = "CREATE TABLE entry (" + "id INTEGER PRIMARY KEY," + "int INTEGER NOT NULL UNIQUE," + "float REAL NOT NULL," + "string VARCHAR(255) NOT NULL," + "time TIMESTAMP NOT NULL," + "bool BOOLEAN NOT NULL," + "bytes BLOB NOT NULL" + ");" ) func TestDuckDBSuite(t *testing.T) { suite.Run(t, new(duckDBTest)) } func (t *duckDBTest) SetupSuite() { dbPath := os.Getenv("DUCKDB_PATH") if dbPath == "" { dbPath = "" } db := engine.Open(map[string]engine.DBConfig{ "test-duckdb": engine.NewDBConfig("duckdb", engine.WithDuckDBFile(dbPath), ), }).Connection("test-duckdb") t.schema = schema.GetSchemaDialect(db) db.Exec(dropTable) db.Exec(createTable) } func (t *duckDBTest) TestGetColumnListing() { result, err := t.schema.GetColumnListing(tableName) t.Require().NoError(err) t.Require().ElementsMatch([]string{"id", "int", "float", "string", "time", "bool", "bytes"}, result) } func (t *duckDBTest) TestTableExists() { result, err := t.schema.TableExists(tableName) t.Require().NoError(err) t.Require().Equal(result, true) } func (t *duckDBTest) TestCompileCreate() { bp := schema.NewBlueprint("users") bp.Create() bp.BigIncrements("id").AutoIncrement().Comment("ID") bp.Boolean("enabled").Default("1").Comment("是否有效") bp.Char("created_user", 36).Default("00000000-0000-0000-0000-000000000000").Comment("创建者") bp.Char("owned_user", 36).Default("00000000-0000-0000-0000-000000000000").Comment("拥有者") bp.Timestamp("created_at").UseCurrent().Comment("创建时间") bp.Timestamp("updated_at").UseCurrent().Comment("更新时间") bp.DateTime("deleted_at").Nullable().Comment("删除时间") sql := t.schema.CompileCreate(bp) t.Equal([]string{ "CREATE SEQUENCE IF NOT EXISTS \"users_id_seq\"", "CREATE TABLE IF NOT EXISTS \"users\" (\n" + "\"id\" BIGINT DEFAULT nextval('users_id_seq') PRIMARY KEY,\n" + "\"enabled\" BOOLEAN NOT NULL DEFAULT '1',\n" + "\"created_user\" CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',\n" + "\"owned_user\" CHAR(36) NOT NULL DEFAULT '00000000-0000-0000-0000-000000000000',\n" + "\"created_at\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n" + "\"updated_at\" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n" + "\"deleted_at\" TIMESTAMP NULL\n" + ")", "COMMENT ON COLUMN \"users\".\"id\" IS 'ID'", "COMMENT ON COLUMN \"users\".\"enabled\" IS '是否有效'", "COMMENT ON COLUMN \"users\".\"created_user\" IS '创建者'", "COMMENT ON COLUMN \"users\".\"owned_user\" IS '拥有者'", "COMMENT ON COLUMN \"users\".\"created_at\" IS '创建时间'", "COMMENT ON COLUMN \"users\".\"updated_at\" IS '更新时间'", "COMMENT ON COLUMN \"users\".\"deleted_at\" IS '删除时间'", }, sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileAdd() { bp := schema.NewBlueprint("users") bp.String("name", 50).Comment("用户名") bp.SmallInteger("age").Default("18").Comment("年龄") bp.String("sex", 1).Default("0").Comment("性别") sql := t.schema.CompileAdd(bp) t.Equal([]string{ "ALTER TABLE \"users\"\n" + "ADD COLUMN \"name\" VARCHAR(50) NOT NULL,\n" + "ADD COLUMN \"age\" SMALLINT NOT NULL DEFAULT '18',\n" + "ADD COLUMN \"sex\" VARCHAR(1) NOT NULL DEFAULT '0'", "COMMENT ON COLUMN \"users\".\"name\" IS '用户名'", "COMMENT ON COLUMN \"users\".\"age\" IS '年龄'", "COMMENT ON COLUMN \"users\".\"sex\" IS '性别'", }, sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileChange() { bp := schema.NewBlueprint("users") bp.String("name", 50).Change("username") bp.SmallInteger("age").Default("19").Comment("年龄").Change() sql := t.schema.CompileChange(bp) t.Require().NotEmpty(sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileDropColumn() { bp := schema.NewBlueprint("users") bp.DropColumn("age", "sex") sql := t.schema.CompileDropColumn(bp) t.Equal([]string{ "ALTER TABLE \"users\"\n" + "DROP COLUMN \"age\",\n" + "DROP COLUMN \"sex\"", }, sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileDrop() { bp := schema.NewBlueprint("users") bp.Drop() sql := t.schema.CompileDrop(bp) t.Equal([]string{"DROP TABLE \"users\""}, sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileDropIfExists() { bp := schema.NewBlueprint("users") bp.Drop() sql := t.schema.CompileDropIfExists(bp) t.Equal([]string{"DROP TABLE IF EXISTS \"users\""}, sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileRename() { bp := schema.NewBlueprint("users") bp.Rename("user") sql := t.schema.CompileRename(bp) t.Equal([]string{"ALTER TABLE \"users\" RENAME TO \"user\""}, sql) t.T().Log(sql) } func (t *duckDBTest) TestCompileModifyComment() { bp := schema.NewBlueprint("users") bp.Comment = "用户表" sql := t.schema.CompileModifyComment(bp) t.Equal([]string{"COMMENT ON TABLE \"users\" IS '用户表'"}, sql) t.T().Log(sql) }