diff --git a/Makefile b/Makefile index 185ac0e..1bac962 100644 --- a/Makefile +++ b/Makefile @@ -44,9 +44,9 @@ test-sqlite: install cd internal/integration && queryx db:migrate --schema sqlite.hcl cd internal/integration && queryx db:migrate --schema sqlite.hcl cd internal/integration && queryx generate --schema sqlite.hcl - cd internal/integration && yarn tsc - cd internal/integration && yarn test - # cd internal/integration && go test ./... +# cd internal/integration && yarn tsc +# cd internal/integration && yarn test + cd internal/integration && go test ./... test: test-postgresql test-sqlite test-mysql @@ -56,3 +56,66 @@ test-migrate: install sleep 1 cd internal/migrate && queryx db:migrate --schema sqlite2.hcl cd internal/migrate && sqlite3 test.sqlite3 "insert into users(name, email) values('test', 'test@example.com')" + + +benchmarks-golang-postgresql: install + cd internal/benchmarks/go-queryx && rm -rf db + cd internal/benchmarks/go-queryx && queryx db:drop --schema postgresql.hcl + cd internal/benchmarks/go-queryx && queryx db:create --schema postgresql.hcl + cd internal/benchmarks/go-queryx && queryx db:migrate --schema postgresql.hcl + cd internal/benchmarks/go-queryx && queryx g --schema postgresql.hcl + cd internal/benchmarks && go build -o bin/queryxorm main.go + cd internal/benchmarks && install bin/queryxorm /usr/local/bin + queryxorm -adapter=postgresql + +benchmarks-golang-mysql: install + cd internal/benchmarks/go-queryx && rm -rf db + cd internal/benchmarks/go-queryx && queryx db:drop --schema mysql.hcl + cd internal/benchmarks/go-queryx && queryx db:create --schema mysql.hcl + cd internal/benchmarks/go-queryx && queryx db:migrate --schema mysql.hcl + cd internal/benchmarks/go-queryx && queryx g --schema mysql.hcl + cd internal/benchmarks && go build -o bin/queryxorm main.go + cd internal/benchmarks && install bin/queryxorm /usr/local/bin + queryxorm -adapter=mysql + +benchmarks-golang-sqlite: install + cd internal/benchmarks/go-queryx && rm -rf db + cd internal/benchmarks/go-queryx && queryx db:drop --schema sqlite.hcl + cd internal/benchmarks/go-queryx && queryx db:create --schema sqlite.hcl + cd internal/benchmarks/go-queryx && queryx db:migrate --schema sqlite.hcl + cd internal/benchmarks/go-queryx && queryx g --schema sqlite.hcl + cd internal/benchmarks && go build -o bin/queryxorm main.go + cd internal/benchmarks && install bin/queryxorm /usr/local/bin + queryxorm -adapter=sqlite + +benchmarks-golang: install benchmarks-golang-mysql benchmarks-golang-sqlite benchmarks-golang-postgresql + +benchmarks-typescript-postgresql: install + cd internal/benchmarks/ts-queryx && rm -rf db + cd internal/benchmarks/ts-queryx && queryx db:drop --schema postgresql.hcl + cd internal/benchmarks/ts-queryx && queryx db:create --schema postgresql.hcl + cd internal/benchmarks/ts-queryx && queryx db:migrate --schema postgresql.hcl + cd internal/benchmarks/ts-queryx && queryx g --schema postgresql.hcl + cd internal/benchmarks/ts-queryx && tsc benchmark.test.ts + cd internal/benchmarks/ts-queryx && node benchmark.test.js + + +benchmarks-typescript-mysql: install + cd internal/benchmarks/ts-queryx && rm -rf db + cd internal/benchmarks/ts-queryx && queryx db:drop --schema mysql.hcl + cd internal/benchmarks/ts-queryx && queryx db:create --schema mysql.hcl + cd internal/benchmarks/ts-queryx && queryx db:migrate --schema mysql.hcl + cd internal/benchmarks/ts-queryx && queryx g --schema mysql.hcl + cd internal/benchmarks/ts-queryx && yarn + cd internal/benchmarks/ts-queryx && tsc benchmark.test.ts + cd internal/benchmarks/ts-queryx && node benchmark.test.js + + +benchmarks-typescript-sqlite: install + cd internal/benchmarks/ts-queryx && rm -rf db + cd internal/benchmarks/ts-queryx && queryx db:drop --schema sqlite.hcl + cd internal/benchmarks/ts-queryx && queryx db:create --schema sqlite.hcl + cd internal/benchmarks/ts-queryx && queryx db:migrate --schema sqlite.hcl + cd internal/benchmarks/ts-queryx && queryx g --schema sqlite.hcl + cd internal/benchmarks/ts-queryx && tsc benchmark.test.ts + cd internal/benchmarks/ts-queryx && node benchmark.test.js diff --git a/benchmarks-results.md b/benchmarks-results.md new file mode 100644 index 0000000..02d783b --- /dev/null +++ b/benchmarks-results.md @@ -0,0 +1,73 @@ +# Results + +- orm-benchmark +``` +golang-mysql-Reports: +InsertAll +queryx: 24 68688983 ns/op 279390 B/op 3296 allocs/op + +Create +queryx: 50 24818608 ns/op 16685 B/op 253 allocs/op + +Update +queryx: 1215 968346 ns/op 7980 B/op 114 allocs/op + +Read +queryx: 1201 976828 ns/op 9196 B/op 155 allocs/op + +ReadSlice +queryx: 762 2458304 ns/op 386941 B/op 12405 allocs/op + + +golang-sqlite-Reports: +ReadSlice +queryx: 358 3447322 ns/op 398725 B/op 16991 allocs/op + +InsertAll +queryx: 48 31670682 ns/op 246893 B/op 3898 allocs/op + +Create +queryx: 72 18938976 ns/op 11278 B/op 238 allocs/op + +Update +queryx: 499 3277440 ns/op 8052 B/op 127 allocs/op + +Read +queryx: 903 1488458 ns/op 9252 B/op 208 allocs/op + + +golang-postgresql-Reports: +InsertAll +queryx: 134 8033703 ns/op 289751 B/op 3505 allocs/op + +Create +queryx: 194 5316417 ns/op 10501 B/op 184 allocs/op + +Update +queryx: 208 5298013 ns/op 7944 B/op 116 allocs/op + +Read +queryx: 1186 1187729 ns/op 9278 B/op 157 allocs/op + +ReadSlice +queryx: 1008 2237629 ns/op 348255 B/op 10661 allocs/op + +typescript-mysql-Reports: +create: x 790 ops/sec ±191.34% (36 runs sampled) +insertAll: x 591 ops/sec ±60.50% (20 runs sampled) +find x 4,631 ops/sec ±24.66% (34 runs sampled) +update: x 760 ops/sec ±87.89% (10 runs sampled) + +typescript-postgresql-Reports: +create: x 1,071 ops/sec ±86.40% (9 runs sampled) +insertAll: x 8,521 ops/sec ±21.30% (35 runs sampled) +find: x 4,269 ops/sec ±16.80% (52 runs sampled) +update: x 1,860 ops/sec ±46.43% (38 runs sampled) + +typescript-sqlite-Reports: +create:x 25,930 ops/sec +18.77%(44 runs sampled) +insertAll:x14,361 ops/sec +66.85%(29 runs sampled) +find x 1.087 ops/sec +78.85%(13 runs sampled) +update:x 2,225 ops/sec +18.76%(36 runs sampled) + +``` diff --git a/generator/client/typescript/templates/queryx/adapter.mysql.ts b/generator/client/typescript/templates/queryx/adapter.mysql.ts index 22c21bf..bb35f89 100644 --- a/generator/client/typescript/templates/queryx/adapter.mysql.ts +++ b/generator/client/typescript/templates/queryx/adapter.mysql.ts @@ -1,6 +1,6 @@ // Code generated by queryx, DO NOT EDIT. -import mysql, { ResultSetHeader, RowDataPacket } from "mysql2/promise"; +import mysql, { createPool, ResultSetHeader, RowDataPacket } from "mysql2/promise"; import { parse } from "date-fns"; import { Config } from "./config"; @@ -14,7 +14,7 @@ export class Adapter { } connect() { - const pool = mysql.createPool({ + const pool = createPool({ uri: this.config.url, }); this.pool = pool; diff --git a/internal/benchmarks/go-queryx/helper/sql.go b/internal/benchmarks/go-queryx/helper/sql.go new file mode 100644 index 0000000..567d799 --- /dev/null +++ b/internal/benchmarks/go-queryx/helper/sql.go @@ -0,0 +1,62 @@ +package helper + +import ( + "fmt" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db" + "log" +) + +const ( + sqlSqliteCreateTable = `CREATE TABLE models ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + name varchar NULL, + title varchar NULL, + fax varchar NULL, + web varchar NULL, + age bigint NULL, + righ boolean NULL, + counter integer NULL + );` + sqlPostgresCreateTable = `CREATE TABLE "public"."models" ( + "id" bigserial NOT NULL, + "name" character varying NULL, + "title" character varying NULL, + "fax" character varying NULL, + "web" character varying NULL, + "age" bigint NULL, + "righ" boolean NULL, + "counter" integer NULL, + PRIMARY KEY ("id"));` + sqlMysqlCreateTable = `CREATE TABLE test.models ( + id bigint NOT NULL AUTO_INCREMENT, + name varchar(255) NULL, title varchar(255) NULL, + fax varchar(255) NULL, web varchar(255) NULL, + age bigint NULL, + righ bool NULL, + counter int NULL, + PRIMARY KEY (id));` +) + +func CreateTables(client *db.QXClient, adapter string) error { + var sql string + switch adapter { + case "mysql": + sql = sqlMysqlCreateTable + case "postgresql": + sql = sqlPostgresCreateTable + case "sqlite": + sql = sqlSqliteCreateTable + default: + return fmt.Errorf("this type of adapter is not supported:%v", adapter) + } + _, err := client.Exec(`DROP TABLE IF EXISTS models;`) + if err != nil { + return err + } + _, err = client.Exec(sql) + if err != nil { + log.Fatal(err) + return err + } + return err +} diff --git a/internal/benchmarks/go-queryx/helper/suite.go b/internal/benchmarks/go-queryx/helper/suite.go new file mode 100644 index 0000000..2f0b68b --- /dev/null +++ b/internal/benchmarks/go-queryx/helper/suite.go @@ -0,0 +1,81 @@ +package helper + +import ( + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db" + "testing" +) + +type ORMInterface interface { + Name() string + Init() (*db.QXClient, error) + Create(b *testing.B) + InsertAll(b *testing.B) + Update(b *testing.B) + Read(b *testing.B) + ReadSlice(b *testing.B) +} + +type BenchmarkResult struct { + ORM string + Results []Result +} + +type Result struct { + Name string + Method string + ErrorMsg string + + N int + NsPerOp int64 + MemAllocs int64 + MemBytes int64 +} + +type BenchmarkReport []*Result + +func (s BenchmarkReport) Len() int { return len(s) } + +func (s BenchmarkReport) Swap(i, j int) { s[i], s[j] = s[j], s[i] } + +func (s BenchmarkReport) Less(i, j int) bool { + if s[i].ErrorMsg != "" { + return false + } + if s[j].ErrorMsg != "" { + return true + } + return s[i].NsPerOp < s[j].NsPerOp +} + +func RunBenchmarks(adapter string, orm ORMInterface, reports map[string]BenchmarkReport) error { + c, err := orm.Init() + if err != nil { + return err + } + + operations := []func(b *testing.B){orm.InsertAll, orm.Create, orm.Update, orm.Read, orm.ReadSlice} + + for _, operation := range operations { + err = CreateTables(c, adapter) + if err != nil { + return err + } + + br := testing.Benchmark(operation) + method := getFuncName(operation) + + gotResult := &Result{ + Name: orm.Name(), + Method: method, + ErrorMsg: GetError(orm.Name(), method), + N: br.N, + NsPerOp: br.NsPerOp(), + MemAllocs: br.AllocsPerOp(), + MemBytes: br.AllocedBytesPerOp(), + } + + reports[method] = append(reports[method], gotResult) + } + + return nil +} diff --git a/internal/benchmarks/go-queryx/helper/tools.go b/internal/benchmarks/go-queryx/helper/tools.go new file mode 100644 index 0000000..32de89f --- /dev/null +++ b/internal/benchmarks/go-queryx/helper/tools.go @@ -0,0 +1,33 @@ +package helper + +import ( + "reflect" + "runtime" + "strings" + "sync" + "testing" +) + +var Errors map[string]map[string]string + +var mu sync.Mutex + +func SetError(b *testing.B, orm, method, err string) { + b.Helper() + + mu.Lock() + Errors[orm][method] = err + mu.Unlock() + b.Fail() +} + +func GetError(orm, method string) string { + return Errors[orm][method] +} + +func getFuncName(function interface{}) string { + name := strings.Split(runtime.FuncForPC(reflect.ValueOf(function).Pointer()).Name(), ".") + straightName := strings.Split(name[len(name)-1], "-")[0] + + return straightName +} diff --git a/internal/benchmarks/go-queryx/models.go b/internal/benchmarks/go-queryx/models.go new file mode 100644 index 0000000..2623eed --- /dev/null +++ b/internal/benchmarks/go-queryx/models.go @@ -0,0 +1,26 @@ +package go_queryx + +// Model for go-queryx +type Model struct { + ID int `column:"id"` + Name string `column:"name"` + Title string `column:"title"` + Fax string `column:"fax"` + Web string `column:"web"` + Age int64 `column:"age"` + Righ bool `column:"righ"` + Counter int32 `column:"counter"` +} + +func NewModel() *Model { + m := new(Model) + m.Name = "Orm Benchmark" + m.Title = "Just a Benchmark for fun" + m.Fax = "99909990" + m.Web = "http://blog.milkpod29.me" + m.Age = 100 + m.Righ = true + m.Counter = 1000 + + return m +} diff --git a/internal/benchmarks/go-queryx/mysql.hcl b/internal/benchmarks/go-queryx/mysql.hcl new file mode 100644 index 0000000..f60130d --- /dev/null +++ b/internal/benchmarks/go-queryx/mysql.hcl @@ -0,0 +1,41 @@ +database "db" { + adapter = "mysql" + time_zone = "Asia/Shanghai" + + config "development" { + url = "mysql://root:@127.0.0.1:3306/test" + } + config "test" { + url = env("DATABASE_URL") + } + + generator "client-golang" { + test = true + } + + model "Model" { + timestamps = false + column "name" { + type = string + } + column "title" { + type = string + } + column "fax" { + type = string + } + column "web" { + type = string + } + column "age" { + type = bigint + } + column "righ" { + type = boolean + } + column "counter" { + type = integer + } + } + +} diff --git a/internal/benchmarks/go-queryx/postgresql.hcl b/internal/benchmarks/go-queryx/postgresql.hcl new file mode 100644 index 0000000..f087591 --- /dev/null +++ b/internal/benchmarks/go-queryx/postgresql.hcl @@ -0,0 +1,41 @@ +database "db" { + adapter = "postgresql" + time_zone = "Asia/Shanghai" + + config "development" { + url = "postgresql://postgres:postgres@localhost:5432/test?sslmode=disable" + } + config "test" { + url = env("DATABASE_URL") + } + + generator "client-golang" { + test = true + } + + model "Model" { + timestamps = false + column "name" { + type = string + } + column "title" { + type = string + } + column "fax" { + type = string + } + column "web" { + type = string + } + column "age" { + type = bigint + } + column "righ" { + type = boolean + } + column "counter" { + type = integer + } + } + +} diff --git a/internal/benchmarks/go-queryx/queryx.go b/internal/benchmarks/go-queryx/queryx.go new file mode 100644 index 0000000..b3b0092 --- /dev/null +++ b/internal/benchmarks/go-queryx/queryx.go @@ -0,0 +1,134 @@ +package go_queryx + +import ( + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db/queryx" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/helper" + "testing" +) + +var ( + c *db.QXClient +) + +const ( + queryxSelectMultiSQL = `SELECT * FROM models WHERE id > 0` +) + +type Queryx struct { + helper.ORMInterface +} + +func CreateQueryx() helper.ORMInterface { + return &Queryx{} +} + +func (Queryx *Queryx) Name() string { + return "queryx" +} + +func (Queryx *Queryx) Init() (*db.QXClient, error) { + client, err := db.NewClient() + if err != nil { + return nil, err + } + c = client + return client, err +} + +func (Queryx *Queryx) Create(b *testing.B) { + m := NewModel() + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := c.QueryModel().Create(c.ChangeModel().SetName(m.Name). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(m.Age).SetCounter(m.Counter).SetRigh(m.Righ)) + if err != nil { + helper.SetError(b, Queryx.Name(), "Create", err.Error()) + } + } +} + +func (Queryx *Queryx) InsertAll(b *testing.B) { + m := NewModel() + ms := make([]*queryx.ModelChange, 0, 100) + for i := 0; i < 100; i++ { + ms = append(ms, c.ChangeModel().SetName(m.Name). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(m.Age).SetCounter(m.Counter).SetRigh(m.Righ)) + } + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := c.QueryModel().InsertAll(ms) + if err != nil { + helper.SetError(b, Queryx.Name(), "InsertAll", err.Error()) + } + } +} + +func (Queryx *Queryx) Update(b *testing.B) { + m := NewModel() + + change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(m.Age).SetCounter(m.Counter) + m8, err := c.QueryModel().Create(change) + if err != nil { + helper.SetError(b, Queryx.Name(), "Update", err.Error()) + } + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := c.QueryModel().Where(c.ModelID.EQ(m8.ID)).UpdateAll(change) + if err != nil { + helper.SetError(b, Queryx.Name(), "UpdateAll", err.Error()) + } + } +} + +func (Queryx *Queryx) Read(b *testing.B) { + m := NewModel() + change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(m.Age).SetCounter(m.Counter) + _, err := c.QueryModel().Create(change) + if err != nil { + helper.SetError(b, Queryx.Name(), "Read", err.Error()) + } + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := c.QueryModel().FindBy(c.ModelName.EQ(m.Name)) + if err != nil { + helper.SetError(b, Queryx.Name(), "FindBy", err.Error()) + } + } +} + +func (Queryx *Queryx) ReadSlice(b *testing.B) { + m := NewModel() + change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(m.Age).SetCounter(m.Counter) + for i := 0; i < 100; i++ { + _, err := c.QueryModel().Create(change) + if err != nil { + helper.SetError(b, Queryx.Name(), "ReadSlice", err.Error()) + } + } + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := c.QueryModel().FindBySQL(queryxSelectMultiSQL) + if err != nil { + helper.SetError(b, Queryx.Name(), "FindBySQL", err.Error()) + } + } +} diff --git a/internal/benchmarks/go-queryx/sqlite.hcl b/internal/benchmarks/go-queryx/sqlite.hcl new file mode 100644 index 0000000..0faee32 --- /dev/null +++ b/internal/benchmarks/go-queryx/sqlite.hcl @@ -0,0 +1,41 @@ +database "db" { + adapter = "sqlite" + time_zone = "Asia/Shanghai" + + config "development" { + url = "sqlite:test.sqlite3" + } + config "test" { + url = env("DATABASE_URL") + } + + generator "client-golang" { + test = true + } + + model "Model" { + timestamps = false + column "name" { + type = string + } + column "title" { + type = string + } + column "fax" { + type = string + } + column "web" { + type = string + } + column "age" { + type = bigint + } + column "righ" { + type = boolean + } + column "counter" { + type = integer + } + } + +} diff --git a/internal/benchmarks/main.go b/internal/benchmarks/main.go new file mode 100644 index 0000000..46775a3 --- /dev/null +++ b/internal/benchmarks/main.go @@ -0,0 +1,54 @@ +package main + +import ( + "flag" + "fmt" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/helper" + "os" + "runtime" + "sort" + "text/tabwriter" +) + +var adapter string + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU()) + flag.StringVar(&adapter, "adapter", "postgresql", "-orm=postgresql") + flag.Parse() + helper.Errors = make(map[string]map[string]string, 0) + helper.Errors["queryx"] = make(map[string]string, 0) + runBenchmarks(adapter) +} + +func runBenchmarks(adapter string) { + table := new(tabwriter.Writer) + table.Init(os.Stdout, 0, 8, 2, '\t', tabwriter.AlignRight) + reports := make(map[string]helper.BenchmarkReport, 0) + err := helper.RunBenchmarks(adapter, go_queryx.CreateQueryx(), reports) + if err != nil { + panic(fmt.Sprintf("An error occured while running the benchmarks: %v", err)) + } + for _, v := range reports { + sort.Sort(v) + } + _, _ = fmt.Fprintf(table, "Reports:\n\n") + i := 1 + for method, report := range reports { + _, _ = fmt.Fprintf(table, "%s\n", method) + for _, result := range report { + if result.ErrorMsg == "" { + _, _ = fmt.Fprintf(table, "%s:\t%d\t%d ns/op\t%d B/op\t%d allocs/op\n", result.Name, result.N, result.NsPerOp, result.MemBytes, result.MemAllocs) + } else { + _, _ = fmt.Fprintf(table, "%s:\t%s\n", result.Name, result.ErrorMsg) + } + } + + if i != len(reports) { + _, _ = fmt.Fprintf(table, "\n") + } + i++ + } + _ = table.Flush() +} diff --git a/internal/benchmarks/ts-queryx/benchmark.test.ts b/internal/benchmarks/ts-queryx/benchmark.test.ts new file mode 100644 index 0000000..51421c4 --- /dev/null +++ b/internal/benchmarks/ts-queryx/benchmark.test.ts @@ -0,0 +1,67 @@ +import { newClient,Model} from "./db"; +import * as Benchmark from 'benchmark'; + +const suite = new Benchmark.Suite(); +const c=newClient() +let model: Model + + +function benchmarkCreate(){ + suite + .on('complete', (event: { target: any; }) => { + console.log(String(event.target)); + }).add('create:', async () => { + model = await c.queryModel().create({ + name: "benchmark", + title: "title", + fax: "fax", + web: "web", + age: 122, + righ: true, + counter: 1222 + }); + }).run() + .add("insertAll:",async () => { + await c.queryModel().insertAll([{ + name: "all1benchmark", + title: "title", + fax: "fax", + web: "web", + age: 122, + righ: true, + counter: 1222 + }, { + name: "all2benchmark", + title: "title", + fax: "fax", + web: "web", + age: 122, + righ: true, + counter: 1222 + }, { + name: "all3benchmark", + title: "title", + fax: "fax", + web: "web", + age: 122, + righ: true, + counter: 1222 + }]) + }).run() + .add("find:",async () => { + await c.queryModel().find(model.id) + }).run() + .add( "update:", async () => { + await c.queryModel().where(c.modelID.eq(model.id)).updateAll({ + name: "benchmark-update", + title: "title", + fax: "fax", + web: "web", + age: 122, + righ: true, + counter: 1222 + }); + }).run() + ; +} +benchmarkCreate() diff --git a/internal/benchmarks/ts-queryx/mysql.hcl b/internal/benchmarks/ts-queryx/mysql.hcl new file mode 100644 index 0000000..c870925 --- /dev/null +++ b/internal/benchmarks/ts-queryx/mysql.hcl @@ -0,0 +1,41 @@ +database "db" { + adapter = "mysql" + time_zone = "Asia/Shanghai" + + config "development" { + url = "mysql://root:@127.0.0.1:3306/test" + } + config "test" { + url = env("DATABASE_URL") + } + + generator "client-typescript" { + test = true + } + + model "Model" { + timestamps = false + column "name" { + type = string + } + column "title" { + type = string + } + column "fax" { + type = string + } + column "web" { + type = string + } + column "age" { + type = bigint + } + column "righ" { + type = boolean + } + column "counter" { + type = integer + } + } + +} diff --git a/internal/benchmarks/ts-queryx/package.json b/internal/benchmarks/ts-queryx/package.json new file mode 100644 index 0000000..b0e124b --- /dev/null +++ b/internal/benchmarks/ts-queryx/package.json @@ -0,0 +1,15 @@ +{ + "name": "ts-queryx", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "@types/better-sqlite3": "^7.6.4", + "@types/pg": "^8.10.2", + "better-sqlite3": "^9.3.0", + "date-fns": "^2.30.0", + "mysql2": "^3.8.0", + "pg": "^8.11.3", + "tsc": "^2.0.4" + } +} diff --git a/internal/benchmarks/ts-queryx/postgresql.hcl b/internal/benchmarks/ts-queryx/postgresql.hcl new file mode 100644 index 0000000..e559062 --- /dev/null +++ b/internal/benchmarks/ts-queryx/postgresql.hcl @@ -0,0 +1,41 @@ +database "db" { + adapter = "postgresql" + time_zone = "Asia/Shanghai" + + config "development" { + url = "postgresql://postgres:postgres@localhost:5432/test?sslmode=disable" + } + config "test" { + url = env("DATABASE_URL") + } + + generator "client-typescript" { + test = true + } + + model "Model" { + timestamps = false + column "name" { + type = string + } + column "title" { + type = string + } + column "fax" { + type = string + } + column "web" { + type = string + } + column "age" { + type = bigint + } + column "righ" { + type = boolean + } + column "counter" { + type = integer + } + } + +} diff --git a/internal/benchmarks/ts-queryx/sqlite.hcl b/internal/benchmarks/ts-queryx/sqlite.hcl new file mode 100644 index 0000000..8ef7380 --- /dev/null +++ b/internal/benchmarks/ts-queryx/sqlite.hcl @@ -0,0 +1,41 @@ +database "db" { + adapter = "sqlite" + time_zone = "Asia/Shanghai" + + config "development" { + url = "sqlite:test.sqlite3" + } + config "test" { + url = env("DATABASE_URL") + } + + generator "client-typescript" { + test = true + } + + model "Model" { + timestamps = false + column "name" { + type = string + } + column "title" { + type = string + } + column "fax" { + type = string + } + column "web" { + type = string + } + column "age" { + type = bigint + } + column "righ" { + type = boolean + } + column "counter" { + type = integer + } + } + +} diff --git a/internal/benchmarks/ts-queryx/tsconfig.json b/internal/benchmarks/ts-queryx/tsconfig.json new file mode 100644 index 0000000..75a94b9 --- /dev/null +++ b/internal/benchmarks/ts-queryx/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ESNext", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "module": "ESNext", /* Specify what module code is generated. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + "lib": ["ESNext", "DOM"], + "strict": true, + "moduleResolution": "Node", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "useDefineForClassFields": true, + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/package.json b/package.json index 5887d16..f2b7ff8 100644 --- a/package.json +++ b/package.json @@ -10,5 +10,12 @@ "devDependencies": { "vitepress": "1.0.0-rc.10", "vitepress-plugin-tabs": "^0.4.1" + }, + "dependencies": { + "@types/benchmark": "^2.1.5", + "@types/lodash": "^4.14.202", + "benchmark": "^2.1.4", + "tsc": "^2.0.4", + "typescript": "^5.3.3" } } diff --git a/yarn.lock b/yarn.lock index edf3ac4..d2d686e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -276,6 +276,16 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== +"@types/benchmark@^2.1.5": + version "2.1.5" + resolved "https://registry.npmmirror.com/@types/benchmark/-/benchmark-2.1.5.tgz#940c1850c18fdfdaee3fd6ed29cd92ae0d445b45" + integrity sha512-cKio2eFB3v7qmKcvIHLUMw/dIx/8bhWPuzpzRT4unCPRTD8VdA9Zb0afxpcxOqR4PixRS7yT42FqGS8BYL8g1w== + +"@types/lodash@^4.14.202": + version "4.14.202" + resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== + "@types/web-bluetooth@^0.0.17": version "0.0.17" resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.17.tgz#5c9f3c617f64a9735d7b72a7cc671e166d900c40" @@ -432,6 +442,14 @@ ansi-sequence-parser@^1.1.0: resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== +benchmark@^2.1.4: + version "2.1.4" + resolved "https://registry.npmmirror.com/benchmark/-/benchmark-2.1.4.tgz#09f3de31c916425d498cc2ee565a0ebf3c2a5629" + integrity sha512-l9MlfN4M1K/H2fbhfMy3B7vJd6AGKJVQn2h6Sg/Yx+KckoUA7ewS5Vv6TjSq18ooE1kS9hhAlQRH3AkXIh/aOQ== + dependencies: + lodash "^4.17.4" + platform "^1.3.3" + csstype@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" @@ -487,6 +505,11 @@ jsonc-parser@^3.2.0: resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== +lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + magic-string@^0.30.0: version "0.30.3" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.3.tgz#403755dfd9d6b398dfa40635d52e96c5ac095b85" @@ -514,6 +537,11 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== +platform@^1.3.3: + version "1.3.6" + resolved "https://registry.npmmirror.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7" + integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg== + postcss@^8.1.10, postcss@^8.4.27: version "8.4.30" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.30.tgz#0e0648d551a606ef2192a26da4cabafcc09c1aa7" @@ -555,6 +583,16 @@ tabbable@^6.2.0: resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== +tsc@^2.0.4: + version "2.0.4" + resolved "https://registry.npmmirror.com/tsc/-/tsc-2.0.4.tgz#5f6499146abea5dca4420b451fa4f2f9345238f5" + integrity sha512-fzoSieZI5KKJVBYGvwbVZs/J5za84f2lSTLPYf6AGiIf43tZ3GNrI1QzTLcjtyDDP4aLxd46RTZq1nQxe7+k5Q== + +typescript@^5.3.3: + version "5.3.3" + resolved "https://registry.npmmirror.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37" + integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw== + vite@^4.4.9: version "4.4.9" resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d"