mirror of
				https://github.com/chaisql/chai.git
				synced 2025-10-31 19:02:48 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package query_test
 | |
| 
 | |
| import (
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/genjidb/genji"
 | |
| 	"github.com/genjidb/genji/database"
 | |
| 	"github.com/genjidb/genji/document"
 | |
| 	"github.com/genjidb/genji/sql/parser"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| )
 | |
| 
 | |
| func parsePath(t testing.TB, str string) document.ValuePath {
 | |
| 	vp, err := parser.ParsePath(str)
 | |
| 	require.NoError(t, err)
 | |
| 	return vp
 | |
| }
 | |
| 
 | |
| func TestCreateTable(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name  string
 | |
| 		query string
 | |
| 		fails bool
 | |
| 	}{
 | |
| 		{"Basic", `CREATE TABLE test`, false},
 | |
| 		{"Exists", "CREATE TABLE test;CREATE TABLE test", true},
 | |
| 		{"If not exists", "CREATE TABLE IF NOT EXISTS test", false},
 | |
| 		{"If not exists, twice", "CREATE TABLE IF NOT EXISTS test;CREATE TABLE IF NOT EXISTS test", false},
 | |
| 		{"With primary key", "CREATE TABLE test(foo TEXT PRIMARY KEY)", false},
 | |
| 		{"With field constraints", "CREATE TABLE test(foo.a[1][2] TEXT primary key, bar[4][0].bat INTEGER not null, baz not null)", false},
 | |
| 		{"With no constraints", "CREATE TABLE test(a, b)", false},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tests {
 | |
| 		t.Run(test.name, func(t *testing.T) {
 | |
| 			db, err := genji.Open(":memory:")
 | |
| 			require.NoError(t, err)
 | |
| 			defer db.Close()
 | |
| 
 | |
| 			err = db.Exec(test.query)
 | |
| 			if test.fails {
 | |
| 				require.Error(t, err)
 | |
| 				return
 | |
| 			}
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			err = db.View(func(tx *genji.Tx) error {
 | |
| 				_, err := tx.GetTable("test")
 | |
| 				return err
 | |
| 			})
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	t.Run("constraints", func(t *testing.T) {
 | |
| 		db, err := genji.Open(":memory:")
 | |
| 		require.NoError(t, err)
 | |
| 		defer db.Close()
 | |
| 
 | |
| 		t.Run("with fixed size data types", func(t *testing.T) {
 | |
| 			err = db.Exec(`CREATE TABLE test(d double, b bool)`)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			err = db.View(func(tx *genji.Tx) error {
 | |
| 				tb, err := tx.GetTable("test")
 | |
| 				if err != nil {
 | |
| 					return err
 | |
| 				}
 | |
| 
 | |
| 				info, err := tb.Info()
 | |
| 				if err != nil {
 | |
| 					return err
 | |
| 				}
 | |
| 
 | |
| 				require.Equal(t, []database.FieldConstraint{
 | |
| 					{Path: parsePath(t, "d"), Type: document.DoubleValue},
 | |
| 					{Path: parsePath(t, "b"), Type: document.BoolValue},
 | |
| 				}, info.FieldConstraints)
 | |
| 				return nil
 | |
| 			})
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 		})
 | |
| 
 | |
| 		t.Run("with variable size data types", func(t *testing.T) {
 | |
| 			err = db.Exec(`
 | |
| 				CREATE TABLE test1(
 | |
| 					foo.bar[1].hello bytes PRIMARY KEY, foo.a[1][2] TEXT NOT NULL, bar[4][0].bat integer, b blob, t text, a array, d document
 | |
| 				)
 | |
| 			`)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			err = db.View(func(tx *genji.Tx) error {
 | |
| 				tb, err := tx.GetTable("test1")
 | |
| 				if err != nil {
 | |
| 					return err
 | |
| 				}
 | |
| 				info, err := tb.Info()
 | |
| 				if err != nil {
 | |
| 					return err
 | |
| 				}
 | |
| 
 | |
| 				require.Equal(t, []database.FieldConstraint{
 | |
| 					{Path: parsePath(t, "foo.bar[1].hello"), Type: document.BlobValue, IsPrimaryKey: true},
 | |
| 					{Path: parsePath(t, "foo.a[1][2]"), Type: document.TextValue, IsNotNull: true},
 | |
| 					{Path: parsePath(t, "bar[4][0].bat"), Type: document.IntegerValue},
 | |
| 					{Path: parsePath(t, "b"), Type: document.BlobValue},
 | |
| 					{Path: parsePath(t, "t"), Type: document.TextValue},
 | |
| 					{Path: parsePath(t, "a"), Type: document.ArrayValue},
 | |
| 					{Path: parsePath(t, "d"), Type: document.DocumentValue},
 | |
| 				}, info.FieldConstraints)
 | |
| 				return nil
 | |
| 			})
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestCreateIndex(t *testing.T) {
 | |
| 	tests := []struct {
 | |
| 		name  string
 | |
| 		query string
 | |
| 		fails bool
 | |
| 	}{
 | |
| 		{"Basic", "CREATE INDEX idx ON test (foo)", false},
 | |
| 		{"If not exists", "CREATE INDEX IF NOT EXISTS idx ON test (foo.bar)", false},
 | |
| 		{"Unique", "CREATE UNIQUE INDEX IF NOT EXISTS idx ON test (foo[1])", false},
 | |
| 		{"No fields", "CREATE INDEX idx ON test", true},
 | |
| 		{"More than 1 field", "CREATE INDEX idx ON test (foo, bar)", true},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tests {
 | |
| 		t.Run(test.name, func(t *testing.T) {
 | |
| 			db, err := genji.Open(":memory:")
 | |
| 			require.NoError(t, err)
 | |
| 			defer db.Close()
 | |
| 
 | |
| 			err = db.Exec("CREATE TABLE test")
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			err = db.Exec(test.query)
 | |
| 			if test.fails {
 | |
| 				require.Error(t, err)
 | |
| 				return
 | |
| 			}
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 	}
 | |
| }
 | 
