From ce80a03f6d5de592ced0a002ec201cf5860f6318 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 18 Jan 2024 21:08:43 +0800 Subject: [PATCH 01/18] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9F=BA=E5=87=86?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/bench/go-queryx/db/errors.go | 7 + .../migrations/20240118175745_auto.down.sql | 1 + .../db/migrations/20240118175745_auto.up.sql | 1 + internal/bench/go-queryx/db/model.go | 91 ++++++ internal/bench/go-queryx/db/model_query.go | 297 ++++++++++++++++++ internal/bench/go-queryx/db/queryx.go | 120 +++++++ internal/bench/go-queryx/db/queryx/adapter.go | 48 +++ .../bench/go-queryx/db/queryx/adapter_test.go | 15 + internal/bench/go-queryx/db/queryx/bigint.go | 75 +++++ .../go-queryx/db/queryx/bigint_column.go | 93 ++++++ .../bench/go-queryx/db/queryx/bigint_test.go | 40 +++ internal/bench/go-queryx/db/queryx/bind.go | 167 ++++++++++ internal/bench/go-queryx/db/queryx/boolean.go | 77 +++++ .../go-queryx/db/queryx/boolean_column.go | 39 +++ .../bench/go-queryx/db/queryx/boolean_test.go | 40 +++ internal/bench/go-queryx/db/queryx/clause.go | 57 ++++ .../bench/go-queryx/db/queryx/clause_test.go | 37 +++ internal/bench/go-queryx/db/queryx/config.go | 26 ++ .../bench/go-queryx/db/queryx/date_test.go | 40 +++ .../go-queryx/db/queryx/datetime_test.go | 40 +++ internal/bench/go-queryx/db/queryx/db.go | 110 +++++++ internal/bench/go-queryx/db/queryx/delete.go | 36 +++ .../bench/go-queryx/db/queryx/delete_test.go | 15 + internal/bench/go-queryx/db/queryx/env.go | 7 + .../bench/go-queryx/db/queryx/float_test.go | 40 +++ internal/bench/go-queryx/db/queryx/insert.go | 82 +++++ .../bench/go-queryx/db/queryx/insert_test.go | 33 ++ internal/bench/go-queryx/db/queryx/integer.go | 78 +++++ .../go-queryx/db/queryx/integer_column.go | 88 ++++++ .../bench/go-queryx/db/queryx/integer_test.go | 40 +++ .../bench/go-queryx/db/queryx/json_test.go | 42 +++ internal/bench/go-queryx/db/queryx/logger.go | 15 + .../bench/go-queryx/db/queryx/model_change.go | 143 +++++++++ internal/bench/go-queryx/db/queryx/scan.go | 135 ++++++++ internal/bench/go-queryx/db/queryx/schema.go | 52 +++ internal/bench/go-queryx/db/queryx/select.go | 142 +++++++++ .../bench/go-queryx/db/queryx/select_test.go | 35 +++ internal/bench/go-queryx/db/queryx/string.go | 72 +++++ .../go-queryx/db/queryx/string_column.go | 93 ++++++ .../bench/go-queryx/db/queryx/string_test.go | 40 +++ internal/bench/go-queryx/db/queryx/table.go | 13 + .../bench/go-queryx/db/queryx/time_test.go | 40 +++ internal/bench/go-queryx/db/queryx/update.go | 67 ++++ .../bench/go-queryx/db/queryx/update_test.go | 14 + .../bench/go-queryx/db/queryx/uuid_test.go | 40 +++ internal/bench/go-queryx/helper/constants.go | 8 + internal/bench/go-queryx/helper/error.go | 23 ++ internal/bench/go-queryx/helper/misc.go | 14 + internal/bench/go-queryx/helper/sql.go | 64 ++++ internal/bench/go-queryx/helper/suite.go | 89 ++++++ internal/bench/go-queryx/models.go | 34 ++ internal/bench/go-queryx/queryx.go | 140 +++++++++ internal/bench/go-queryx/schema.hcl | 41 +++ internal/bench/main.go | 167 ++++++++++ 54 files changed, 3363 insertions(+) create mode 100644 internal/bench/go-queryx/db/errors.go create mode 100644 internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql create mode 100644 internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql create mode 100644 internal/bench/go-queryx/db/model.go create mode 100644 internal/bench/go-queryx/db/model_query.go create mode 100644 internal/bench/go-queryx/db/queryx.go create mode 100644 internal/bench/go-queryx/db/queryx/adapter.go create mode 100644 internal/bench/go-queryx/db/queryx/adapter_test.go create mode 100644 internal/bench/go-queryx/db/queryx/bigint.go create mode 100644 internal/bench/go-queryx/db/queryx/bigint_column.go create mode 100644 internal/bench/go-queryx/db/queryx/bigint_test.go create mode 100644 internal/bench/go-queryx/db/queryx/bind.go create mode 100644 internal/bench/go-queryx/db/queryx/boolean.go create mode 100644 internal/bench/go-queryx/db/queryx/boolean_column.go create mode 100644 internal/bench/go-queryx/db/queryx/boolean_test.go create mode 100644 internal/bench/go-queryx/db/queryx/clause.go create mode 100644 internal/bench/go-queryx/db/queryx/clause_test.go create mode 100644 internal/bench/go-queryx/db/queryx/config.go create mode 100644 internal/bench/go-queryx/db/queryx/date_test.go create mode 100644 internal/bench/go-queryx/db/queryx/datetime_test.go create mode 100644 internal/bench/go-queryx/db/queryx/db.go create mode 100644 internal/bench/go-queryx/db/queryx/delete.go create mode 100644 internal/bench/go-queryx/db/queryx/delete_test.go create mode 100644 internal/bench/go-queryx/db/queryx/env.go create mode 100644 internal/bench/go-queryx/db/queryx/float_test.go create mode 100644 internal/bench/go-queryx/db/queryx/insert.go create mode 100644 internal/bench/go-queryx/db/queryx/insert_test.go create mode 100644 internal/bench/go-queryx/db/queryx/integer.go create mode 100644 internal/bench/go-queryx/db/queryx/integer_column.go create mode 100644 internal/bench/go-queryx/db/queryx/integer_test.go create mode 100644 internal/bench/go-queryx/db/queryx/json_test.go create mode 100644 internal/bench/go-queryx/db/queryx/logger.go create mode 100644 internal/bench/go-queryx/db/queryx/model_change.go create mode 100644 internal/bench/go-queryx/db/queryx/scan.go create mode 100644 internal/bench/go-queryx/db/queryx/schema.go create mode 100644 internal/bench/go-queryx/db/queryx/select.go create mode 100644 internal/bench/go-queryx/db/queryx/select_test.go create mode 100644 internal/bench/go-queryx/db/queryx/string.go create mode 100644 internal/bench/go-queryx/db/queryx/string_column.go create mode 100644 internal/bench/go-queryx/db/queryx/string_test.go create mode 100644 internal/bench/go-queryx/db/queryx/table.go create mode 100644 internal/bench/go-queryx/db/queryx/time_test.go create mode 100644 internal/bench/go-queryx/db/queryx/update.go create mode 100644 internal/bench/go-queryx/db/queryx/update_test.go create mode 100644 internal/bench/go-queryx/db/queryx/uuid_test.go create mode 100644 internal/bench/go-queryx/helper/constants.go create mode 100644 internal/bench/go-queryx/helper/error.go create mode 100644 internal/bench/go-queryx/helper/misc.go create mode 100644 internal/bench/go-queryx/helper/sql.go create mode 100644 internal/bench/go-queryx/helper/suite.go create mode 100644 internal/bench/go-queryx/models.go create mode 100644 internal/bench/go-queryx/queryx.go create mode 100644 internal/bench/go-queryx/schema.hcl create mode 100644 internal/bench/main.go diff --git a/internal/bench/go-queryx/db/errors.go b/internal/bench/go-queryx/db/errors.go new file mode 100644 index 00000000..a74d06ff --- /dev/null +++ b/internal/bench/go-queryx/db/errors.go @@ -0,0 +1,7 @@ +// Code generated by queryx, DO NOT EDIT. + +package db + +import "errors" + +var ErrInsertAllEmptyChanges = errors.New("queryx: insert all with empty changes") diff --git a/internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql b/internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql new file mode 100644 index 00000000..5100e91c --- /dev/null +++ b/internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql @@ -0,0 +1 @@ +DROP TABLE "public"."models" \ No newline at end of file diff --git a/internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql b/internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql new file mode 100644 index 00000000..28d15e4f --- /dev/null +++ b/internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql @@ -0,0 +1 @@ +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")); \ No newline at end of file diff --git a/internal/bench/go-queryx/db/model.go b/internal/bench/go-queryx/db/model.go new file mode 100644 index 00000000..26f7f571 --- /dev/null +++ b/internal/bench/go-queryx/db/model.go @@ -0,0 +1,91 @@ +// Code generated by queryx, DO NOT EDIT. + +package db + +import ( + "fmt" + "strings" + + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" +) + +type Model struct { + ID int64 `json:"id" db:"id"` + Name queryx.String `json:"name" db:"name"` + Title queryx.String `json:"title" db:"title"` + Fax queryx.String `json:"fax" db:"fax"` + Web queryx.String `json:"web" db:"web"` + Age queryx.BigInt `json:"age" db:"age"` + Righ queryx.Boolean `json:"righ" db:"righ"` + Counter queryx.Integer `json:"counter" db:"counter"` + + schema *queryx.Schema + queries Queries +} + +// String implements the stringer interface. +func (m *Model) String() string { + var sb strings.Builder + sb.WriteString("(Model ") + sb.WriteString(fmt.Sprintf("id: %v", m.ID)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("name: %s", m.Name)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("title: %s", m.Title)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("fax: %s", m.Fax)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("web: %s", m.Web)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("age: %s", m.Age)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("righ: %s", m.Righ)) + sb.WriteString(", ") + sb.WriteString(fmt.Sprintf("counter: %s", m.Counter)) + sb.WriteString(")") + return sb.String() +} + +func (m *Model) applyChange(change *queryx.ModelChange) error { + if change == nil { + return nil + } + if change.ID.Set { + m.ID = change.ID.Val + } + if change.Name.Set { + m.Name = change.Name + } + if change.Title.Set { + m.Title = change.Title + } + if change.Fax.Set { + m.Fax = change.Fax + } + if change.Web.Set { + m.Web = change.Web + } + if change.Age.Set { + m.Age = change.Age + } + if change.Righ.Set { + m.Righ = change.Righ + } + if change.Counter.Set { + m.Counter = change.Counter + } + return nil +} +func (m *Model) Update(change *queryx.ModelChange) error { + _, err := m.queries.QueryModel().Where(m.schema.And(m.schema.ModelID.EQ(m.ID))).UpdateAll(change) + if err != nil { + return err + } + + return m.applyChange(change) +} + +func (m *Model) Delete() error { + _, err := m.queries.QueryModel().Delete(m.ID) + return err +} diff --git a/internal/bench/go-queryx/db/model_query.go b/internal/bench/go-queryx/db/model_query.go new file mode 100644 index 00000000..baee73d4 --- /dev/null +++ b/internal/bench/go-queryx/db/model_query.go @@ -0,0 +1,297 @@ +// Code generated by queryx, DO NOT EDIT. + +package db + +import ( + "database/sql" + "errors" + "fmt" + + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" +) + +type ModelQuery struct { + adapter *queryx.Adapter + schema *queryx.Schema + queries Queries + selectStatement *queryx.SelectStatement + preload map[string]bool + err error +} + +func NewModelQuery(adapter *queryx.Adapter, schema *queryx.Schema, queries Queries) *ModelQuery { + s := queryx.NewSelect().Select("models.*").From("models") + return &ModelQuery{ + adapter: adapter, + schema: schema, + queries: queries, + selectStatement: s, + preload: make(map[string]bool), + } +} + +func (q *ModelQuery) Create(change *queryx.ModelChange) (*Model, error) { + if q.err != nil { + return nil, q.err + } + + record := &Model{ + schema: q.schema, + queries: q.queries, + } + columns, values := change.Changes() + query, args := queryx.NewInsert(). + Into("models"). + Columns(columns...). + Values(values...). + Returning("*").ToSQL() + err := q.adapter.QueryOne(query, args...).Scan(record) + if err != nil { + return nil, err + } + + return record, nil +} + +func (q *ModelQuery) InsertAll(changes []*queryx.ModelChange) (int64, error) { + if q.err != nil { + return 0, q.err + } + + if len(changes) == 0 { + return 0, ErrInsertAllEmptyChanges + } + + s := queryx.NewInsert().Into("models") + for i, change := range changes { + columns, values := change.Changes() + if i == 0 { + s.Columns(columns...) + } + s.Values(values...) + } + + query, args := s.ToSQL() + return q.adapter.Exec(query, args...) +} + +func (q *ModelQuery) Delete(id int64) (int64, error) { + query, args := queryx.NewDelete().From("models").Where(q.schema.ModelID.EQ(id)).ToSQL() + result, err := q.adapter.Exec(query, args...) + if err != nil { + return 0, err + } + return result, err +} + +func (q *ModelQuery) Find(id int64) (*Model, error) { + res, err := q.Where(q.schema.ModelID.EQ(id)).First() + if err != nil { + return nil, err + } + if res == nil { + return nil, sql.ErrNoRows + } + res.schema = q.schema + res.queries = q.queries + return res, err +} + +func (q *ModelQuery) FindBy(where *queryx.Clause) (*Model, error) { + return q.Where(where).First() +} + +func (q *ModelQuery) FindBySQL(query string, args ...interface{}) ([]*Model, error) { + var modelList []Model + models := make([]*Model, 0) + err := q.adapter.Query(query, args...).Scan(&modelList) + if err != nil { + return nil, err + } + for i := 0; i < len(modelList); i++ { + models = append(models, &modelList[i]) + } + return models, nil +} + +func (q *ModelQuery) Where(clauses ...*queryx.Clause) *ModelQuery { + q.selectStatement.Where(clauses...) + return q +} + +func (q *ModelQuery) Select(selection ...string) *ModelQuery { + q.selectStatement.Select(selection...) + return q +} + +func (q *ModelQuery) Limit(limit int) *ModelQuery { + q.selectStatement.Limit(limit) + return q +} + +func (q *ModelQuery) Offset(offset int) *ModelQuery { + q.selectStatement.Offset(offset) + return q +} + +func (q *ModelQuery) Group(group string) *ModelQuery { + q.selectStatement.GroupBy(group) + return q +} + +func (q *ModelQuery) Having(having string) *ModelQuery { + q.selectStatement.Having(having) + return q +} + +func (q *ModelQuery) Joins(joins string) *ModelQuery { + q.selectStatement.Join(joins) + return q +} + +func (q *ModelQuery) Order(order ...string) *ModelQuery { + q.selectStatement.Order(order...) + return q +} + +func (q *ModelQuery) All() ([]*Model, error) { + if q.err != nil { + return nil, q.err + } + var rows []Model + models := make([]*Model, 0) + query, args := q.selectStatement.ToSQL() + err := q.adapter.Query(query, args...).Scan(&rows) + if err != nil { + return nil, err + } + + if len(rows) == 0 { + return models, nil + } + + for i := range rows { + rows[i].schema = q.schema + rows[i].queries = q.queries + models = append(models, &rows[i]) + } + + return models, nil +} + +func (q *ModelQuery) First() (*Model, error) { + q.Limit(1) + results, err := q.All() + if err != nil { + return nil, err + } + if len(results) > 0 { + return results[0], nil + } + + return nil, nil +} + +func (q *ModelQuery) Count() (int64, error) { + var res struct { + Count int64 `db:"count"` + } + q.selectStatement.Select("count(*)") + query, args := q.selectStatement.ToSQL() + if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { + return 0, err + } + + return res.Count, nil +} + +func (q *ModelQuery) Avg(v string) (float64, error) { + var res struct { + Avg sql.NullFloat64 `db:"avg"` + } + q.selectStatement.Select(fmt.Sprintf("avg(%+v)", v)) + query, args := q.selectStatement.ToSQL() + if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { + return 0, err + } + + return res.Avg.Float64, nil +} + +func (q *ModelQuery) Sum(v string) (float64, error) { + var res struct { + Sum sql.NullFloat64 `db:"sum"` + } + q.selectStatement.Select(fmt.Sprintf("sum(%+v)", v)) + query, args := q.selectStatement.ToSQL() + if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { + return 0, err + } + + return res.Sum.Float64, nil +} + +func (q *ModelQuery) Max(v string) (float64, error) { + var res struct { + Max sql.NullFloat64 `db:"max"` + } + q.selectStatement.Select(fmt.Sprintf("max(%+v)", v)) + query, args := q.selectStatement.ToSQL() + if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { + return 0, err + } + + return res.Max.Float64, nil +} + +func (q *ModelQuery) Min(v string) (float64, error) { + var res struct { + Min sql.NullFloat64 `db:"min"` + } + q.selectStatement.Select(fmt.Sprintf("min(%+v)", v)) + query, args := q.selectStatement.ToSQL() + if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { + return 0, err + } + + return res.Min.Float64, nil +} + +func (q *ModelQuery) Exists() (bool, error) { + q.selectStatement.Select("1 AS one").Limit(1) + // select 1 as one from users limit 1 + query, args := q.selectStatement.ToSQL() + var res struct { + One int64 `db:"one"` + } + if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { + if errors.Is(err, sql.ErrNoRows) { + return false, nil + } + return false, err + } + + return res.One == 1, nil +} + +func (q *ModelQuery) UpdateAll(change *queryx.ModelChange) (int64, error) { + if q.err != nil { + return 0, q.err + } + columns, values := change.Changes() + query, args := q.selectStatement.Update().Columns(columns...).Values(values...).ToSQL() + result, err := q.adapter.Exec(query, args...) + if err != nil { + return 0, err + } + return result, err +} + +func (q *ModelQuery) DeleteAll() (int64, error) { + query, args := q.selectStatement.Delete().ToSQL() + result, err := q.adapter.Exec(query, args...) + if err != nil { + return 0, err + } + return result, err +} diff --git a/internal/bench/go-queryx/db/queryx.go b/internal/bench/go-queryx/db/queryx.go new file mode 100644 index 00000000..80260fde --- /dev/null +++ b/internal/bench/go-queryx/db/queryx.go @@ -0,0 +1,120 @@ +// Code generated by queryx, DO NOT EDIT. + +package db + +import ( + "context" + "database/sql" + "fmt" + "log" + "os" + + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" +) + +type Queries interface { + QueryModel() *ModelQuery +} + +type QXClient struct { + db *sql.DB + config *queryx.Config + logger queryx.Logger + *queryx.Adapter + *queryx.Schema +} + +func NewClient() (*QXClient, error) { + env := os.Getenv("QUERYX_ENV") + if env == "" { + env = "development" + } + return NewClientWithEnv(env) +} + +func NewClientWithEnv(env string) (*QXClient, error) { + config := queryx.NewConfig(env) + if config == nil { + return nil, fmt.Errorf("client config is missing for %s", env) + } + db, err := sql.Open("postgres", config.URL) + if err != nil { + return nil, err + } + + client := &QXClient{ + db: db, + config: config, + Adapter: queryx.NewAdapter(db), + Schema: queryx.NewSchema(), + } + client.setDefaultLogger() + + return client, nil +} + +func (c *QXClient) SetLogger(logger queryx.Logger) { + c.logger = logger +} + +func (c *QXClient) setDefaultLogger() { + c.logger = log.New(os.Stderr, "sql ", log.Llongfile|log.LstdFlags) +} + +func (c *QXClient) QueryModel() *ModelQuery { + return NewModelQuery(c.Adapter, c.Schema, c) +} + +func (c *QXClient) Transaction(f func(t *Tx) error) error { + tx, err := c.Tx() + if err != nil { + return err + } + defer tx.Rollback() + if err = f(tx); err != nil { + return err + } + return tx.Commit() +} + +func (c *QXClient) Raw(fragment string, args ...interface{}) *queryx.Clause { + return queryx.NewClause(fragment, args) +} + +type Tx struct { + *queryx.Schema + *queryx.Adapter + tx *sql.Tx + client *QXClient +} + +func (c *QXClient) Tx() (*Tx, error) { + ctx := context.Background() + tx, err := c.db.BeginTx(ctx, nil) + if err != nil { + return nil, err + } + + return &Tx{ + tx: tx, + Schema: c.Schema, + Adapter: queryx.NewAdapter(tx), + client: c, + }, nil +} + +func (tx *Tx) Commit() error { + return tx.tx.Commit() +} + +func (tx *Tx) Rollback() error { + return tx.tx.Rollback() +} + +func (tx *Tx) QueryModel() *ModelQuery { + return NewModelQuery(tx.Adapter, tx.Schema, tx) +} + +func (tx *Tx) Raw(fragment string, args ...interface{}) *queryx.Clause { + return queryx.NewClause(fragment, args) +} diff --git a/internal/bench/go-queryx/db/queryx/adapter.go b/internal/bench/go-queryx/db/queryx/adapter.go new file mode 100644 index 00000000..55eac2a7 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/adapter.go @@ -0,0 +1,48 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "regexp" + "strconv" + "strings" + + _ "github.com/lib/pq" +) + +func (a *Adapter) Exec(query string, args ...interface{}) (int64, error) { + matched1, err := regexp.MatchString(`.* IN (.*?)`, query) + if err != nil { + return 0, err + } + matched2, err := regexp.MatchString(`.* in (.*?)`, query) + if err != nil { + return 0, err + } + if matched1 || matched2 { + query, args, err = In(query, args...) + if err != nil { + return 0, err + } + } + query, args = rebind(query, args) + result, err := a.db.Exec(query, args...) + if err != nil { + return 0, err + } + return result.RowsAffected() +} + +func rebind(query string, args []interface{}) (string, []interface{}) { + rqb := make([]byte, 0, len(query)+10) + var i, j int + for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") { + rqb = append(rqb, query[:i]...) + rqb = append(rqb, '$') + j++ + rqb = strconv.AppendInt(rqb, int64(j), 10) + query = query[i+1:] + } + query = string(append(rqb, query...)) + return query, args +} diff --git a/internal/bench/go-queryx/db/queryx/adapter_test.go b/internal/bench/go-queryx/db/queryx/adapter_test.go new file mode 100644 index 00000000..07fea4be --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/adapter_test.go @@ -0,0 +1,15 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestRebind(t *testing.T) { + sql, args := rebind("a ? b ?", []interface{}{1, 2}) + require.Equal(t, "a $1 b $2", sql) + require.Equal(t, []interface{}{1, 2}, args) +} diff --git a/internal/bench/go-queryx/db/queryx/bigint.go b/internal/bench/go-queryx/db/queryx/bigint.go new file mode 100644 index 00000000..1d58235d --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/bigint.go @@ -0,0 +1,75 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "strconv" +) + +type BigInt struct { + Val int64 + Valid bool + Set bool +} + +func NewBigInt(v int64) BigInt { + return BigInt{Val: v, Valid: true, Set: true} +} + +func NewNullableBigInt(v *int64) BigInt { + if v != nil { + return NewBigInt(*v) + } + return BigInt{Set: true} +} + +// Scan implements the Scanner interface. +func (b *BigInt) Scan(value interface{}) error { + n := sql.NullInt64{} + err := n.Scan(value) + if err != nil { + return err + } + b.Val, b.Valid = n.Int64, n.Valid + return nil +} + +// Value implements the driver Valuer interface. +func (b BigInt) Value() (driver.Value, error) { + if !b.Valid { + return nil, nil + } + return b.Val, nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (b BigInt) MarshalJSON() ([]byte, error) { + if !b.Valid { + return json.Marshal(nil) + } + return json.Marshal(b.Val) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (b *BigInt) UnmarshalJSON(data []byte) error { + b.Set = true + if string(data) == "null" { + return nil + } + b.Valid = true + if err := json.Unmarshal(data, &b.Val); err != nil { + return err + } + return nil +} + +// String implements the stringer interface. +func (b BigInt) String() string { + if !b.Valid { + return "null" + } + return strconv.FormatInt(b.Val, 10) +} diff --git a/internal/bench/go-queryx/db/queryx/bigint_column.go b/internal/bench/go-queryx/db/queryx/bigint_column.go new file mode 100644 index 00000000..8682bd2a --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/bigint_column.go @@ -0,0 +1,93 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import "fmt" + +type BigIntColumn struct { + Name string + Table *Table +} + +func (t *Table) NewBigIntColumn(name string) *BigIntColumn { + return &BigIntColumn{ + Table: t, + Name: name, + } +} + +func (c *BigIntColumn) EQ(v int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) NE(v int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) LT(v int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s < ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) GT(v int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s > ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) LE(v int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s <= ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) GE(v int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s >= ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) In(v []int64) *Clause { + if len(v) == 0 { + return &Clause{ + fragment: "1=0", + } + } + return &Clause{ + fragment: fmt.Sprintf("%s.%s IN (?)", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BigIntColumn) InRange(start int64, end int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s >= ? and %s.%s< ?", c.Table.Name, c.Name, c.Table.Name, c.Name), + args: []interface{}{start, end}, + } +} + +func (c *BigIntColumn) Between(start int64, end int64) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s >= ? and %s.%s<= ?", c.Table.Name, c.Name, c.Table.Name, c.Name), + args: []interface{}{start, end}, + } +} + +func (c *BigIntColumn) Asc() string { + return fmt.Sprintf("%s.%s ASC", c.Table.Name, c.Name) +} + +func (c *BigIntColumn) Desc() string { + return fmt.Sprintf("%s.%s DESC", c.Table.Name, c.Name) +} diff --git a/internal/bench/go-queryx/db/queryx/bigint_test.go b/internal/bench/go-queryx/db/queryx/bigint_test.go new file mode 100644 index 00000000..1500f356 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/bigint_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewBigInt(t *testing.T) { + b1 := NewBigInt(2) + require.Equal(t, int64(2), b1.Val) + require.True(t, b1.Valid) + + b2 := NewNullableBigInt(nil) + require.False(t, b2.Valid) +} + +func TestBigIntJSON(t *testing.T) { + type Foo struct { + X BigInt `json:"x"` + Y BigInt `json:"y"` + } + x := NewBigInt(2) + y := NewNullableBigInt(nil) + s := `{"x":2,"y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/bind.go b/internal/bench/go-queryx/db/queryx/bind.go new file mode 100644 index 00000000..d248e8db --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/bind.go @@ -0,0 +1,167 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql/driver" + "fmt" + "reflect" + "strings" +) + +// In expands slice values in args, returning the modified query string +// and a new arg list that can be executed by a database. The `query` should +// use the `?` bindVar. The return value uses the `?` bindVar. +func In(query string, args ...interface{}) (string, []interface{}, error) { + // argMeta stores reflect.Value and length for slices and + // the value itself for non-slice arguments + type argMeta struct { + v reflect.Value + i interface{} + length int + } + + var flatArgsCount int + var anySlices bool + + var stackMeta [32]argMeta + + var meta []argMeta + if len(args) <= len(stackMeta) { + meta = stackMeta[:len(args)] + } else { + meta = make([]argMeta, len(args)) + } + + for i, arg := range args { + if a, ok := arg.(driver.Valuer); ok { + var err error + arg, err = a.Value() + if err != nil { + return "", nil, err + } + } + + if v, ok := asSliceForIn(arg); ok { + meta[i].length = v.Len() + meta[i].v = v + + anySlices = true + flatArgsCount += meta[i].length + + if meta[i].length == 0 { + return "", nil, fmt.Errorf("empty slice passed to 'in' query") + } + } else { + meta[i].i = arg + flatArgsCount++ + } + } + + // don't do any parsing if there aren't any slices; note that this means + // some errors that we might have caught below will not be returned. + if !anySlices { + return query, args, nil + } + + newArgs := make([]interface{}, 0, flatArgsCount) + + var buf strings.Builder + buf.Grow(len(query) + len(", ?")*flatArgsCount) + + var arg, offset int + + for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') { + if arg >= len(meta) { + // if an argument wasn't passed, lets return an error; this is + // not actually how database/sql Exec/Query works, but since we are + // creating an argument list programmatically, we want to be able + // to catch these programmer errors earlier. + return "", nil, fmt.Errorf("number of bindVars exceeds arguments") + } + + argMeta := meta[arg] + arg++ + + // not a slice, continue. + // our questionmark will either be written before the next expansion + // of a slice or after the loop when writing the rest of the query + if argMeta.length == 0 { + offset = offset + i + 1 + newArgs = append(newArgs, argMeta.i) + continue + } + + // write everything up to and including our ? character + buf.WriteString(query[:offset+i+1]) + + for si := 1; si < argMeta.length; si++ { + buf.WriteString(", ?") + } + + newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length) + + // slice the query and reset the offset. this avoids some bookkeeping for + // the write after the loop + query = query[offset+i+1:] + offset = 0 + } + + buf.WriteString(query) + + if arg < len(meta) { + return "", nil, fmt.Errorf("number of bindVars less than number arguments") + } + + return buf.String(), newArgs, nil +} +func asSliceForIn(i interface{}) (v reflect.Value, ok bool) { + if i == nil { + return reflect.Value{}, false + } + + v = reflect.ValueOf(i) + t := Deref(v.Type()) + + // Only expand slices + if t.Kind() != reflect.Slice { + return reflect.Value{}, false + } + + // []byte is a driver.Value type so it should not be expanded + if t == reflect.TypeOf([]byte{}) { + return reflect.Value{}, false + + } + + return v, true +} + +// Deref is Indirect for reflect.Types +func Deref(t reflect.Type) reflect.Type { + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return t +} + +func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} { + switch val := v.Interface().(type) { + case []interface{}: + args = append(args, val...) + case []int: + for i := range val { + args = append(args, val[i]) + } + case []string: + for i := range val { + args = append(args, val[i]) + } + default: + for si := 0; si < vlen; si++ { + args = append(args, v.Index(si).Interface()) + } + } + + return args +} diff --git a/internal/bench/go-queryx/db/queryx/boolean.go b/internal/bench/go-queryx/db/queryx/boolean.go new file mode 100644 index 00000000..388d2e95 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/boolean.go @@ -0,0 +1,77 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" +) + +type Boolean struct { + Val bool + Valid bool + Set bool +} + +func NewBoolean(v bool) Boolean { + return Boolean{Val: v, Valid: true, Set: true} +} + +func NewNullableBoolean(v *bool) Boolean { + if v != nil { + return NewBoolean(*v) + } + return Boolean{Set: true} +} + +// Scan implements the Scanner interface. +func (b *Boolean) Scan(value interface{}) error { + n := sql.NullBool{} + err := n.Scan(value) + if err != nil { + return err + } + b.Val, b.Valid = n.Bool, n.Valid + return nil +} + +// Value implements the driver Valuer interface. +func (b Boolean) Value() (driver.Value, error) { + if !b.Valid { + return nil, nil + } + return b.Val, nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (b Boolean) MarshalJSON() ([]byte, error) { + if !b.Valid { + return json.Marshal(nil) + } + return json.Marshal(b.Val) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (b *Boolean) UnmarshalJSON(data []byte) error { + b.Set = true + if string(data) == "null" { + return nil + } + b.Valid = true + if err := json.Unmarshal(data, &b.Val); err != nil { + return err + } + return nil +} + +// String implements the stringer interface. +func (b Boolean) String() string { + if !b.Valid { + return "null" + } + if b.Val { + return "true" + } + return "false" +} diff --git a/internal/bench/go-queryx/db/queryx/boolean_column.go b/internal/bench/go-queryx/db/queryx/boolean_column.go new file mode 100644 index 00000000..72764e3e --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/boolean_column.go @@ -0,0 +1,39 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import "fmt" + +type BooleanColumn struct { + Name string + Table *Table +} + +func (t *Table) NewBooleanColumn(name string) *BooleanColumn { + return &BooleanColumn{ + Table: t, + Name: name, + } +} + +func (c *BooleanColumn) EQ(v bool) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *BooleanColumn) NE(v bool) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (b *BooleanColumn) Asc() string { + return fmt.Sprintf("%s.%s ASC", b.Table.Name, b.Name) +} + +func (b *BooleanColumn) Desc() string { + return fmt.Sprintf("%s.%s DESC", b.Table.Name, b.Name) +} diff --git a/internal/bench/go-queryx/db/queryx/boolean_test.go b/internal/bench/go-queryx/db/queryx/boolean_test.go new file mode 100644 index 00000000..31a8fb62 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/boolean_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewBoolean(t *testing.T) { + b1 := NewBoolean(true) + require.Equal(t, true, b1.Val) + require.True(t, b1.Valid) + + b2 := NewNullableBoolean(nil) + require.False(t, b2.Valid) +} + +func TestBooleanJSON(t *testing.T) { + type Foo struct { + X Boolean `json:"x"` + Y Boolean `json:"y"` + } + x := NewBoolean(true) + y := NewNullableBoolean(nil) + s := `{"x":true,"y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/clause.go b/internal/bench/go-queryx/db/queryx/clause.go new file mode 100644 index 00000000..a5b03575 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/clause.go @@ -0,0 +1,57 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "fmt" + "strings" +) + +type Clause struct { + fragment string + args []interface{} + err error +} + +func NewClause(fragment string, args []interface{}) *Clause { + return &Clause{ + fragment: fragment, + args: args, + } +} + +func (c *Clause) Err() error { + return c.err +} + +func (c *Clause) And(clauses ...*Clause) *Clause { + if len(clauses) == 0 { + return c + } + + var fragments []string + var args []interface{} + clauses = append([]*Clause{c}, clauses...) + for _, clause := range clauses { + fragments = append(fragments, fmt.Sprintf("(%s)", clause.fragment)) + args = append(args, clause.args...) + } + + return NewClause(strings.Join(fragments, " AND "), args) +} + +func (c *Clause) Or(clauses ...*Clause) *Clause { + if len(clauses) == 0 { + return c + } + + var fragments []string + var args []interface{} + clauses = append([]*Clause{c}, clauses...) + for _, clause := range clauses { + fragments = append(fragments, fmt.Sprintf("(%s)", clause.fragment)) + args = append(args, clause.args...) + } + + return NewClause(strings.Join(fragments, " OR "), args) +} diff --git a/internal/bench/go-queryx/db/queryx/clause_test.go b/internal/bench/go-queryx/db/queryx/clause_test.go new file mode 100644 index 00000000..b7d548cb --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/clause_test.go @@ -0,0 +1,37 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestClauseAddOr(t *testing.T) { + c1 := &Clause{ + fragment: "a = ?", + args: []interface{}{1}, + } + c2 := &Clause{ + fragment: "b = ?", + args: []interface{}{"x"}, + } + + c3 := c1.And(c2) + require.Equal(t, "(a = ?) AND (b = ?)", c3.fragment) + require.Equal(t, []interface{}{1, "x"}, c3.args) + + c4 := c1.Or(c2) + require.Equal(t, "(a = ?) OR (b = ?)", c4.fragment) + require.Equal(t, []interface{}{1, "x"}, c4.args) + + c5 := c1.And(c1.Or(c2)) + require.Equal(t, "(a = ?) AND ((a = ?) OR (b = ?))", c5.fragment) + require.Equal(t, []interface{}{1, 1, "x"}, c5.args) + + require.Equal(t, "a = ?", c1.fragment) + require.Equal(t, []interface{}{1}, c1.args) + require.Equal(t, "b = ?", c2.fragment) + require.Equal(t, []interface{}{"x"}, c2.args) +} diff --git a/internal/bench/go-queryx/db/queryx/config.go b/internal/bench/go-queryx/db/queryx/config.go new file mode 100644 index 00000000..a430ec80 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/config.go @@ -0,0 +1,26 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import () + +type Config struct { + URL string +} + +func NewConfig(env string) *Config { + switch env { + case "development": + return &Config{ + URL: fixURL("postgresql://postgres:postgres@localhost:5432/test?sslmode=disable"), + } + case "test": + return &Config{ + URL: fixURL(getenv("DATABASE_URL")), + } + } + return nil +} +func fixURL(rawURL string) string { + return rawURL +} diff --git a/internal/bench/go-queryx/db/queryx/date_test.go b/internal/bench/go-queryx/db/queryx/date_test.go new file mode 100644 index 00000000..b45d5cfc --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/date_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewDate(t *testing.T) { + d1 := NewDate("2012-11-10") + require.Equal(t, "2012-11-10", d1.Val.Format("2006-01-02")) + require.True(t, d1.Valid) + + d2 := NewNullableDate(nil) + require.False(t, d2.Valid) +} + +func TestDateJSON(t *testing.T) { + type Foo struct { + X Date `json:"x"` + Y Date `json:"y"` + } + x := NewDate("2012-11-10") + y := NewNullableDate(nil) + s := `{"x":"2012-11-10","y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/datetime_test.go b/internal/bench/go-queryx/db/queryx/datetime_test.go new file mode 100644 index 00000000..824edf32 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/datetime_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewDatetime(t *testing.T) { + d1 := NewDatetime("2012-12-12 11:10:09") + require.Equal(t, "2012-12-12 11:10:09", d1.Val.Format("2006-01-02 15:04:05")) + require.True(t, d1.Valid) + + d2 := NewNullableDatetime(nil) + require.False(t, d2.Valid) +} + +func TestDatetimeJSON(t *testing.T) { + type Foo struct { + X Datetime `json:"x"` + Y Datetime `json:"y"` + } + x := NewDatetime("2012-12-12 11:10:09") + y := NewNullableDatetime(nil) + s := `{"x":"2012-12-12T03:10:09Z","y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/db.go b/internal/bench/go-queryx/db/queryx/db.go new file mode 100644 index 00000000..f37b7902 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/db.go @@ -0,0 +1,110 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql" + "regexp" +) + +type DB interface { + Exec(query string, args ...interface{}) (sql.Result, error) + Query(query string, args ...interface{}) (*sql.Rows, error) +} + +type Adapter struct { + db DB +} + +func NewAdapter(db DB) *Adapter { + return &Adapter{db: db} +} + +func (a *Adapter) Query(query string, args ...interface{}) *Rows { + return &Rows{ + adapter: a, + query: query, + args: args, + } +} + +type Rows struct { + adapter *Adapter + query string + args []interface{} + err error +} + +func (r *Rows) Scan(v interface{}) error { + if r.err != nil { + return r.err + } + var err error + query, args := r.query, r.args + matched1, err := regexp.MatchString(`.* IN (.*?)`, query) + if err != nil { + return err + } + matched2, err := regexp.MatchString(`.* in (.*?)`, query) + if err != nil { + return err + } + if matched1 || matched2 { + query, args, err = In(query, args...) + if err != nil { + return err + } + } + query, args = rebind(query, args) + rows, err := r.adapter.db.Query(query, args...) + if err != nil { + return err + } + err = ScanSlice(rows, v) + if err != nil { + return err + } + return err +} + +type Row struct { + adapter *Adapter + query string + args []interface{} +} + +func (r *Row) Scan(v interface{}) error { + query, args := r.query, r.args + matched1, err := regexp.MatchString(`.* IN (.*?)`, query) + if err != nil { + return err + } + matched2, err := regexp.MatchString(`.* in (.*?)`, query) + if err != nil { + return err + } + if matched1 || matched2 { + query, args, err = In(query, args...) + if err != nil { + return err + } + } + query, args = rebind(query, args) + rows, err := r.adapter.db.Query(query, args...) + if err != nil { + return err + } + err = ScanOne(rows, v) + if err != nil { + return err + } + return err +} + +func (a *Adapter) QueryOne(query string, args ...interface{}) *Row { + return &Row{ + adapter: a, + query: query, + args: args, + } +} diff --git a/internal/bench/go-queryx/db/queryx/delete.go b/internal/bench/go-queryx/db/queryx/delete.go new file mode 100644 index 00000000..736b99df --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/delete.go @@ -0,0 +1,36 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import "fmt" + +type DeleteStatemnet struct { + from string + where *Clause +} + +func NewDelete() *DeleteStatemnet { + return &DeleteStatemnet{} +} + +func (s *DeleteStatemnet) From(from string) *DeleteStatemnet { + s.from = from + return s +} + +func (s *DeleteStatemnet) Where(expr *Clause) *DeleteStatemnet { + s.where = expr + return s +} + +func (s *DeleteStatemnet) ToSQL() (string, []interface{}) { + sql, args := "", []interface{}{} + sql = fmt.Sprintf("DELETE FROM %s", s.from) + + if s.where != nil { + sql = fmt.Sprintf("%s WHERE %s", sql, s.where.fragment) + args = append(args, s.where.args...) + } + + return sql, args +} diff --git a/internal/bench/go-queryx/db/queryx/delete_test.go b/internal/bench/go-queryx/db/queryx/delete_test.go new file mode 100644 index 00000000..82f2d51e --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/delete_test.go @@ -0,0 +1,15 @@ +package queryx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewDelete(t *testing.T) { + s := NewDelete().From("users") + + sql, args := s.ToSQL() + require.Equal(t, "DELETE FROM users", sql) + require.Equal(t, []interface{}{}, args) +} diff --git a/internal/bench/go-queryx/db/queryx/env.go b/internal/bench/go-queryx/db/queryx/env.go new file mode 100644 index 00000000..79c79ec2 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/env.go @@ -0,0 +1,7 @@ +package queryx + +import "os" + +func getenv(k string) string { + return os.Getenv(k) +} diff --git a/internal/bench/go-queryx/db/queryx/float_test.go b/internal/bench/go-queryx/db/queryx/float_test.go new file mode 100644 index 00000000..5ff65740 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/float_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewFloat(t *testing.T) { + f1 := NewFloat(2.1) + require.Equal(t, 2.1, f1.Val) + require.True(t, f1.Valid) + + f2 := NewNullableFloat(nil) + require.False(t, f2.Valid) +} + +func TestFloatJSON(t *testing.T) { + type Foo struct { + X Float `json:"x"` + Y Float `json:"y"` + } + x := NewFloat(2.1) + y := NewNullableFloat(nil) + s := `{"x":2.1,"y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/insert.go b/internal/bench/go-queryx/db/queryx/insert.go new file mode 100644 index 00000000..cf09926d --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/insert.go @@ -0,0 +1,82 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "fmt" + "strings" +) + +type InsertStatement struct { + into string + columns []string + values [][]interface{} + returning []string + onConflict string +} + +func NewInsert() *InsertStatement { + return &InsertStatement{} +} + +func (s *InsertStatement) Into(into string) *InsertStatement { + s.into = into + return s +} + +func (s *InsertStatement) Columns(columns ...string) *InsertStatement { + s.columns = columns + return s +} + +func (s *InsertStatement) Values(values ...interface{}) *InsertStatement { + if len(values) > 0 { + s.values = append(s.values, values) + } + return s +} +func (s *InsertStatement) Returning(returning ...string) *InsertStatement { + s.returning = returning + return s +} + +func (s *InsertStatement) OnConflict(onConflict string) *InsertStatement { + s.onConflict = onConflict + return s +} + +func (s *InsertStatement) ToSQL() (string, []interface{}) { + sql := fmt.Sprintf("INSERT INTO %s", s.into) + + if len(s.columns) > 0 { + sql = fmt.Sprintf("%s(%s)", sql, strings.Join(s.columns, ", ")) + } else { + sql = fmt.Sprintf("%s DEFAULT VALUES", sql) + } + values := []string{} + for _, v := range s.values { + ss := []string{} + for range v { + ss = append(ss, "?") + } + values = append(values, fmt.Sprintf("(%s)", strings.Join(ss, ", "))) + } + if len(values) > 0 { + sql = fmt.Sprintf("%s VALUES %s", sql, strings.Join(values, ", ")) + } + + if len(s.returning) > 0 { + sql = fmt.Sprintf("%s RETURNING %s", sql, strings.Join(s.returning, ", ")) + } + + if s.onConflict != "" { + sql = fmt.Sprintf("%s %s", sql, s.onConflict) + } + + args := []interface{}{} + for _, v := range s.values { + args = append(args, v...) + } + + return sql, args +} diff --git a/internal/bench/go-queryx/db/queryx/insert_test.go b/internal/bench/go-queryx/db/queryx/insert_test.go new file mode 100644 index 00000000..6eb30653 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/insert_test.go @@ -0,0 +1,33 @@ +package queryx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewInsert(t *testing.T) { + s1 := NewInsert().Into("users") + sql, args := s1.ToSQL() + require.Equal(t, "INSERT INTO users DEFAULT VALUES", sql) + require.Equal(t, []interface{}{}, args) + + var columns []string + var values []interface{} + s2 := NewInsert().Into("users").Columns(columns...).Values(values...).Returning("id", "name") + sql, args = s2.ToSQL() + require.Equal(t, "INSERT INTO users DEFAULT VALUES RETURNING id, name", sql) + require.Equal(t, []interface{}{}, args) + + s3 := NewInsert().Into("users").Columns("name", "email").Values("test", "test@example.com") + sql, args = s3.ToSQL() + require.Equal(t, "INSERT INTO users(name, email) VALUES (?, ?)", sql) + require.Equal(t, []interface{}{"test", "test@example.com"}, args) + + s4 := NewInsert().Into("users").Columns("name", "email"). + Values("test1", "test1@example.com"). + Values("test2", "test2@example.com") + sql, args = s4.ToSQL() + require.Equal(t, "INSERT INTO users(name, email) VALUES (?, ?), (?, ?)", sql) + require.Equal(t, []interface{}{"test1", "test1@example.com", "test2", "test2@example.com"}, args) +} diff --git a/internal/bench/go-queryx/db/queryx/integer.go b/internal/bench/go-queryx/db/queryx/integer.go new file mode 100644 index 00000000..060eb85c --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/integer.go @@ -0,0 +1,78 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "strconv" +) + +type Integer struct { + Val int32 + Valid bool + Set bool +} + +func NewInteger(v int32) Integer { + return Integer{Val: v, Valid: true, Set: true} +} + +func NewNullableInteger(v *int32) Integer { + if v != nil { + return NewInteger(*v) + } + return Integer{Set: true} +} + +// Scan implements the Scanner interface. +func (i *Integer) Scan(value interface{}) error { + n := sql.NullInt64{} + err := n.Scan(value) + if err != nil { + return err + } + i.Val, i.Valid = int32(n.Int64), n.Valid + return nil +} + +// Value implements the driver Valuer interface. +func (i Integer) Value() (driver.Value, error) { + if !i.Valid { + return nil, nil + } + return int64(i.Val), nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (i Integer) MarshalJSON() ([]byte, error) { + if !i.Valid { + return json.Marshal(nil) + } + return json.Marshal(i.Val) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (i *Integer) UnmarshalJSON(data []byte) error { + i.Set = true + s := string(data) + if s == "null" { + return nil + } + i.Valid = true + p, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return err + } + i.Val = int32(p) + return nil +} + +// String implements the stringer interface. +func (i Integer) String() string { + if !i.Valid { + return "null" + } + return strconv.Itoa(int(i.Val)) +} diff --git a/internal/bench/go-queryx/db/queryx/integer_column.go b/internal/bench/go-queryx/db/queryx/integer_column.go new file mode 100644 index 00000000..00d3e35f --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/integer_column.go @@ -0,0 +1,88 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import "fmt" + +type IntegerColumn struct { + Name string + Table *Table +} + +func (t *Table) NewIntegerColumn(name string) *IntegerColumn { + return &IntegerColumn{ + Table: t, + Name: name, + } +} + +func (c *IntegerColumn) EQ(v int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) NE(v int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) LT(v int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s < ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) GT(v int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s > ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) LE(v int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s <= ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) GE(v int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s >= ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) In(v []int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s IN (?)", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *IntegerColumn) InRange(start int32, end int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s >= ? and %s.%s< ?", c.Table.Name, c.Name, c.Table.Name, c.Name), + args: []interface{}{start, end}, + } +} + +func (c *IntegerColumn) Between(start int32, end int32) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s >= ? and %s.%s<= ?", c.Table.Name, c.Name, c.Table.Name, c.Name), + args: []interface{}{start, end}, + } +} + +func (c *IntegerColumn) Asc() string { + return fmt.Sprintf("%s.%s ASC", c.Table.Name, c.Name) +} + +func (c *IntegerColumn) Desc() string { + return fmt.Sprintf("%s.%s DESC", c.Table.Name, c.Name) +} diff --git a/internal/bench/go-queryx/db/queryx/integer_test.go b/internal/bench/go-queryx/db/queryx/integer_test.go new file mode 100644 index 00000000..1a2c2ec3 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/integer_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewInteger(t *testing.T) { + i1 := NewInteger(2) + require.Equal(t, int32(2), i1.Val) + require.True(t, i1.Valid) + + i2 := NewNullableInteger(nil) + require.False(t, i2.Valid) +} + +func TestIntegerJSON(t *testing.T) { + type Foo struct { + X Integer `json:"x"` + Y Integer `json:"y"` + } + x := NewInteger(2) + y := NewNullableInteger(nil) + s := `{"x":2,"y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/json_test.go b/internal/bench/go-queryx/db/queryx/json_test.go new file mode 100644 index 00000000..39879002 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/json_test.go @@ -0,0 +1,42 @@ +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewJSON(t *testing.T) { + m := map[string]interface{}{"a": 1} + j1 := NewJSON(m) + require.Equal(t, m, j1.Val) + require.True(t, j1.Valid) + + j2 := NewNullableJSON(nil) + require.False(t, j2.Valid) + + j3 := NewNullableJSON(m) + require.True(t, j3.Valid) +} + +func TestJSONJSON(t *testing.T) { + type Foo struct { + X JSON `json:"x"` + Y JSON `json:"y"` + } + x := NewJSON(map[string]interface{}{"a": "b"}) + y := NewNullableJSON(nil) + s := `{"x":{"a":"b"},"y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/logger.go b/internal/bench/go-queryx/db/queryx/logger.go new file mode 100644 index 00000000..8d0fe04a --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/logger.go @@ -0,0 +1,15 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +type Logger interface { + Print(v ...interface{}) + Printf(format string, v ...interface{}) + Println(v ...interface{}) + Panic(v ...interface{}) + Panicf(format string, v ...interface{}) + Panicln(v ...interface{}) + Fatal(v ...interface{}) + Fatalf(format string, v ...interface{}) + Fatalln(v ...interface{}) +} diff --git a/internal/bench/go-queryx/db/queryx/model_change.go b/internal/bench/go-queryx/db/queryx/model_change.go new file mode 100644 index 00000000..13eb90ca --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/model_change.go @@ -0,0 +1,143 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +type ModelChange struct { + ID BigInt + Name String + Title String + Fax String + Web String + Age BigInt + Righ Boolean + Counter Integer +} + +func (c *ModelChange) Changes() (columns []string, values []interface{}) { + if c == nil { + return columns, values + } + if c.ID.Set { + columns = append(columns, "id") + values = append(values, c.ID) + } + if c.Name.Set { + columns = append(columns, "name") + values = append(values, c.Name) + } + if c.Title.Set { + columns = append(columns, "title") + values = append(values, c.Title) + } + if c.Fax.Set { + columns = append(columns, "fax") + values = append(values, c.Fax) + } + if c.Web.Set { + columns = append(columns, "web") + values = append(values, c.Web) + } + if c.Age.Set { + columns = append(columns, "age") + values = append(values, c.Age) + } + if c.Righ.Set { + columns = append(columns, "righ") + values = append(values, c.Righ) + } + if c.Counter.Set { + columns = append(columns, "counter") + values = append(values, c.Counter) + } + return columns, values +} + +func (c *ModelChange) SetID(id int64) *ModelChange { + c.ID = NewBigInt(id) + c.ID.Set = true + return c +} + +func (c *ModelChange) SetName(name string) *ModelChange { + c.Name = NewString(name) + c.Name.Set = true + return c +} + +func (c *ModelChange) SetNullableName(name *string) *ModelChange { + c.Name = NewNullableString(name) + c.Name.Set = true + return c +} + +func (c *ModelChange) SetTitle(title string) *ModelChange { + c.Title = NewString(title) + c.Title.Set = true + return c +} + +func (c *ModelChange) SetNullableTitle(title *string) *ModelChange { + c.Title = NewNullableString(title) + c.Title.Set = true + return c +} + +func (c *ModelChange) SetFax(fax string) *ModelChange { + c.Fax = NewString(fax) + c.Fax.Set = true + return c +} + +func (c *ModelChange) SetNullableFax(fax *string) *ModelChange { + c.Fax = NewNullableString(fax) + c.Fax.Set = true + return c +} + +func (c *ModelChange) SetWeb(web string) *ModelChange { + c.Web = NewString(web) + c.Web.Set = true + return c +} + +func (c *ModelChange) SetNullableWeb(web *string) *ModelChange { + c.Web = NewNullableString(web) + c.Web.Set = true + return c +} + +func (c *ModelChange) SetAge(age int64) *ModelChange { + c.Age = NewBigInt(age) + c.Age.Set = true + return c +} + +func (c *ModelChange) SetNullableAge(age *int64) *ModelChange { + c.Age = NewNullableBigInt(age) + c.Age.Set = true + return c +} + +func (c *ModelChange) SetRigh(righ bool) *ModelChange { + c.Righ = NewBoolean(righ) + c.Righ.Set = true + return c +} + +func (c *ModelChange) SetNullableRigh(righ *bool) *ModelChange { + c.Righ = NewNullableBoolean(righ) + c.Righ.Set = true + return c +} + +func (c *ModelChange) SetCounter(counter int32) *ModelChange { + c.Counter = NewInteger(counter) + c.Counter.Set = true + return c +} + +func (c *ModelChange) SetNullableCounter(counter *int32) *ModelChange { + c.Counter = NewNullableInteger(counter) + c.Counter.Set = true + return c +} diff --git a/internal/bench/go-queryx/db/queryx/scan.go b/internal/bench/go-queryx/db/queryx/scan.go new file mode 100644 index 00000000..4dde2a11 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/scan.go @@ -0,0 +1,135 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql" + "fmt" + "reflect" + "strings" +) + +func ScanOne(rows *sql.Rows, v interface{}) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + return fmt.Errorf("must pass pointer") + } + + columns, err := rows.Columns() + if err != nil { + return err + } + + typ := rv.Type().Elem() + + // column -> index + names := make(map[string]int, typ.NumField()) + for i := 0; i < typ.NumField(); i++ { + f := typ.Field(i) + names[columnName(f)] = i + } + + if !rows.Next() { + return sql.ErrNoRows + } + + indexes := make(map[int]int, typ.NumField()) + for i, c := range columns { + name := strings.ToLower(strings.Split(c, "(")[0]) + index, ok := names[name] + if !ok { + return fmt.Errorf("name not found") + } + indexes[i] = index + } + + values := make([]interface{}, len(columns)) + for i := range columns { + t := typ.Field(indexes[i]).Type + values[i] = reflect.New(t).Interface() + + } + + // scan into interfaces + if err := rows.Scan(values...); err != nil { + return err + } + + for i, v := range values { + reflect.Indirect(rv).Field(indexes[i]).Set(reflect.Indirect(reflect.ValueOf(v))) + } + + if rows.Next() { + return fmt.Errorf("more than one row") + } + + return nil +} + +func ScanSlice(rows *sql.Rows, v interface{}) error { + rv := reflect.ValueOf(v) + if rv.Kind() != reflect.Ptr { + return fmt.Errorf("must pass pointer") + } + + rv = reflect.Indirect(rv) + if k := rv.Kind(); k != reflect.Slice { + return fmt.Errorf("must pass slice") + } + + columns, err := rows.Columns() + if err != nil { + return err + } + + typ := rv.Type().Elem() + + names := make(map[string]int, typ.NumField()) + for i := 0; i < typ.NumField(); i++ { + f := typ.Field(i) + names[columnName(f)] = i + } + + indexes := make(map[int]int, typ.NumField()) + for i, c := range columns { + name := strings.ToLower(strings.Split(c, "(")[0]) + index, ok := names[name] + if !ok { + return fmt.Errorf("name %+v not found", name) + } + indexes[i] = index + } + + for rows.Next() { + values := make([]interface{}, len(columns)) + for i := range columns { + t := typ.Field(indexes[i]).Type + values[i] = reflect.New(t).Interface() + } + + // scan into interfaces + if err := rows.Scan(values...); err != nil { + return err + } + + // convert to reflect.Value + e := reflect.New(typ).Elem() + for i, v := range values { + fv := e.Field(indexes[i]) + fv.Set(reflect.Indirect(reflect.ValueOf(v))) + } + + vv := reflect.Append(rv, e) + rv.Set(vv) + } + + return nil +} + +func columnName(f reflect.StructField) string { + name := strings.ToLower(f.Name) + if tag, ok := f.Tag.Lookup("db"); ok { + name = tag + } + return name +} diff --git a/internal/bench/go-queryx/db/queryx/schema.go b/internal/bench/go-queryx/db/queryx/schema.go new file mode 100644 index 00000000..af30619f --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/schema.go @@ -0,0 +1,52 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +type Schema struct { + Model *Table + ModelID *BigIntColumn + ModelName *StringColumn + ModelTitle *StringColumn + ModelFax *StringColumn + ModelWeb *StringColumn + ModelAge *BigIntColumn + ModelRigh *BooleanColumn + ModelCounter *IntegerColumn +} + +func NewSchema() *Schema { + model := NewTable("models") + + return &Schema{ + Model: model, + ModelID: model.NewBigIntColumn("id"), + ModelName: model.NewStringColumn("name"), + ModelTitle: model.NewStringColumn("title"), + ModelFax: model.NewStringColumn("fax"), + ModelWeb: model.NewStringColumn("web"), + ModelAge: model.NewBigIntColumn("age"), + ModelRigh: model.NewBooleanColumn("righ"), + ModelCounter: model.NewIntegerColumn("counter"), + } +} + +func (s *Schema) And(clauses ...*Clause) *Clause { + return clauses[0].And(clauses[1:]...) +} + +func (s *Schema) Or(clauses ...*Clause) *Clause { + return clauses[0].Or(clauses[1:]...) +} + +func (s *Schema) ChangeModel() *ModelChange { + return &ModelChange{ + ID: BigInt{}, + Name: String{}, + Title: String{}, + Fax: String{}, + Web: String{}, + Age: BigInt{}, + Righ: Boolean{}, + Counter: Integer{}, + } +} diff --git a/internal/bench/go-queryx/db/queryx/select.go b/internal/bench/go-queryx/db/queryx/select.go new file mode 100644 index 00000000..fec8eeb8 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/select.go @@ -0,0 +1,142 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "fmt" + "strings" +) + +type SelectStatement struct { + selection []string + from string + where *Clause + limit *int + offset *int + order []string + group string + having string + distinct []string + joins []string +} + +func NewSelect() *SelectStatement { + return &SelectStatement{} +} + +func (s *SelectStatement) Select(selection ...string) *SelectStatement { + s.selection = selection + return s +} + +func (s *SelectStatement) From(from string) *SelectStatement { + s.from = from + return s +} + +func (s *SelectStatement) Where(clauses ...*Clause) *SelectStatement { + if len(clauses) == 0 { + return s + } + + if s.where == nil { + s.where = clauses[0].And(clauses[1:]...) + } else { + s.where = s.where.And(clauses...) + } + + return s +} + +func (s *SelectStatement) Limit(limit int) *SelectStatement { + s.limit = &limit + return s +} + +func (s *SelectStatement) Offset(offset int) *SelectStatement { + s.offset = &offset + return s +} + +func (s *SelectStatement) Order(order ...string) *SelectStatement { + s.order = append(s.order, order...) + return s +} + +func (s *SelectStatement) Distinct(distinct ...string) *SelectStatement { + s.distinct = distinct + return s +} + +func (s *SelectStatement) GroupBy(group string) *SelectStatement { + s.group = group + return s +} + +func (s *SelectStatement) Having(having string) *SelectStatement { + s.having = having + return s +} + +func (s *SelectStatement) Join(join ...string) *SelectStatement { + s.joins = append(s.joins, join...) + return s +} + +// convert select statement to update statement +func (s *SelectStatement) Update() *UpdateStatement { + if s.limit != nil { + return NewUpdate().Table(s.from).Where(s.where) // TODO: convert into subquery + } + return NewUpdate().Table(s.from).Where(s.where) +} + +// convert select statement to delete statement +func (s *SelectStatement) Delete() *DeleteStatemnet { + return NewDelete().From(s.from).Where(s.where) +} + +func (s *SelectStatement) ToSQL() (string, []interface{}) { + var query string + if len(s.distinct) > 0 { + query = fmt.Sprintf("SELECT DISTINCT %s FROM %s", strings.Join(s.distinct, ", "), s.from) + } else { + query = fmt.Sprintf("SELECT %s FROM %s", strings.Join(s.selection, ", "), s.from) + } + args := []interface{}{} + + if len(s.joins) > 0 { + for i := 0; i < len(s.joins); i++ { + query = fmt.Sprintf("%s %s", query, s.joins[i]) + } + } + + if s.where != nil { + query = fmt.Sprintf("%s WHERE %s", query, s.where.fragment) + args = append(args, s.where.args...) + } + + if s.group != "" { + query = fmt.Sprintf("%s GROUP BY %s", query, s.group) + } + + if s.having != "" { + query = fmt.Sprintf("%s HAVING %s", query, s.having) + } + + if s.order != nil { + query = fmt.Sprintf("%s ORDER BY %s", query, strings.Join(s.order, ", ")) + } + + if s.limit != nil { + query = fmt.Sprintf("%s LIMIT ?", query) + args = append(args, *s.limit) + } + + if s.offset != nil { + query = fmt.Sprintf("%s OFFSET ?", query) + args = append(args, *s.offset) + } + + return query, args +} diff --git a/internal/bench/go-queryx/db/queryx/select_test.go b/internal/bench/go-queryx/db/queryx/select_test.go new file mode 100644 index 00000000..5c4b8977 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/select_test.go @@ -0,0 +1,35 @@ +package queryx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSelect(t *testing.T) { + s := NewSelect().Select("users.*").From("users") + sql, args := s.ToSQL() + require.Equal(t, `SELECT users.* FROM users`, sql) + require.Equal(t, []interface{}{}, args) + + sql, args = s.Update().Columns("name", "email").Values("test", "test@example.com").ToSQL() + require.Equal(t, `UPDATE users SET name = ?, email = ?`, sql) + require.Equal(t, []interface{}{"test", "test@example.com"}, args) + + s1 := s.Limit(1) + sql, args = s1.ToSQL() + require.Equal(t, `SELECT users.* FROM users LIMIT ?`, sql) + require.Equal(t, []interface{}{1}, args) +} + +func TestSelectWhere(t *testing.T) { + s1 := NewSelect().Select("users.*").From("users").Where(NewClause("id = ?", []interface{}{1})) + sql, args := s1.ToSQL() + require.Equal(t, `SELECT users.* FROM users WHERE id = ?`, sql) + require.Equal(t, []interface{}{1}, args) + + s1.Where(NewClause("name = ?", []interface{}{"test"})) + sql, args = s1.ToSQL() + require.Equal(t, `SELECT users.* FROM users WHERE (id = ?) AND (name = ?)`, sql) + require.Equal(t, []interface{}{1, "test"}, args) +} diff --git a/internal/bench/go-queryx/db/queryx/string.go b/internal/bench/go-queryx/db/queryx/string.go new file mode 100644 index 00000000..d47dd756 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/string.go @@ -0,0 +1,72 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "fmt" +) + +type String struct { + Val string + Valid bool + Set bool +} + +func NewString(v string) String { + return String{Val: v, Valid: true, Set: true} +} + +func NewNullableString(v *string) String { + if v != nil { + return NewString(*v) + } + return String{Set: true} +} + +// Scan implements the Scanner interface. +func (s *String) Scan(value interface{}) error { + ns := sql.NullString{String: s.Val} + err := ns.Scan(value) + s.Val, s.Valid = ns.String, ns.Valid + return err +} + +// Value implements the driver Valuer interface. +func (s String) Value() (driver.Value, error) { + if !s.Valid { + return nil, nil + } + return s.Val, nil +} + +// MarshalJSON implements the json.Marshaler interface. +func (s String) MarshalJSON() ([]byte, error) { + if !s.Valid { + return json.Marshal(nil) + } + return json.Marshal(s.Val) +} + +// UnmarshalJSON implements the json.Unmarshaler interface. +func (s *String) UnmarshalJSON(data []byte) error { + s.Set = true + if string(data) == "null" { + return nil + } + s.Valid = true + if err := json.Unmarshal(data, &s.Val); err != nil { + return err + } + return nil +} + +// String implements the stringer interface. +func (s String) String() string { + if !s.Valid { + return "null" + } + return fmt.Sprintf(`"%s"`, s.Val) +} diff --git a/internal/bench/go-queryx/db/queryx/string_column.go b/internal/bench/go-queryx/db/queryx/string_column.go new file mode 100644 index 00000000..00601c96 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/string_column.go @@ -0,0 +1,93 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import "fmt" + +type StringColumn struct { + Name string + Table *Table +} + +func (t *Table) NewStringColumn(name string) *StringColumn { + return &StringColumn{ + Table: t, + Name: name, + } +} + +func (c *StringColumn) NE(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} +func (c *StringColumn) EQ(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("lower(%s.%s) = lower(?)", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *StringColumn) IEQ(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *StringColumn) In(v []string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s IN (?)", c.Table.Name, c.Name), + args: []interface{}{v}, + } +} + +func (c *StringColumn) Like(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s ilike ?", c.Table.Name, c.Name), + args: []interface{}{fmt.Sprintf("%s%s%s", "%", v, "%")}, + } +} + +func (c *StringColumn) ILike(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s like ?", c.Table.Name, c.Name), + args: []interface{}{fmt.Sprintf("%s%s%s", "%", v, "%")}, + } +} +func (c *StringColumn) IStartsWith(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s like ?", c.Table.Name, c.Name), + args: []interface{}{fmt.Sprintf("%s%s", v, "%")}, + } +} + +func (c *StringColumn) StartsWith(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s ilike ?", c.Table.Name, c.Name), + args: []interface{}{fmt.Sprintf("%s%s", v, "%")}, + } +} + +func (c *StringColumn) EndsWith(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s ilike ?", c.Table.Name, c.Name), + args: []interface{}{fmt.Sprintf("%s%s", "%", v)}, + } +} + +func (c *StringColumn) IEndsWith(v string) *Clause { + return &Clause{ + fragment: fmt.Sprintf("%s.%s like ?", c.Table.Name, c.Name), + args: []interface{}{fmt.Sprintf("%s%s", "%", v)}, + } +} + +func (c *StringColumn) Asc() string { + return fmt.Sprintf("%s.%s ASC", c.Table.Name, c.Name) +} + +func (c *StringColumn) Desc() string { + return fmt.Sprintf("%s.%s DESC", c.Table.Name, c.Name) +} diff --git a/internal/bench/go-queryx/db/queryx/string_test.go b/internal/bench/go-queryx/db/queryx/string_test.go new file mode 100644 index 00000000..d2e7644f --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/string_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewString(t *testing.T) { + s1 := NewString("ss") + require.Equal(t, "ss", s1.Val) + require.True(t, s1.Valid) + + s2 := NewNullableString(nil) + require.False(t, s2.Valid) +} + +func TestStringJSON(t *testing.T) { + type Foo struct { + X String `json:"x"` + Y String `json:"y"` + } + x := NewString("ss") + y := NewNullableString(nil) + s := `{"x":"ss","y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/table.go b/internal/bench/go-queryx/db/queryx/table.go new file mode 100644 index 00000000..75a2e9a8 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/table.go @@ -0,0 +1,13 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +type Table struct { + Name string +} + +func NewTable(name string) *Table { + return &Table{ + Name: name, + } +} diff --git a/internal/bench/go-queryx/db/queryx/time_test.go b/internal/bench/go-queryx/db/queryx/time_test.go new file mode 100644 index 00000000..55bb768f --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/time_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewTime(t *testing.T) { + t1 := NewTime("12:11:10") + require.Equal(t, "12:11:10", t1.Val.Format("15:04:05")) + require.True(t, t1.Valid) + + t2 := NewNullableTime(nil) + require.False(t, t2.Valid) +} + +func TestTimeJSON(t *testing.T) { + type Foo struct { + X Time `json:"x"` + Y Time `json:"y"` + } + x := NewTime("12:11:10") + y := NewNullableTime(nil) + s := `{"x":"12:11:10","y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/db/queryx/update.go b/internal/bench/go-queryx/db/queryx/update.go new file mode 100644 index 00000000..2388cfbe --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/update.go @@ -0,0 +1,67 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "fmt" + "strings" +) + +type UpdateStatement struct { + table string + columns []string + values []interface{} + where *Clause + returning string +} + +func NewUpdate() *UpdateStatement { + return &UpdateStatement{} +} + +func (s *UpdateStatement) Table(table string) *UpdateStatement { + s.table = table + return s +} + +func (s *UpdateStatement) Columns(columns ...string) *UpdateStatement { + s.columns = columns + return s +} + +func (s *UpdateStatement) Values(values ...interface{}) *UpdateStatement { + s.values = values + return s +} + +func (s *UpdateStatement) Where(expr *Clause) *UpdateStatement { + s.where = expr + return s +} + +func (s *UpdateStatement) Returning(returning string) *UpdateStatement { + s.returning = returning + return s +} + +func (s *UpdateStatement) ToSQL() (string, []interface{}) { + sql, args := fmt.Sprintf("UPDATE %s SET", s.table), s.values + + sets := []string{} + for _, col := range s.columns { + sets = append(sets, fmt.Sprintf("%s = ?", col)) + } + + sql = fmt.Sprintf("%s %s", sql, strings.Join(sets, ", ")) + + if s.where != nil { + sql = fmt.Sprintf("%s WHERE %s", sql, s.where.fragment) + args = append(args, s.where.args...) + } + + if s.returning != "" { + sql = fmt.Sprintf("%s RETURNING %s", sql, s.returning) + } + + return sql, args +} diff --git a/internal/bench/go-queryx/db/queryx/update_test.go b/internal/bench/go-queryx/db/queryx/update_test.go new file mode 100644 index 00000000..0d5e40e6 --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/update_test.go @@ -0,0 +1,14 @@ +package queryx + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewUpdate(t *testing.T) { + s := NewUpdate().Table("users").Columns("name", "email").Values("test", "test@example.com") + sql, args := s.ToSQL() + require.Equal(t, "UPDATE users SET name = ?, email = ?", sql) + require.Equal(t, []interface{}{"test", "test@example.com"}, args) +} diff --git a/internal/bench/go-queryx/db/queryx/uuid_test.go b/internal/bench/go-queryx/db/queryx/uuid_test.go new file mode 100644 index 00000000..3fcd2eeb --- /dev/null +++ b/internal/bench/go-queryx/db/queryx/uuid_test.go @@ -0,0 +1,40 @@ +// Code generated by queryx, DO NOT EDIT. + +package queryx + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNewUUID(t *testing.T) { + u1 := NewUUID("a81e44c5-7e18-4dfe-b9b3-d9280629d2ef") + require.Equal(t, "a81e44c5-7e18-4dfe-b9b3-d9280629d2ef", u1.Val) + require.True(t, u1.Valid) + + u2 := NewNullableUUID(nil) + require.False(t, u2.Valid) +} + +func TestUUIDJSON(t *testing.T) { + type Foo struct { + X UUID `json:"x"` + Y UUID `json:"y"` + } + x := NewUUID("a81e44c5-7e18-4dfe-b9b3-d9280629d2ef") + y := NewNullableUUID(nil) + s := `{"x":"a81e44c5-7e18-4dfe-b9b3-d9280629d2ef","y":null}` + + f1 := Foo{X: x, Y: y} + b, err := json.Marshal(f1) + require.NoError(t, err) + require.Equal(t, s, string(b)) + + var f2 Foo + err = json.Unmarshal([]byte(s), &f2) + require.NoError(t, err) + require.Equal(t, x, f2.X) + require.Equal(t, y, f2.Y) +} diff --git a/internal/bench/go-queryx/helper/constants.go b/internal/bench/go-queryx/helper/constants.go new file mode 100644 index 00000000..e8a58577 --- /dev/null +++ b/internal/bench/go-queryx/helper/constants.go @@ -0,0 +1,8 @@ +package helper + +var ( + OrmMaxIdle int + OrmMaxConn int + OrmSource string + DebugMode bool +) diff --git a/internal/bench/go-queryx/helper/error.go b/internal/bench/go-queryx/helper/error.go new file mode 100644 index 00000000..a532fd7b --- /dev/null +++ b/internal/bench/go-queryx/helper/error.go @@ -0,0 +1,23 @@ +package helper + +import ( + "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] +} diff --git a/internal/bench/go-queryx/helper/misc.go b/internal/bench/go-queryx/helper/misc.go new file mode 100644 index 00000000..067887b3 --- /dev/null +++ b/internal/bench/go-queryx/helper/misc.go @@ -0,0 +1,14 @@ +package helper + +import ( + "reflect" + "runtime" + "strings" +) + +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/bench/go-queryx/helper/sql.go b/internal/bench/go-queryx/helper/sql.go new file mode 100644 index 00000000..e9f38cff --- /dev/null +++ b/internal/bench/go-queryx/helper/sql.go @@ -0,0 +1,64 @@ +package helper + +import ( + "database/sql" + "fmt" + _ "github.com/lib/pq" +) + +func CreateTables() error { + queries := [][]string{ + { + `DROP TABLE IF EXISTS models;`, + `CREATE TABLE models ( + id SERIAL NOT NULL, + name text NOT NULL, + title text NOT NULL, + fax text NOT NULL, + web text NOT NULL, + age integer NOT NULL, + "righ" boolean NOT NULL, + counter bigint NOT NULL, + CONSTRAINT models_pkey PRIMARY KEY (id) + ) WITH (OIDS=FALSE);`, + }, + { + `DROP TABLE IF EXISTS model5;`, + `CREATE TABLE model5 ( + id SERIAL NOT NULL, + name text NOT NULL, + title text NOT NULL, + fax text NOT NULL, + web text NOT NULL, + age integer NOT NULL, + "righ" boolean NOT NULL, + counter bigint NOT NULL + ) WITH (OIDS=FALSE);`, + }, + } + + db, err := sql.Open("postgres", OrmSource) + if err != nil { + return fmt.Errorf("init_tables: %w", err) + } + + defer func() { + _ = db.Close() + }() + + err = db.Ping() + if err != nil { + return fmt.Errorf("init_tables: %w", err) + } + + for _, query := range queries { + for _, line := range query { + _, err = db.Exec(line) + if err != nil { + return fmt.Errorf("init_tables: %w", err) + } + } + } + + return nil +} diff --git a/internal/bench/go-queryx/helper/suite.go b/internal/bench/go-queryx/helper/suite.go new file mode 100644 index 00000000..49540b8b --- /dev/null +++ b/internal/bench/go-queryx/helper/suite.go @@ -0,0 +1,89 @@ +package helper + +import ( + "testing" +) + +type ORMInterface interface { + Name() string + Init() error + Close() error + Insert(b *testing.B) + InsertMulti(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(orm ORMInterface, reports map[string]BenchmarkReport) (BenchmarkResult, error) { + err := orm.Init() + if err != nil { + return BenchmarkResult{}, err + } + + defer func(orm ORMInterface) { + _ = orm.Close() + }(orm) + + var result BenchmarkResult + operations := []func(b *testing.B){orm.Insert, orm.InsertMulti, orm.Update, orm.Read, orm.ReadSlice} + + result.ORM = orm.Name() + for _, operation := range operations { + // Clean tables for each run + err := CreateTables() + if err != nil { + panic(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) + result.Results = append(result.Results, *gotResult) + } + + return result, nil +} diff --git a/internal/bench/go-queryx/models.go b/internal/bench/go-queryx/models.go new file mode 100644 index 00000000..9781d797 --- /dev/null +++ b/internal/bench/go-queryx/models.go @@ -0,0 +1,34 @@ +package go_queryx + +// Model for go-queryx +type Model8 struct { + ID int `column:"id"` + Name string `column:"name"` + Title string `column:"title"` + Fax string `column:"fax"` + Web string `column:"web"` + Age int `column:"age"` + Righ bool `column:"righ"` + Counter int64 `column:"counter"` +} + +func (entity *Model8) GetTableName() string { + return "models" +} + +func (entity *Model8) GetPKColumnName() string { + return "id" +} + +func NewModel8() *Model8 { + m := new(Model8) + 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/bench/go-queryx/queryx.go b/internal/bench/go-queryx/queryx.go new file mode 100644 index 00000000..7ae65cc0 --- /dev/null +++ b/internal/bench/go-queryx/queryx.go @@ -0,0 +1,140 @@ +package go_queryx + +import ( + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db" + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/helper" + "testing" + + _ "github.com/lib/pq" +) + +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 "go-queryx" +} + +func (Queryx *Queryx) Init() error { + client, err := db.NewClient() + if err != nil { + return err + } + c = client + return err +} + +func (Queryx *Queryx) Close() error { + return nil +} + +func (Queryx *Queryx) Insert(b *testing.B) { + m := NewModel8() + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + m.ID = 0 + _, err := c.QueryModel().Create(c.ChangeModel().SetName(m.Name). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)).SetRigh(m.Righ)) + if err != nil { + helper.SetError(b, Queryx.Name(), "Insert", err.Error()) + } + } +} + +func (Queryx *Queryx) InsertMulti(b *testing.B) { + m := NewModel8() + 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(int64(m.Age)).SetCounter(int32(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(), "InsertMulti", err.Error()) + } + } +} + +func (Queryx *Queryx) Update(b *testing.B) { + m := NewModel8() + change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(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(), "Update", err.Error()) + } + } +} + +func (Queryx *Queryx) Read(b *testing.B) { + m := NewModel8() + change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(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(), "Read", err.Error()) + } + } +} + +func (Queryx *Queryx) ReadSlice(b *testing.B) { + m := NewModel8() + change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(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(), "ReadSlice", err.Error()) + } + } +} diff --git a/internal/bench/go-queryx/schema.hcl b/internal/bench/go-queryx/schema.hcl new file mode 100644 index 00000000..9c640497 --- /dev/null +++ b/internal/bench/go-queryx/schema.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/bench/main.go b/internal/bench/main.go new file mode 100644 index 00000000..32461881 --- /dev/null +++ b/internal/bench/main.go @@ -0,0 +1,167 @@ +package main + +import ( + "flag" + "fmt" + "github.com/swiftcarrot/queryx/internal/bench/go-queryx" + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/helper" + "math/rand" + "os" + "runtime" + "sort" + "strings" + "text/tabwriter" + "time" + + _ "github.com/lib/pq" +) + +// VERSION constant +const VERSION = "v1.0.2" + +var defaultBenchmarkNames = []string{ + "beego", "bun", "dbr", "ent", + "godb", "gorm", "gorm_prep", "gorp", + "pg", "pgx", "pgx_pool", "pop", + "raw", "reform", "rel", "sqlboiler", + "sqlc", "sqlx", "upper", "xorm", + "zorm", "gen", "go-queryx", +} + +type ListOpts []string + +func (opts *ListOpts) String() string { + return fmt.Sprint(*opts) +} + +func (opts *ListOpts) Set(value string) error { + if value != "all" && !strings.Contains(" "+strings.Join(defaultBenchmarkNames, " ")+" ", " "+value+" ") { + return fmt.Errorf("wrong run name %s", value) + } + + *opts = append(*opts, value) + return nil +} + +func (opts ListOpts) Shuffle() { + rd := rand.New(rand.NewSource(time.Now().UnixNano())) + for i := 0; i < len(opts); i++ { + a := rd.Intn(len(opts)) + b := rd.Intn(len(opts)) + opts[a], opts[b] = opts[b], opts[a] + } +} + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU()) + + var orms ListOpts + var all bool + + flag.StringVar(&helper.OrmSource, "source", "host=localhost user=postgres password=postgres dbname=test sslmode=disable", "postgres dsn source") + flag.Var(&orms, "orm", "orm name: all, "+strings.Join(defaultBenchmarkNames, ", ")) + flag.IntVar(&helper.OrmMaxIdle, "max_idle", 200, "max idle conns") + flag.IntVar(&helper.OrmMaxConn, "max_conn", 200, "max open conns") + flag.BoolVar(&helper.DebugMode, "debug", false, "Enable debug mode (also prints not-sorted results of ORMs)") + version := flag.Bool("version", false, "prints current roxy version") + flag.Parse() + + // Print version + if *version { + fmt.Println(VERSION) + os.Exit(0) + } + + // Check it is all + if len(orms) == 0 { + all = true + } else { + for _, n := range orms { + if n == "all" { + all = true + } + } + } + + if all { + orms = defaultBenchmarkNames + } + orms.Shuffle() + + // Init error map + helper.Errors = make(map[string]map[string]string, 0) + for _, name := range defaultBenchmarkNames { + helper.Errors[name] = make(map[string]string, 0) + } + + runBenchmarks(orms) +} + +func runBenchmarks(orms ListOpts) { + // Run benchmarks + benchmarks := map[string]helper.ORMInterface{ + "go-queryx": go_queryx.CreateQueryx(), + } + + table := new(tabwriter.Writer) + table.Init(os.Stdout, 0, 8, 2, '\t', tabwriter.AlignRight) + + reports := make(map[string]helper.BenchmarkReport, 0) + i := 0 + for _, n := range orms { + orm := benchmarks[n] + if orm == nil { + panic(fmt.Sprintf("Unknown ORM: %s", n)) + } + + res, err := helper.RunBenchmarks(orm, reports) + if err != nil { + panic(fmt.Sprintf("An error occured while running the benchmarks: %v", err)) + } + + if helper.DebugMode { + if i != 0 { + _, _ = fmt.Fprint(table, "\n") + } + _, _ = fmt.Fprintf(table, "%s Benchmark Results:\n", n) + for _, result := range res.Results { + if result.ErrorMsg == "" { + _, _ = fmt.Fprintf(table, "%s:\t%d\t%d ns/op\t%d B/op\t%d allocs/op\n", result.Method, result.N, result.NsPerOp, result.MemBytes, result.MemAllocs) + } else { + _, _ = fmt.Fprintf(table, "%s:\t%s\n", result.Method, result.ErrorMsg) + } + } + _ = table.Flush() + } + i++ + } + + // Sort results + for _, v := range reports { + sort.Sort(v) + } + + // Print final reports + if helper.DebugMode { + _, _ = fmt.Fprint(table, "\n") + } + _, _ = 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() +} From e32c73e3998c5ef09f8f45dc5d7bbe26acf5506a Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 18 Jan 2024 21:10:59 +0800 Subject: [PATCH 02/18] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9F=BA=E5=87=86?= =?UTF-8?q?=E6=B5=8B=E8=AF=95=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Makefile b/Makefile index d8a20007..46ba8aaf 100644 --- a/Makefile +++ b/Makefile @@ -56,3 +56,17 @@ 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')" + +build-orm: + cd internal/bench && go build -o bin/queryxorm main.go + +install-orm: build-orm + cd internal/bench && install bin/queryxorm /usr/local/bin + +benchmarks:install-orm install + cd internal/bench/go-queryx && queryx db:drop --schema schema.hcl + cd internal/bench/go-queryx && queryx db:create --schema schema.hcl + cd internal/bench/go-queryx && queryx db:migrate --schema schema.hcl + cd internal/bench/go-queryx && queryx g --schema schema.hcl + #cd internal/bench/ts-queryx && queryx g --schema schema.hcl + queryxorm -orm=go-queryx From a317145fe78ddc6774fe60abbe963e8307a9d10b Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 18 Jan 2024 21:35:24 +0800 Subject: [PATCH 03/18] rm -rf db --- internal/bench/go-queryx/db/errors.go | 7 - .../migrations/20240118175745_auto.down.sql | 1 - .../db/migrations/20240118175745_auto.up.sql | 1 - internal/bench/go-queryx/db/model.go | 91 ------ internal/bench/go-queryx/db/model_query.go | 297 ------------------ internal/bench/go-queryx/db/queryx.go | 120 ------- internal/bench/go-queryx/db/queryx/adapter.go | 48 --- .../bench/go-queryx/db/queryx/adapter_test.go | 15 - internal/bench/go-queryx/db/queryx/bigint.go | 75 ----- .../go-queryx/db/queryx/bigint_column.go | 93 ------ .../bench/go-queryx/db/queryx/bigint_test.go | 40 --- internal/bench/go-queryx/db/queryx/bind.go | 167 ---------- internal/bench/go-queryx/db/queryx/boolean.go | 77 ----- .../go-queryx/db/queryx/boolean_column.go | 39 --- .../bench/go-queryx/db/queryx/boolean_test.go | 40 --- internal/bench/go-queryx/db/queryx/clause.go | 57 ---- .../bench/go-queryx/db/queryx/clause_test.go | 37 --- internal/bench/go-queryx/db/queryx/config.go | 26 -- .../bench/go-queryx/db/queryx/date_test.go | 40 --- .../go-queryx/db/queryx/datetime_test.go | 40 --- internal/bench/go-queryx/db/queryx/db.go | 110 ------- internal/bench/go-queryx/db/queryx/delete.go | 36 --- .../bench/go-queryx/db/queryx/delete_test.go | 15 - internal/bench/go-queryx/db/queryx/env.go | 7 - .../bench/go-queryx/db/queryx/float_test.go | 40 --- internal/bench/go-queryx/db/queryx/insert.go | 82 ----- .../bench/go-queryx/db/queryx/insert_test.go | 33 -- internal/bench/go-queryx/db/queryx/integer.go | 78 ----- .../go-queryx/db/queryx/integer_column.go | 88 ------ .../bench/go-queryx/db/queryx/integer_test.go | 40 --- .../bench/go-queryx/db/queryx/json_test.go | 42 --- internal/bench/go-queryx/db/queryx/logger.go | 15 - .../bench/go-queryx/db/queryx/model_change.go | 143 --------- internal/bench/go-queryx/db/queryx/scan.go | 135 -------- internal/bench/go-queryx/db/queryx/schema.go | 52 --- internal/bench/go-queryx/db/queryx/select.go | 142 --------- .../bench/go-queryx/db/queryx/select_test.go | 35 --- internal/bench/go-queryx/db/queryx/string.go | 72 ----- .../go-queryx/db/queryx/string_column.go | 93 ------ .../bench/go-queryx/db/queryx/string_test.go | 40 --- internal/bench/go-queryx/db/queryx/table.go | 13 - .../bench/go-queryx/db/queryx/time_test.go | 40 --- internal/bench/go-queryx/db/queryx/update.go | 67 ---- .../bench/go-queryx/db/queryx/update_test.go | 14 - .../bench/go-queryx/db/queryx/uuid_test.go | 40 --- 45 files changed, 2783 deletions(-) delete mode 100644 internal/bench/go-queryx/db/errors.go delete mode 100644 internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql delete mode 100644 internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql delete mode 100644 internal/bench/go-queryx/db/model.go delete mode 100644 internal/bench/go-queryx/db/model_query.go delete mode 100644 internal/bench/go-queryx/db/queryx.go delete mode 100644 internal/bench/go-queryx/db/queryx/adapter.go delete mode 100644 internal/bench/go-queryx/db/queryx/adapter_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/bigint.go delete mode 100644 internal/bench/go-queryx/db/queryx/bigint_column.go delete mode 100644 internal/bench/go-queryx/db/queryx/bigint_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/bind.go delete mode 100644 internal/bench/go-queryx/db/queryx/boolean.go delete mode 100644 internal/bench/go-queryx/db/queryx/boolean_column.go delete mode 100644 internal/bench/go-queryx/db/queryx/boolean_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/clause.go delete mode 100644 internal/bench/go-queryx/db/queryx/clause_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/config.go delete mode 100644 internal/bench/go-queryx/db/queryx/date_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/datetime_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/db.go delete mode 100644 internal/bench/go-queryx/db/queryx/delete.go delete mode 100644 internal/bench/go-queryx/db/queryx/delete_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/env.go delete mode 100644 internal/bench/go-queryx/db/queryx/float_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/insert.go delete mode 100644 internal/bench/go-queryx/db/queryx/insert_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/integer.go delete mode 100644 internal/bench/go-queryx/db/queryx/integer_column.go delete mode 100644 internal/bench/go-queryx/db/queryx/integer_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/json_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/logger.go delete mode 100644 internal/bench/go-queryx/db/queryx/model_change.go delete mode 100644 internal/bench/go-queryx/db/queryx/scan.go delete mode 100644 internal/bench/go-queryx/db/queryx/schema.go delete mode 100644 internal/bench/go-queryx/db/queryx/select.go delete mode 100644 internal/bench/go-queryx/db/queryx/select_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/string.go delete mode 100644 internal/bench/go-queryx/db/queryx/string_column.go delete mode 100644 internal/bench/go-queryx/db/queryx/string_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/table.go delete mode 100644 internal/bench/go-queryx/db/queryx/time_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/update.go delete mode 100644 internal/bench/go-queryx/db/queryx/update_test.go delete mode 100644 internal/bench/go-queryx/db/queryx/uuid_test.go diff --git a/internal/bench/go-queryx/db/errors.go b/internal/bench/go-queryx/db/errors.go deleted file mode 100644 index a74d06ff..00000000 --- a/internal/bench/go-queryx/db/errors.go +++ /dev/null @@ -1,7 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package db - -import "errors" - -var ErrInsertAllEmptyChanges = errors.New("queryx: insert all with empty changes") diff --git a/internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql b/internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql deleted file mode 100644 index 5100e91c..00000000 --- a/internal/bench/go-queryx/db/migrations/20240118175745_auto.down.sql +++ /dev/null @@ -1 +0,0 @@ -DROP TABLE "public"."models" \ No newline at end of file diff --git a/internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql b/internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql deleted file mode 100644 index 28d15e4f..00000000 --- a/internal/bench/go-queryx/db/migrations/20240118175745_auto.up.sql +++ /dev/null @@ -1 +0,0 @@ -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")); \ No newline at end of file diff --git a/internal/bench/go-queryx/db/model.go b/internal/bench/go-queryx/db/model.go deleted file mode 100644 index 26f7f571..00000000 --- a/internal/bench/go-queryx/db/model.go +++ /dev/null @@ -1,91 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package db - -import ( - "fmt" - "strings" - - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" -) - -type Model struct { - ID int64 `json:"id" db:"id"` - Name queryx.String `json:"name" db:"name"` - Title queryx.String `json:"title" db:"title"` - Fax queryx.String `json:"fax" db:"fax"` - Web queryx.String `json:"web" db:"web"` - Age queryx.BigInt `json:"age" db:"age"` - Righ queryx.Boolean `json:"righ" db:"righ"` - Counter queryx.Integer `json:"counter" db:"counter"` - - schema *queryx.Schema - queries Queries -} - -// String implements the stringer interface. -func (m *Model) String() string { - var sb strings.Builder - sb.WriteString("(Model ") - sb.WriteString(fmt.Sprintf("id: %v", m.ID)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("name: %s", m.Name)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("title: %s", m.Title)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("fax: %s", m.Fax)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("web: %s", m.Web)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("age: %s", m.Age)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("righ: %s", m.Righ)) - sb.WriteString(", ") - sb.WriteString(fmt.Sprintf("counter: %s", m.Counter)) - sb.WriteString(")") - return sb.String() -} - -func (m *Model) applyChange(change *queryx.ModelChange) error { - if change == nil { - return nil - } - if change.ID.Set { - m.ID = change.ID.Val - } - if change.Name.Set { - m.Name = change.Name - } - if change.Title.Set { - m.Title = change.Title - } - if change.Fax.Set { - m.Fax = change.Fax - } - if change.Web.Set { - m.Web = change.Web - } - if change.Age.Set { - m.Age = change.Age - } - if change.Righ.Set { - m.Righ = change.Righ - } - if change.Counter.Set { - m.Counter = change.Counter - } - return nil -} -func (m *Model) Update(change *queryx.ModelChange) error { - _, err := m.queries.QueryModel().Where(m.schema.And(m.schema.ModelID.EQ(m.ID))).UpdateAll(change) - if err != nil { - return err - } - - return m.applyChange(change) -} - -func (m *Model) Delete() error { - _, err := m.queries.QueryModel().Delete(m.ID) - return err -} diff --git a/internal/bench/go-queryx/db/model_query.go b/internal/bench/go-queryx/db/model_query.go deleted file mode 100644 index baee73d4..00000000 --- a/internal/bench/go-queryx/db/model_query.go +++ /dev/null @@ -1,297 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package db - -import ( - "database/sql" - "errors" - "fmt" - - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" -) - -type ModelQuery struct { - adapter *queryx.Adapter - schema *queryx.Schema - queries Queries - selectStatement *queryx.SelectStatement - preload map[string]bool - err error -} - -func NewModelQuery(adapter *queryx.Adapter, schema *queryx.Schema, queries Queries) *ModelQuery { - s := queryx.NewSelect().Select("models.*").From("models") - return &ModelQuery{ - adapter: adapter, - schema: schema, - queries: queries, - selectStatement: s, - preload: make(map[string]bool), - } -} - -func (q *ModelQuery) Create(change *queryx.ModelChange) (*Model, error) { - if q.err != nil { - return nil, q.err - } - - record := &Model{ - schema: q.schema, - queries: q.queries, - } - columns, values := change.Changes() - query, args := queryx.NewInsert(). - Into("models"). - Columns(columns...). - Values(values...). - Returning("*").ToSQL() - err := q.adapter.QueryOne(query, args...).Scan(record) - if err != nil { - return nil, err - } - - return record, nil -} - -func (q *ModelQuery) InsertAll(changes []*queryx.ModelChange) (int64, error) { - if q.err != nil { - return 0, q.err - } - - if len(changes) == 0 { - return 0, ErrInsertAllEmptyChanges - } - - s := queryx.NewInsert().Into("models") - for i, change := range changes { - columns, values := change.Changes() - if i == 0 { - s.Columns(columns...) - } - s.Values(values...) - } - - query, args := s.ToSQL() - return q.adapter.Exec(query, args...) -} - -func (q *ModelQuery) Delete(id int64) (int64, error) { - query, args := queryx.NewDelete().From("models").Where(q.schema.ModelID.EQ(id)).ToSQL() - result, err := q.adapter.Exec(query, args...) - if err != nil { - return 0, err - } - return result, err -} - -func (q *ModelQuery) Find(id int64) (*Model, error) { - res, err := q.Where(q.schema.ModelID.EQ(id)).First() - if err != nil { - return nil, err - } - if res == nil { - return nil, sql.ErrNoRows - } - res.schema = q.schema - res.queries = q.queries - return res, err -} - -func (q *ModelQuery) FindBy(where *queryx.Clause) (*Model, error) { - return q.Where(where).First() -} - -func (q *ModelQuery) FindBySQL(query string, args ...interface{}) ([]*Model, error) { - var modelList []Model - models := make([]*Model, 0) - err := q.adapter.Query(query, args...).Scan(&modelList) - if err != nil { - return nil, err - } - for i := 0; i < len(modelList); i++ { - models = append(models, &modelList[i]) - } - return models, nil -} - -func (q *ModelQuery) Where(clauses ...*queryx.Clause) *ModelQuery { - q.selectStatement.Where(clauses...) - return q -} - -func (q *ModelQuery) Select(selection ...string) *ModelQuery { - q.selectStatement.Select(selection...) - return q -} - -func (q *ModelQuery) Limit(limit int) *ModelQuery { - q.selectStatement.Limit(limit) - return q -} - -func (q *ModelQuery) Offset(offset int) *ModelQuery { - q.selectStatement.Offset(offset) - return q -} - -func (q *ModelQuery) Group(group string) *ModelQuery { - q.selectStatement.GroupBy(group) - return q -} - -func (q *ModelQuery) Having(having string) *ModelQuery { - q.selectStatement.Having(having) - return q -} - -func (q *ModelQuery) Joins(joins string) *ModelQuery { - q.selectStatement.Join(joins) - return q -} - -func (q *ModelQuery) Order(order ...string) *ModelQuery { - q.selectStatement.Order(order...) - return q -} - -func (q *ModelQuery) All() ([]*Model, error) { - if q.err != nil { - return nil, q.err - } - var rows []Model - models := make([]*Model, 0) - query, args := q.selectStatement.ToSQL() - err := q.adapter.Query(query, args...).Scan(&rows) - if err != nil { - return nil, err - } - - if len(rows) == 0 { - return models, nil - } - - for i := range rows { - rows[i].schema = q.schema - rows[i].queries = q.queries - models = append(models, &rows[i]) - } - - return models, nil -} - -func (q *ModelQuery) First() (*Model, error) { - q.Limit(1) - results, err := q.All() - if err != nil { - return nil, err - } - if len(results) > 0 { - return results[0], nil - } - - return nil, nil -} - -func (q *ModelQuery) Count() (int64, error) { - var res struct { - Count int64 `db:"count"` - } - q.selectStatement.Select("count(*)") - query, args := q.selectStatement.ToSQL() - if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { - return 0, err - } - - return res.Count, nil -} - -func (q *ModelQuery) Avg(v string) (float64, error) { - var res struct { - Avg sql.NullFloat64 `db:"avg"` - } - q.selectStatement.Select(fmt.Sprintf("avg(%+v)", v)) - query, args := q.selectStatement.ToSQL() - if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { - return 0, err - } - - return res.Avg.Float64, nil -} - -func (q *ModelQuery) Sum(v string) (float64, error) { - var res struct { - Sum sql.NullFloat64 `db:"sum"` - } - q.selectStatement.Select(fmt.Sprintf("sum(%+v)", v)) - query, args := q.selectStatement.ToSQL() - if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { - return 0, err - } - - return res.Sum.Float64, nil -} - -func (q *ModelQuery) Max(v string) (float64, error) { - var res struct { - Max sql.NullFloat64 `db:"max"` - } - q.selectStatement.Select(fmt.Sprintf("max(%+v)", v)) - query, args := q.selectStatement.ToSQL() - if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { - return 0, err - } - - return res.Max.Float64, nil -} - -func (q *ModelQuery) Min(v string) (float64, error) { - var res struct { - Min sql.NullFloat64 `db:"min"` - } - q.selectStatement.Select(fmt.Sprintf("min(%+v)", v)) - query, args := q.selectStatement.ToSQL() - if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { - return 0, err - } - - return res.Min.Float64, nil -} - -func (q *ModelQuery) Exists() (bool, error) { - q.selectStatement.Select("1 AS one").Limit(1) - // select 1 as one from users limit 1 - query, args := q.selectStatement.ToSQL() - var res struct { - One int64 `db:"one"` - } - if err := q.adapter.QueryOne(query, args...).Scan(&res); err != nil { - if errors.Is(err, sql.ErrNoRows) { - return false, nil - } - return false, err - } - - return res.One == 1, nil -} - -func (q *ModelQuery) UpdateAll(change *queryx.ModelChange) (int64, error) { - if q.err != nil { - return 0, q.err - } - columns, values := change.Changes() - query, args := q.selectStatement.Update().Columns(columns...).Values(values...).ToSQL() - result, err := q.adapter.Exec(query, args...) - if err != nil { - return 0, err - } - return result, err -} - -func (q *ModelQuery) DeleteAll() (int64, error) { - query, args := q.selectStatement.Delete().ToSQL() - result, err := q.adapter.Exec(query, args...) - if err != nil { - return 0, err - } - return result, err -} diff --git a/internal/bench/go-queryx/db/queryx.go b/internal/bench/go-queryx/db/queryx.go deleted file mode 100644 index 80260fde..00000000 --- a/internal/bench/go-queryx/db/queryx.go +++ /dev/null @@ -1,120 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package db - -import ( - "context" - "database/sql" - "fmt" - "log" - "os" - - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" -) - -type Queries interface { - QueryModel() *ModelQuery -} - -type QXClient struct { - db *sql.DB - config *queryx.Config - logger queryx.Logger - *queryx.Adapter - *queryx.Schema -} - -func NewClient() (*QXClient, error) { - env := os.Getenv("QUERYX_ENV") - if env == "" { - env = "development" - } - return NewClientWithEnv(env) -} - -func NewClientWithEnv(env string) (*QXClient, error) { - config := queryx.NewConfig(env) - if config == nil { - return nil, fmt.Errorf("client config is missing for %s", env) - } - db, err := sql.Open("postgres", config.URL) - if err != nil { - return nil, err - } - - client := &QXClient{ - db: db, - config: config, - Adapter: queryx.NewAdapter(db), - Schema: queryx.NewSchema(), - } - client.setDefaultLogger() - - return client, nil -} - -func (c *QXClient) SetLogger(logger queryx.Logger) { - c.logger = logger -} - -func (c *QXClient) setDefaultLogger() { - c.logger = log.New(os.Stderr, "sql ", log.Llongfile|log.LstdFlags) -} - -func (c *QXClient) QueryModel() *ModelQuery { - return NewModelQuery(c.Adapter, c.Schema, c) -} - -func (c *QXClient) Transaction(f func(t *Tx) error) error { - tx, err := c.Tx() - if err != nil { - return err - } - defer tx.Rollback() - if err = f(tx); err != nil { - return err - } - return tx.Commit() -} - -func (c *QXClient) Raw(fragment string, args ...interface{}) *queryx.Clause { - return queryx.NewClause(fragment, args) -} - -type Tx struct { - *queryx.Schema - *queryx.Adapter - tx *sql.Tx - client *QXClient -} - -func (c *QXClient) Tx() (*Tx, error) { - ctx := context.Background() - tx, err := c.db.BeginTx(ctx, nil) - if err != nil { - return nil, err - } - - return &Tx{ - tx: tx, - Schema: c.Schema, - Adapter: queryx.NewAdapter(tx), - client: c, - }, nil -} - -func (tx *Tx) Commit() error { - return tx.tx.Commit() -} - -func (tx *Tx) Rollback() error { - return tx.tx.Rollback() -} - -func (tx *Tx) QueryModel() *ModelQuery { - return NewModelQuery(tx.Adapter, tx.Schema, tx) -} - -func (tx *Tx) Raw(fragment string, args ...interface{}) *queryx.Clause { - return queryx.NewClause(fragment, args) -} diff --git a/internal/bench/go-queryx/db/queryx/adapter.go b/internal/bench/go-queryx/db/queryx/adapter.go deleted file mode 100644 index 55eac2a7..00000000 --- a/internal/bench/go-queryx/db/queryx/adapter.go +++ /dev/null @@ -1,48 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "regexp" - "strconv" - "strings" - - _ "github.com/lib/pq" -) - -func (a *Adapter) Exec(query string, args ...interface{}) (int64, error) { - matched1, err := regexp.MatchString(`.* IN (.*?)`, query) - if err != nil { - return 0, err - } - matched2, err := regexp.MatchString(`.* in (.*?)`, query) - if err != nil { - return 0, err - } - if matched1 || matched2 { - query, args, err = In(query, args...) - if err != nil { - return 0, err - } - } - query, args = rebind(query, args) - result, err := a.db.Exec(query, args...) - if err != nil { - return 0, err - } - return result.RowsAffected() -} - -func rebind(query string, args []interface{}) (string, []interface{}) { - rqb := make([]byte, 0, len(query)+10) - var i, j int - for i = strings.Index(query, "?"); i != -1; i = strings.Index(query, "?") { - rqb = append(rqb, query[:i]...) - rqb = append(rqb, '$') - j++ - rqb = strconv.AppendInt(rqb, int64(j), 10) - query = query[i+1:] - } - query = string(append(rqb, query...)) - return query, args -} diff --git a/internal/bench/go-queryx/db/queryx/adapter_test.go b/internal/bench/go-queryx/db/queryx/adapter_test.go deleted file mode 100644 index 07fea4be..00000000 --- a/internal/bench/go-queryx/db/queryx/adapter_test.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestRebind(t *testing.T) { - sql, args := rebind("a ? b ?", []interface{}{1, 2}) - require.Equal(t, "a $1 b $2", sql) - require.Equal(t, []interface{}{1, 2}, args) -} diff --git a/internal/bench/go-queryx/db/queryx/bigint.go b/internal/bench/go-queryx/db/queryx/bigint.go deleted file mode 100644 index 1d58235d..00000000 --- a/internal/bench/go-queryx/db/queryx/bigint.go +++ /dev/null @@ -1,75 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" -) - -type BigInt struct { - Val int64 - Valid bool - Set bool -} - -func NewBigInt(v int64) BigInt { - return BigInt{Val: v, Valid: true, Set: true} -} - -func NewNullableBigInt(v *int64) BigInt { - if v != nil { - return NewBigInt(*v) - } - return BigInt{Set: true} -} - -// Scan implements the Scanner interface. -func (b *BigInt) Scan(value interface{}) error { - n := sql.NullInt64{} - err := n.Scan(value) - if err != nil { - return err - } - b.Val, b.Valid = n.Int64, n.Valid - return nil -} - -// Value implements the driver Valuer interface. -func (b BigInt) Value() (driver.Value, error) { - if !b.Valid { - return nil, nil - } - return b.Val, nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (b BigInt) MarshalJSON() ([]byte, error) { - if !b.Valid { - return json.Marshal(nil) - } - return json.Marshal(b.Val) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (b *BigInt) UnmarshalJSON(data []byte) error { - b.Set = true - if string(data) == "null" { - return nil - } - b.Valid = true - if err := json.Unmarshal(data, &b.Val); err != nil { - return err - } - return nil -} - -// String implements the stringer interface. -func (b BigInt) String() string { - if !b.Valid { - return "null" - } - return strconv.FormatInt(b.Val, 10) -} diff --git a/internal/bench/go-queryx/db/queryx/bigint_column.go b/internal/bench/go-queryx/db/queryx/bigint_column.go deleted file mode 100644 index 8682bd2a..00000000 --- a/internal/bench/go-queryx/db/queryx/bigint_column.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import "fmt" - -type BigIntColumn struct { - Name string - Table *Table -} - -func (t *Table) NewBigIntColumn(name string) *BigIntColumn { - return &BigIntColumn{ - Table: t, - Name: name, - } -} - -func (c *BigIntColumn) EQ(v int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) NE(v int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) LT(v int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s < ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) GT(v int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s > ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) LE(v int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s <= ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) GE(v int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s >= ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) In(v []int64) *Clause { - if len(v) == 0 { - return &Clause{ - fragment: "1=0", - } - } - return &Clause{ - fragment: fmt.Sprintf("%s.%s IN (?)", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BigIntColumn) InRange(start int64, end int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s >= ? and %s.%s< ?", c.Table.Name, c.Name, c.Table.Name, c.Name), - args: []interface{}{start, end}, - } -} - -func (c *BigIntColumn) Between(start int64, end int64) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s >= ? and %s.%s<= ?", c.Table.Name, c.Name, c.Table.Name, c.Name), - args: []interface{}{start, end}, - } -} - -func (c *BigIntColumn) Asc() string { - return fmt.Sprintf("%s.%s ASC", c.Table.Name, c.Name) -} - -func (c *BigIntColumn) Desc() string { - return fmt.Sprintf("%s.%s DESC", c.Table.Name, c.Name) -} diff --git a/internal/bench/go-queryx/db/queryx/bigint_test.go b/internal/bench/go-queryx/db/queryx/bigint_test.go deleted file mode 100644 index 1500f356..00000000 --- a/internal/bench/go-queryx/db/queryx/bigint_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewBigInt(t *testing.T) { - b1 := NewBigInt(2) - require.Equal(t, int64(2), b1.Val) - require.True(t, b1.Valid) - - b2 := NewNullableBigInt(nil) - require.False(t, b2.Valid) -} - -func TestBigIntJSON(t *testing.T) { - type Foo struct { - X BigInt `json:"x"` - Y BigInt `json:"y"` - } - x := NewBigInt(2) - y := NewNullableBigInt(nil) - s := `{"x":2,"y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/bind.go b/internal/bench/go-queryx/db/queryx/bind.go deleted file mode 100644 index d248e8db..00000000 --- a/internal/bench/go-queryx/db/queryx/bind.go +++ /dev/null @@ -1,167 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql/driver" - "fmt" - "reflect" - "strings" -) - -// In expands slice values in args, returning the modified query string -// and a new arg list that can be executed by a database. The `query` should -// use the `?` bindVar. The return value uses the `?` bindVar. -func In(query string, args ...interface{}) (string, []interface{}, error) { - // argMeta stores reflect.Value and length for slices and - // the value itself for non-slice arguments - type argMeta struct { - v reflect.Value - i interface{} - length int - } - - var flatArgsCount int - var anySlices bool - - var stackMeta [32]argMeta - - var meta []argMeta - if len(args) <= len(stackMeta) { - meta = stackMeta[:len(args)] - } else { - meta = make([]argMeta, len(args)) - } - - for i, arg := range args { - if a, ok := arg.(driver.Valuer); ok { - var err error - arg, err = a.Value() - if err != nil { - return "", nil, err - } - } - - if v, ok := asSliceForIn(arg); ok { - meta[i].length = v.Len() - meta[i].v = v - - anySlices = true - flatArgsCount += meta[i].length - - if meta[i].length == 0 { - return "", nil, fmt.Errorf("empty slice passed to 'in' query") - } - } else { - meta[i].i = arg - flatArgsCount++ - } - } - - // don't do any parsing if there aren't any slices; note that this means - // some errors that we might have caught below will not be returned. - if !anySlices { - return query, args, nil - } - - newArgs := make([]interface{}, 0, flatArgsCount) - - var buf strings.Builder - buf.Grow(len(query) + len(", ?")*flatArgsCount) - - var arg, offset int - - for i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') { - if arg >= len(meta) { - // if an argument wasn't passed, lets return an error; this is - // not actually how database/sql Exec/Query works, but since we are - // creating an argument list programmatically, we want to be able - // to catch these programmer errors earlier. - return "", nil, fmt.Errorf("number of bindVars exceeds arguments") - } - - argMeta := meta[arg] - arg++ - - // not a slice, continue. - // our questionmark will either be written before the next expansion - // of a slice or after the loop when writing the rest of the query - if argMeta.length == 0 { - offset = offset + i + 1 - newArgs = append(newArgs, argMeta.i) - continue - } - - // write everything up to and including our ? character - buf.WriteString(query[:offset+i+1]) - - for si := 1; si < argMeta.length; si++ { - buf.WriteString(", ?") - } - - newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length) - - // slice the query and reset the offset. this avoids some bookkeeping for - // the write after the loop - query = query[offset+i+1:] - offset = 0 - } - - buf.WriteString(query) - - if arg < len(meta) { - return "", nil, fmt.Errorf("number of bindVars less than number arguments") - } - - return buf.String(), newArgs, nil -} -func asSliceForIn(i interface{}) (v reflect.Value, ok bool) { - if i == nil { - return reflect.Value{}, false - } - - v = reflect.ValueOf(i) - t := Deref(v.Type()) - - // Only expand slices - if t.Kind() != reflect.Slice { - return reflect.Value{}, false - } - - // []byte is a driver.Value type so it should not be expanded - if t == reflect.TypeOf([]byte{}) { - return reflect.Value{}, false - - } - - return v, true -} - -// Deref is Indirect for reflect.Types -func Deref(t reflect.Type) reflect.Type { - if t.Kind() == reflect.Ptr { - t = t.Elem() - } - return t -} - -func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} { - switch val := v.Interface().(type) { - case []interface{}: - args = append(args, val...) - case []int: - for i := range val { - args = append(args, val[i]) - } - case []string: - for i := range val { - args = append(args, val[i]) - } - default: - for si := 0; si < vlen; si++ { - args = append(args, v.Index(si).Interface()) - } - } - - return args -} diff --git a/internal/bench/go-queryx/db/queryx/boolean.go b/internal/bench/go-queryx/db/queryx/boolean.go deleted file mode 100644 index 388d2e95..00000000 --- a/internal/bench/go-queryx/db/queryx/boolean.go +++ /dev/null @@ -1,77 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" -) - -type Boolean struct { - Val bool - Valid bool - Set bool -} - -func NewBoolean(v bool) Boolean { - return Boolean{Val: v, Valid: true, Set: true} -} - -func NewNullableBoolean(v *bool) Boolean { - if v != nil { - return NewBoolean(*v) - } - return Boolean{Set: true} -} - -// Scan implements the Scanner interface. -func (b *Boolean) Scan(value interface{}) error { - n := sql.NullBool{} - err := n.Scan(value) - if err != nil { - return err - } - b.Val, b.Valid = n.Bool, n.Valid - return nil -} - -// Value implements the driver Valuer interface. -func (b Boolean) Value() (driver.Value, error) { - if !b.Valid { - return nil, nil - } - return b.Val, nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (b Boolean) MarshalJSON() ([]byte, error) { - if !b.Valid { - return json.Marshal(nil) - } - return json.Marshal(b.Val) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (b *Boolean) UnmarshalJSON(data []byte) error { - b.Set = true - if string(data) == "null" { - return nil - } - b.Valid = true - if err := json.Unmarshal(data, &b.Val); err != nil { - return err - } - return nil -} - -// String implements the stringer interface. -func (b Boolean) String() string { - if !b.Valid { - return "null" - } - if b.Val { - return "true" - } - return "false" -} diff --git a/internal/bench/go-queryx/db/queryx/boolean_column.go b/internal/bench/go-queryx/db/queryx/boolean_column.go deleted file mode 100644 index 72764e3e..00000000 --- a/internal/bench/go-queryx/db/queryx/boolean_column.go +++ /dev/null @@ -1,39 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import "fmt" - -type BooleanColumn struct { - Name string - Table *Table -} - -func (t *Table) NewBooleanColumn(name string) *BooleanColumn { - return &BooleanColumn{ - Table: t, - Name: name, - } -} - -func (c *BooleanColumn) EQ(v bool) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *BooleanColumn) NE(v bool) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (b *BooleanColumn) Asc() string { - return fmt.Sprintf("%s.%s ASC", b.Table.Name, b.Name) -} - -func (b *BooleanColumn) Desc() string { - return fmt.Sprintf("%s.%s DESC", b.Table.Name, b.Name) -} diff --git a/internal/bench/go-queryx/db/queryx/boolean_test.go b/internal/bench/go-queryx/db/queryx/boolean_test.go deleted file mode 100644 index 31a8fb62..00000000 --- a/internal/bench/go-queryx/db/queryx/boolean_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewBoolean(t *testing.T) { - b1 := NewBoolean(true) - require.Equal(t, true, b1.Val) - require.True(t, b1.Valid) - - b2 := NewNullableBoolean(nil) - require.False(t, b2.Valid) -} - -func TestBooleanJSON(t *testing.T) { - type Foo struct { - X Boolean `json:"x"` - Y Boolean `json:"y"` - } - x := NewBoolean(true) - y := NewNullableBoolean(nil) - s := `{"x":true,"y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/clause.go b/internal/bench/go-queryx/db/queryx/clause.go deleted file mode 100644 index a5b03575..00000000 --- a/internal/bench/go-queryx/db/queryx/clause.go +++ /dev/null @@ -1,57 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "fmt" - "strings" -) - -type Clause struct { - fragment string - args []interface{} - err error -} - -func NewClause(fragment string, args []interface{}) *Clause { - return &Clause{ - fragment: fragment, - args: args, - } -} - -func (c *Clause) Err() error { - return c.err -} - -func (c *Clause) And(clauses ...*Clause) *Clause { - if len(clauses) == 0 { - return c - } - - var fragments []string - var args []interface{} - clauses = append([]*Clause{c}, clauses...) - for _, clause := range clauses { - fragments = append(fragments, fmt.Sprintf("(%s)", clause.fragment)) - args = append(args, clause.args...) - } - - return NewClause(strings.Join(fragments, " AND "), args) -} - -func (c *Clause) Or(clauses ...*Clause) *Clause { - if len(clauses) == 0 { - return c - } - - var fragments []string - var args []interface{} - clauses = append([]*Clause{c}, clauses...) - for _, clause := range clauses { - fragments = append(fragments, fmt.Sprintf("(%s)", clause.fragment)) - args = append(args, clause.args...) - } - - return NewClause(strings.Join(fragments, " OR "), args) -} diff --git a/internal/bench/go-queryx/db/queryx/clause_test.go b/internal/bench/go-queryx/db/queryx/clause_test.go deleted file mode 100644 index b7d548cb..00000000 --- a/internal/bench/go-queryx/db/queryx/clause_test.go +++ /dev/null @@ -1,37 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestClauseAddOr(t *testing.T) { - c1 := &Clause{ - fragment: "a = ?", - args: []interface{}{1}, - } - c2 := &Clause{ - fragment: "b = ?", - args: []interface{}{"x"}, - } - - c3 := c1.And(c2) - require.Equal(t, "(a = ?) AND (b = ?)", c3.fragment) - require.Equal(t, []interface{}{1, "x"}, c3.args) - - c4 := c1.Or(c2) - require.Equal(t, "(a = ?) OR (b = ?)", c4.fragment) - require.Equal(t, []interface{}{1, "x"}, c4.args) - - c5 := c1.And(c1.Or(c2)) - require.Equal(t, "(a = ?) AND ((a = ?) OR (b = ?))", c5.fragment) - require.Equal(t, []interface{}{1, 1, "x"}, c5.args) - - require.Equal(t, "a = ?", c1.fragment) - require.Equal(t, []interface{}{1}, c1.args) - require.Equal(t, "b = ?", c2.fragment) - require.Equal(t, []interface{}{"x"}, c2.args) -} diff --git a/internal/bench/go-queryx/db/queryx/config.go b/internal/bench/go-queryx/db/queryx/config.go deleted file mode 100644 index a430ec80..00000000 --- a/internal/bench/go-queryx/db/queryx/config.go +++ /dev/null @@ -1,26 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import () - -type Config struct { - URL string -} - -func NewConfig(env string) *Config { - switch env { - case "development": - return &Config{ - URL: fixURL("postgresql://postgres:postgres@localhost:5432/test?sslmode=disable"), - } - case "test": - return &Config{ - URL: fixURL(getenv("DATABASE_URL")), - } - } - return nil -} -func fixURL(rawURL string) string { - return rawURL -} diff --git a/internal/bench/go-queryx/db/queryx/date_test.go b/internal/bench/go-queryx/db/queryx/date_test.go deleted file mode 100644 index b45d5cfc..00000000 --- a/internal/bench/go-queryx/db/queryx/date_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewDate(t *testing.T) { - d1 := NewDate("2012-11-10") - require.Equal(t, "2012-11-10", d1.Val.Format("2006-01-02")) - require.True(t, d1.Valid) - - d2 := NewNullableDate(nil) - require.False(t, d2.Valid) -} - -func TestDateJSON(t *testing.T) { - type Foo struct { - X Date `json:"x"` - Y Date `json:"y"` - } - x := NewDate("2012-11-10") - y := NewNullableDate(nil) - s := `{"x":"2012-11-10","y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/datetime_test.go b/internal/bench/go-queryx/db/queryx/datetime_test.go deleted file mode 100644 index 824edf32..00000000 --- a/internal/bench/go-queryx/db/queryx/datetime_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewDatetime(t *testing.T) { - d1 := NewDatetime("2012-12-12 11:10:09") - require.Equal(t, "2012-12-12 11:10:09", d1.Val.Format("2006-01-02 15:04:05")) - require.True(t, d1.Valid) - - d2 := NewNullableDatetime(nil) - require.False(t, d2.Valid) -} - -func TestDatetimeJSON(t *testing.T) { - type Foo struct { - X Datetime `json:"x"` - Y Datetime `json:"y"` - } - x := NewDatetime("2012-12-12 11:10:09") - y := NewNullableDatetime(nil) - s := `{"x":"2012-12-12T03:10:09Z","y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/db.go b/internal/bench/go-queryx/db/queryx/db.go deleted file mode 100644 index f37b7902..00000000 --- a/internal/bench/go-queryx/db/queryx/db.go +++ /dev/null @@ -1,110 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql" - "regexp" -) - -type DB interface { - Exec(query string, args ...interface{}) (sql.Result, error) - Query(query string, args ...interface{}) (*sql.Rows, error) -} - -type Adapter struct { - db DB -} - -func NewAdapter(db DB) *Adapter { - return &Adapter{db: db} -} - -func (a *Adapter) Query(query string, args ...interface{}) *Rows { - return &Rows{ - adapter: a, - query: query, - args: args, - } -} - -type Rows struct { - adapter *Adapter - query string - args []interface{} - err error -} - -func (r *Rows) Scan(v interface{}) error { - if r.err != nil { - return r.err - } - var err error - query, args := r.query, r.args - matched1, err := regexp.MatchString(`.* IN (.*?)`, query) - if err != nil { - return err - } - matched2, err := regexp.MatchString(`.* in (.*?)`, query) - if err != nil { - return err - } - if matched1 || matched2 { - query, args, err = In(query, args...) - if err != nil { - return err - } - } - query, args = rebind(query, args) - rows, err := r.adapter.db.Query(query, args...) - if err != nil { - return err - } - err = ScanSlice(rows, v) - if err != nil { - return err - } - return err -} - -type Row struct { - adapter *Adapter - query string - args []interface{} -} - -func (r *Row) Scan(v interface{}) error { - query, args := r.query, r.args - matched1, err := regexp.MatchString(`.* IN (.*?)`, query) - if err != nil { - return err - } - matched2, err := regexp.MatchString(`.* in (.*?)`, query) - if err != nil { - return err - } - if matched1 || matched2 { - query, args, err = In(query, args...) - if err != nil { - return err - } - } - query, args = rebind(query, args) - rows, err := r.adapter.db.Query(query, args...) - if err != nil { - return err - } - err = ScanOne(rows, v) - if err != nil { - return err - } - return err -} - -func (a *Adapter) QueryOne(query string, args ...interface{}) *Row { - return &Row{ - adapter: a, - query: query, - args: args, - } -} diff --git a/internal/bench/go-queryx/db/queryx/delete.go b/internal/bench/go-queryx/db/queryx/delete.go deleted file mode 100644 index 736b99df..00000000 --- a/internal/bench/go-queryx/db/queryx/delete.go +++ /dev/null @@ -1,36 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import "fmt" - -type DeleteStatemnet struct { - from string - where *Clause -} - -func NewDelete() *DeleteStatemnet { - return &DeleteStatemnet{} -} - -func (s *DeleteStatemnet) From(from string) *DeleteStatemnet { - s.from = from - return s -} - -func (s *DeleteStatemnet) Where(expr *Clause) *DeleteStatemnet { - s.where = expr - return s -} - -func (s *DeleteStatemnet) ToSQL() (string, []interface{}) { - sql, args := "", []interface{}{} - sql = fmt.Sprintf("DELETE FROM %s", s.from) - - if s.where != nil { - sql = fmt.Sprintf("%s WHERE %s", sql, s.where.fragment) - args = append(args, s.where.args...) - } - - return sql, args -} diff --git a/internal/bench/go-queryx/db/queryx/delete_test.go b/internal/bench/go-queryx/db/queryx/delete_test.go deleted file mode 100644 index 82f2d51e..00000000 --- a/internal/bench/go-queryx/db/queryx/delete_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package queryx - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewDelete(t *testing.T) { - s := NewDelete().From("users") - - sql, args := s.ToSQL() - require.Equal(t, "DELETE FROM users", sql) - require.Equal(t, []interface{}{}, args) -} diff --git a/internal/bench/go-queryx/db/queryx/env.go b/internal/bench/go-queryx/db/queryx/env.go deleted file mode 100644 index 79c79ec2..00000000 --- a/internal/bench/go-queryx/db/queryx/env.go +++ /dev/null @@ -1,7 +0,0 @@ -package queryx - -import "os" - -func getenv(k string) string { - return os.Getenv(k) -} diff --git a/internal/bench/go-queryx/db/queryx/float_test.go b/internal/bench/go-queryx/db/queryx/float_test.go deleted file mode 100644 index 5ff65740..00000000 --- a/internal/bench/go-queryx/db/queryx/float_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewFloat(t *testing.T) { - f1 := NewFloat(2.1) - require.Equal(t, 2.1, f1.Val) - require.True(t, f1.Valid) - - f2 := NewNullableFloat(nil) - require.False(t, f2.Valid) -} - -func TestFloatJSON(t *testing.T) { - type Foo struct { - X Float `json:"x"` - Y Float `json:"y"` - } - x := NewFloat(2.1) - y := NewNullableFloat(nil) - s := `{"x":2.1,"y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/insert.go b/internal/bench/go-queryx/db/queryx/insert.go deleted file mode 100644 index cf09926d..00000000 --- a/internal/bench/go-queryx/db/queryx/insert.go +++ /dev/null @@ -1,82 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "fmt" - "strings" -) - -type InsertStatement struct { - into string - columns []string - values [][]interface{} - returning []string - onConflict string -} - -func NewInsert() *InsertStatement { - return &InsertStatement{} -} - -func (s *InsertStatement) Into(into string) *InsertStatement { - s.into = into - return s -} - -func (s *InsertStatement) Columns(columns ...string) *InsertStatement { - s.columns = columns - return s -} - -func (s *InsertStatement) Values(values ...interface{}) *InsertStatement { - if len(values) > 0 { - s.values = append(s.values, values) - } - return s -} -func (s *InsertStatement) Returning(returning ...string) *InsertStatement { - s.returning = returning - return s -} - -func (s *InsertStatement) OnConflict(onConflict string) *InsertStatement { - s.onConflict = onConflict - return s -} - -func (s *InsertStatement) ToSQL() (string, []interface{}) { - sql := fmt.Sprintf("INSERT INTO %s", s.into) - - if len(s.columns) > 0 { - sql = fmt.Sprintf("%s(%s)", sql, strings.Join(s.columns, ", ")) - } else { - sql = fmt.Sprintf("%s DEFAULT VALUES", sql) - } - values := []string{} - for _, v := range s.values { - ss := []string{} - for range v { - ss = append(ss, "?") - } - values = append(values, fmt.Sprintf("(%s)", strings.Join(ss, ", "))) - } - if len(values) > 0 { - sql = fmt.Sprintf("%s VALUES %s", sql, strings.Join(values, ", ")) - } - - if len(s.returning) > 0 { - sql = fmt.Sprintf("%s RETURNING %s", sql, strings.Join(s.returning, ", ")) - } - - if s.onConflict != "" { - sql = fmt.Sprintf("%s %s", sql, s.onConflict) - } - - args := []interface{}{} - for _, v := range s.values { - args = append(args, v...) - } - - return sql, args -} diff --git a/internal/bench/go-queryx/db/queryx/insert_test.go b/internal/bench/go-queryx/db/queryx/insert_test.go deleted file mode 100644 index 6eb30653..00000000 --- a/internal/bench/go-queryx/db/queryx/insert_test.go +++ /dev/null @@ -1,33 +0,0 @@ -package queryx - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewInsert(t *testing.T) { - s1 := NewInsert().Into("users") - sql, args := s1.ToSQL() - require.Equal(t, "INSERT INTO users DEFAULT VALUES", sql) - require.Equal(t, []interface{}{}, args) - - var columns []string - var values []interface{} - s2 := NewInsert().Into("users").Columns(columns...).Values(values...).Returning("id", "name") - sql, args = s2.ToSQL() - require.Equal(t, "INSERT INTO users DEFAULT VALUES RETURNING id, name", sql) - require.Equal(t, []interface{}{}, args) - - s3 := NewInsert().Into("users").Columns("name", "email").Values("test", "test@example.com") - sql, args = s3.ToSQL() - require.Equal(t, "INSERT INTO users(name, email) VALUES (?, ?)", sql) - require.Equal(t, []interface{}{"test", "test@example.com"}, args) - - s4 := NewInsert().Into("users").Columns("name", "email"). - Values("test1", "test1@example.com"). - Values("test2", "test2@example.com") - sql, args = s4.ToSQL() - require.Equal(t, "INSERT INTO users(name, email) VALUES (?, ?), (?, ?)", sql) - require.Equal(t, []interface{}{"test1", "test1@example.com", "test2", "test2@example.com"}, args) -} diff --git a/internal/bench/go-queryx/db/queryx/integer.go b/internal/bench/go-queryx/db/queryx/integer.go deleted file mode 100644 index 060eb85c..00000000 --- a/internal/bench/go-queryx/db/queryx/integer.go +++ /dev/null @@ -1,78 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "strconv" -) - -type Integer struct { - Val int32 - Valid bool - Set bool -} - -func NewInteger(v int32) Integer { - return Integer{Val: v, Valid: true, Set: true} -} - -func NewNullableInteger(v *int32) Integer { - if v != nil { - return NewInteger(*v) - } - return Integer{Set: true} -} - -// Scan implements the Scanner interface. -func (i *Integer) Scan(value interface{}) error { - n := sql.NullInt64{} - err := n.Scan(value) - if err != nil { - return err - } - i.Val, i.Valid = int32(n.Int64), n.Valid - return nil -} - -// Value implements the driver Valuer interface. -func (i Integer) Value() (driver.Value, error) { - if !i.Valid { - return nil, nil - } - return int64(i.Val), nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (i Integer) MarshalJSON() ([]byte, error) { - if !i.Valid { - return json.Marshal(nil) - } - return json.Marshal(i.Val) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (i *Integer) UnmarshalJSON(data []byte) error { - i.Set = true - s := string(data) - if s == "null" { - return nil - } - i.Valid = true - p, err := strconv.ParseInt(s, 10, 32) - if err != nil { - return err - } - i.Val = int32(p) - return nil -} - -// String implements the stringer interface. -func (i Integer) String() string { - if !i.Valid { - return "null" - } - return strconv.Itoa(int(i.Val)) -} diff --git a/internal/bench/go-queryx/db/queryx/integer_column.go b/internal/bench/go-queryx/db/queryx/integer_column.go deleted file mode 100644 index 00d3e35f..00000000 --- a/internal/bench/go-queryx/db/queryx/integer_column.go +++ /dev/null @@ -1,88 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import "fmt" - -type IntegerColumn struct { - Name string - Table *Table -} - -func (t *Table) NewIntegerColumn(name string) *IntegerColumn { - return &IntegerColumn{ - Table: t, - Name: name, - } -} - -func (c *IntegerColumn) EQ(v int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) NE(v int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) LT(v int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s < ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) GT(v int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s > ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) LE(v int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s <= ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) GE(v int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s >= ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) In(v []int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s IN (?)", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *IntegerColumn) InRange(start int32, end int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s >= ? and %s.%s< ?", c.Table.Name, c.Name, c.Table.Name, c.Name), - args: []interface{}{start, end}, - } -} - -func (c *IntegerColumn) Between(start int32, end int32) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s >= ? and %s.%s<= ?", c.Table.Name, c.Name, c.Table.Name, c.Name), - args: []interface{}{start, end}, - } -} - -func (c *IntegerColumn) Asc() string { - return fmt.Sprintf("%s.%s ASC", c.Table.Name, c.Name) -} - -func (c *IntegerColumn) Desc() string { - return fmt.Sprintf("%s.%s DESC", c.Table.Name, c.Name) -} diff --git a/internal/bench/go-queryx/db/queryx/integer_test.go b/internal/bench/go-queryx/db/queryx/integer_test.go deleted file mode 100644 index 1a2c2ec3..00000000 --- a/internal/bench/go-queryx/db/queryx/integer_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewInteger(t *testing.T) { - i1 := NewInteger(2) - require.Equal(t, int32(2), i1.Val) - require.True(t, i1.Valid) - - i2 := NewNullableInteger(nil) - require.False(t, i2.Valid) -} - -func TestIntegerJSON(t *testing.T) { - type Foo struct { - X Integer `json:"x"` - Y Integer `json:"y"` - } - x := NewInteger(2) - y := NewNullableInteger(nil) - s := `{"x":2,"y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/json_test.go b/internal/bench/go-queryx/db/queryx/json_test.go deleted file mode 100644 index 39879002..00000000 --- a/internal/bench/go-queryx/db/queryx/json_test.go +++ /dev/null @@ -1,42 +0,0 @@ -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewJSON(t *testing.T) { - m := map[string]interface{}{"a": 1} - j1 := NewJSON(m) - require.Equal(t, m, j1.Val) - require.True(t, j1.Valid) - - j2 := NewNullableJSON(nil) - require.False(t, j2.Valid) - - j3 := NewNullableJSON(m) - require.True(t, j3.Valid) -} - -func TestJSONJSON(t *testing.T) { - type Foo struct { - X JSON `json:"x"` - Y JSON `json:"y"` - } - x := NewJSON(map[string]interface{}{"a": "b"}) - y := NewNullableJSON(nil) - s := `{"x":{"a":"b"},"y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/logger.go b/internal/bench/go-queryx/db/queryx/logger.go deleted file mode 100644 index 8d0fe04a..00000000 --- a/internal/bench/go-queryx/db/queryx/logger.go +++ /dev/null @@ -1,15 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -type Logger interface { - Print(v ...interface{}) - Printf(format string, v ...interface{}) - Println(v ...interface{}) - Panic(v ...interface{}) - Panicf(format string, v ...interface{}) - Panicln(v ...interface{}) - Fatal(v ...interface{}) - Fatalf(format string, v ...interface{}) - Fatalln(v ...interface{}) -} diff --git a/internal/bench/go-queryx/db/queryx/model_change.go b/internal/bench/go-queryx/db/queryx/model_change.go deleted file mode 100644 index 13eb90ca..00000000 --- a/internal/bench/go-queryx/db/queryx/model_change.go +++ /dev/null @@ -1,143 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -type ModelChange struct { - ID BigInt - Name String - Title String - Fax String - Web String - Age BigInt - Righ Boolean - Counter Integer -} - -func (c *ModelChange) Changes() (columns []string, values []interface{}) { - if c == nil { - return columns, values - } - if c.ID.Set { - columns = append(columns, "id") - values = append(values, c.ID) - } - if c.Name.Set { - columns = append(columns, "name") - values = append(values, c.Name) - } - if c.Title.Set { - columns = append(columns, "title") - values = append(values, c.Title) - } - if c.Fax.Set { - columns = append(columns, "fax") - values = append(values, c.Fax) - } - if c.Web.Set { - columns = append(columns, "web") - values = append(values, c.Web) - } - if c.Age.Set { - columns = append(columns, "age") - values = append(values, c.Age) - } - if c.Righ.Set { - columns = append(columns, "righ") - values = append(values, c.Righ) - } - if c.Counter.Set { - columns = append(columns, "counter") - values = append(values, c.Counter) - } - return columns, values -} - -func (c *ModelChange) SetID(id int64) *ModelChange { - c.ID = NewBigInt(id) - c.ID.Set = true - return c -} - -func (c *ModelChange) SetName(name string) *ModelChange { - c.Name = NewString(name) - c.Name.Set = true - return c -} - -func (c *ModelChange) SetNullableName(name *string) *ModelChange { - c.Name = NewNullableString(name) - c.Name.Set = true - return c -} - -func (c *ModelChange) SetTitle(title string) *ModelChange { - c.Title = NewString(title) - c.Title.Set = true - return c -} - -func (c *ModelChange) SetNullableTitle(title *string) *ModelChange { - c.Title = NewNullableString(title) - c.Title.Set = true - return c -} - -func (c *ModelChange) SetFax(fax string) *ModelChange { - c.Fax = NewString(fax) - c.Fax.Set = true - return c -} - -func (c *ModelChange) SetNullableFax(fax *string) *ModelChange { - c.Fax = NewNullableString(fax) - c.Fax.Set = true - return c -} - -func (c *ModelChange) SetWeb(web string) *ModelChange { - c.Web = NewString(web) - c.Web.Set = true - return c -} - -func (c *ModelChange) SetNullableWeb(web *string) *ModelChange { - c.Web = NewNullableString(web) - c.Web.Set = true - return c -} - -func (c *ModelChange) SetAge(age int64) *ModelChange { - c.Age = NewBigInt(age) - c.Age.Set = true - return c -} - -func (c *ModelChange) SetNullableAge(age *int64) *ModelChange { - c.Age = NewNullableBigInt(age) - c.Age.Set = true - return c -} - -func (c *ModelChange) SetRigh(righ bool) *ModelChange { - c.Righ = NewBoolean(righ) - c.Righ.Set = true - return c -} - -func (c *ModelChange) SetNullableRigh(righ *bool) *ModelChange { - c.Righ = NewNullableBoolean(righ) - c.Righ.Set = true - return c -} - -func (c *ModelChange) SetCounter(counter int32) *ModelChange { - c.Counter = NewInteger(counter) - c.Counter.Set = true - return c -} - -func (c *ModelChange) SetNullableCounter(counter *int32) *ModelChange { - c.Counter = NewNullableInteger(counter) - c.Counter.Set = true - return c -} diff --git a/internal/bench/go-queryx/db/queryx/scan.go b/internal/bench/go-queryx/db/queryx/scan.go deleted file mode 100644 index 4dde2a11..00000000 --- a/internal/bench/go-queryx/db/queryx/scan.go +++ /dev/null @@ -1,135 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql" - "fmt" - "reflect" - "strings" -) - -func ScanOne(rows *sql.Rows, v interface{}) error { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return fmt.Errorf("must pass pointer") - } - - columns, err := rows.Columns() - if err != nil { - return err - } - - typ := rv.Type().Elem() - - // column -> index - names := make(map[string]int, typ.NumField()) - for i := 0; i < typ.NumField(); i++ { - f := typ.Field(i) - names[columnName(f)] = i - } - - if !rows.Next() { - return sql.ErrNoRows - } - - indexes := make(map[int]int, typ.NumField()) - for i, c := range columns { - name := strings.ToLower(strings.Split(c, "(")[0]) - index, ok := names[name] - if !ok { - return fmt.Errorf("name not found") - } - indexes[i] = index - } - - values := make([]interface{}, len(columns)) - for i := range columns { - t := typ.Field(indexes[i]).Type - values[i] = reflect.New(t).Interface() - - } - - // scan into interfaces - if err := rows.Scan(values...); err != nil { - return err - } - - for i, v := range values { - reflect.Indirect(rv).Field(indexes[i]).Set(reflect.Indirect(reflect.ValueOf(v))) - } - - if rows.Next() { - return fmt.Errorf("more than one row") - } - - return nil -} - -func ScanSlice(rows *sql.Rows, v interface{}) error { - rv := reflect.ValueOf(v) - if rv.Kind() != reflect.Ptr { - return fmt.Errorf("must pass pointer") - } - - rv = reflect.Indirect(rv) - if k := rv.Kind(); k != reflect.Slice { - return fmt.Errorf("must pass slice") - } - - columns, err := rows.Columns() - if err != nil { - return err - } - - typ := rv.Type().Elem() - - names := make(map[string]int, typ.NumField()) - for i := 0; i < typ.NumField(); i++ { - f := typ.Field(i) - names[columnName(f)] = i - } - - indexes := make(map[int]int, typ.NumField()) - for i, c := range columns { - name := strings.ToLower(strings.Split(c, "(")[0]) - index, ok := names[name] - if !ok { - return fmt.Errorf("name %+v not found", name) - } - indexes[i] = index - } - - for rows.Next() { - values := make([]interface{}, len(columns)) - for i := range columns { - t := typ.Field(indexes[i]).Type - values[i] = reflect.New(t).Interface() - } - - // scan into interfaces - if err := rows.Scan(values...); err != nil { - return err - } - - // convert to reflect.Value - e := reflect.New(typ).Elem() - for i, v := range values { - fv := e.Field(indexes[i]) - fv.Set(reflect.Indirect(reflect.ValueOf(v))) - } - - vv := reflect.Append(rv, e) - rv.Set(vv) - } - - return nil -} - -func columnName(f reflect.StructField) string { - name := strings.ToLower(f.Name) - if tag, ok := f.Tag.Lookup("db"); ok { - name = tag - } - return name -} diff --git a/internal/bench/go-queryx/db/queryx/schema.go b/internal/bench/go-queryx/db/queryx/schema.go deleted file mode 100644 index af30619f..00000000 --- a/internal/bench/go-queryx/db/queryx/schema.go +++ /dev/null @@ -1,52 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -type Schema struct { - Model *Table - ModelID *BigIntColumn - ModelName *StringColumn - ModelTitle *StringColumn - ModelFax *StringColumn - ModelWeb *StringColumn - ModelAge *BigIntColumn - ModelRigh *BooleanColumn - ModelCounter *IntegerColumn -} - -func NewSchema() *Schema { - model := NewTable("models") - - return &Schema{ - Model: model, - ModelID: model.NewBigIntColumn("id"), - ModelName: model.NewStringColumn("name"), - ModelTitle: model.NewStringColumn("title"), - ModelFax: model.NewStringColumn("fax"), - ModelWeb: model.NewStringColumn("web"), - ModelAge: model.NewBigIntColumn("age"), - ModelRigh: model.NewBooleanColumn("righ"), - ModelCounter: model.NewIntegerColumn("counter"), - } -} - -func (s *Schema) And(clauses ...*Clause) *Clause { - return clauses[0].And(clauses[1:]...) -} - -func (s *Schema) Or(clauses ...*Clause) *Clause { - return clauses[0].Or(clauses[1:]...) -} - -func (s *Schema) ChangeModel() *ModelChange { - return &ModelChange{ - ID: BigInt{}, - Name: String{}, - Title: String{}, - Fax: String{}, - Web: String{}, - Age: BigInt{}, - Righ: Boolean{}, - Counter: Integer{}, - } -} diff --git a/internal/bench/go-queryx/db/queryx/select.go b/internal/bench/go-queryx/db/queryx/select.go deleted file mode 100644 index fec8eeb8..00000000 --- a/internal/bench/go-queryx/db/queryx/select.go +++ /dev/null @@ -1,142 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "fmt" - "strings" -) - -type SelectStatement struct { - selection []string - from string - where *Clause - limit *int - offset *int - order []string - group string - having string - distinct []string - joins []string -} - -func NewSelect() *SelectStatement { - return &SelectStatement{} -} - -func (s *SelectStatement) Select(selection ...string) *SelectStatement { - s.selection = selection - return s -} - -func (s *SelectStatement) From(from string) *SelectStatement { - s.from = from - return s -} - -func (s *SelectStatement) Where(clauses ...*Clause) *SelectStatement { - if len(clauses) == 0 { - return s - } - - if s.where == nil { - s.where = clauses[0].And(clauses[1:]...) - } else { - s.where = s.where.And(clauses...) - } - - return s -} - -func (s *SelectStatement) Limit(limit int) *SelectStatement { - s.limit = &limit - return s -} - -func (s *SelectStatement) Offset(offset int) *SelectStatement { - s.offset = &offset - return s -} - -func (s *SelectStatement) Order(order ...string) *SelectStatement { - s.order = append(s.order, order...) - return s -} - -func (s *SelectStatement) Distinct(distinct ...string) *SelectStatement { - s.distinct = distinct - return s -} - -func (s *SelectStatement) GroupBy(group string) *SelectStatement { - s.group = group - return s -} - -func (s *SelectStatement) Having(having string) *SelectStatement { - s.having = having - return s -} - -func (s *SelectStatement) Join(join ...string) *SelectStatement { - s.joins = append(s.joins, join...) - return s -} - -// convert select statement to update statement -func (s *SelectStatement) Update() *UpdateStatement { - if s.limit != nil { - return NewUpdate().Table(s.from).Where(s.where) // TODO: convert into subquery - } - return NewUpdate().Table(s.from).Where(s.where) -} - -// convert select statement to delete statement -func (s *SelectStatement) Delete() *DeleteStatemnet { - return NewDelete().From(s.from).Where(s.where) -} - -func (s *SelectStatement) ToSQL() (string, []interface{}) { - var query string - if len(s.distinct) > 0 { - query = fmt.Sprintf("SELECT DISTINCT %s FROM %s", strings.Join(s.distinct, ", "), s.from) - } else { - query = fmt.Sprintf("SELECT %s FROM %s", strings.Join(s.selection, ", "), s.from) - } - args := []interface{}{} - - if len(s.joins) > 0 { - for i := 0; i < len(s.joins); i++ { - query = fmt.Sprintf("%s %s", query, s.joins[i]) - } - } - - if s.where != nil { - query = fmt.Sprintf("%s WHERE %s", query, s.where.fragment) - args = append(args, s.where.args...) - } - - if s.group != "" { - query = fmt.Sprintf("%s GROUP BY %s", query, s.group) - } - - if s.having != "" { - query = fmt.Sprintf("%s HAVING %s", query, s.having) - } - - if s.order != nil { - query = fmt.Sprintf("%s ORDER BY %s", query, strings.Join(s.order, ", ")) - } - - if s.limit != nil { - query = fmt.Sprintf("%s LIMIT ?", query) - args = append(args, *s.limit) - } - - if s.offset != nil { - query = fmt.Sprintf("%s OFFSET ?", query) - args = append(args, *s.offset) - } - - return query, args -} diff --git a/internal/bench/go-queryx/db/queryx/select_test.go b/internal/bench/go-queryx/db/queryx/select_test.go deleted file mode 100644 index 5c4b8977..00000000 --- a/internal/bench/go-queryx/db/queryx/select_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package queryx - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestSelect(t *testing.T) { - s := NewSelect().Select("users.*").From("users") - sql, args := s.ToSQL() - require.Equal(t, `SELECT users.* FROM users`, sql) - require.Equal(t, []interface{}{}, args) - - sql, args = s.Update().Columns("name", "email").Values("test", "test@example.com").ToSQL() - require.Equal(t, `UPDATE users SET name = ?, email = ?`, sql) - require.Equal(t, []interface{}{"test", "test@example.com"}, args) - - s1 := s.Limit(1) - sql, args = s1.ToSQL() - require.Equal(t, `SELECT users.* FROM users LIMIT ?`, sql) - require.Equal(t, []interface{}{1}, args) -} - -func TestSelectWhere(t *testing.T) { - s1 := NewSelect().Select("users.*").From("users").Where(NewClause("id = ?", []interface{}{1})) - sql, args := s1.ToSQL() - require.Equal(t, `SELECT users.* FROM users WHERE id = ?`, sql) - require.Equal(t, []interface{}{1}, args) - - s1.Where(NewClause("name = ?", []interface{}{"test"})) - sql, args = s1.ToSQL() - require.Equal(t, `SELECT users.* FROM users WHERE (id = ?) AND (name = ?)`, sql) - require.Equal(t, []interface{}{1, "test"}, args) -} diff --git a/internal/bench/go-queryx/db/queryx/string.go b/internal/bench/go-queryx/db/queryx/string.go deleted file mode 100644 index d47dd756..00000000 --- a/internal/bench/go-queryx/db/queryx/string.go +++ /dev/null @@ -1,72 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "database/sql" - "database/sql/driver" - "encoding/json" - "fmt" -) - -type String struct { - Val string - Valid bool - Set bool -} - -func NewString(v string) String { - return String{Val: v, Valid: true, Set: true} -} - -func NewNullableString(v *string) String { - if v != nil { - return NewString(*v) - } - return String{Set: true} -} - -// Scan implements the Scanner interface. -func (s *String) Scan(value interface{}) error { - ns := sql.NullString{String: s.Val} - err := ns.Scan(value) - s.Val, s.Valid = ns.String, ns.Valid - return err -} - -// Value implements the driver Valuer interface. -func (s String) Value() (driver.Value, error) { - if !s.Valid { - return nil, nil - } - return s.Val, nil -} - -// MarshalJSON implements the json.Marshaler interface. -func (s String) MarshalJSON() ([]byte, error) { - if !s.Valid { - return json.Marshal(nil) - } - return json.Marshal(s.Val) -} - -// UnmarshalJSON implements the json.Unmarshaler interface. -func (s *String) UnmarshalJSON(data []byte) error { - s.Set = true - if string(data) == "null" { - return nil - } - s.Valid = true - if err := json.Unmarshal(data, &s.Val); err != nil { - return err - } - return nil -} - -// String implements the stringer interface. -func (s String) String() string { - if !s.Valid { - return "null" - } - return fmt.Sprintf(`"%s"`, s.Val) -} diff --git a/internal/bench/go-queryx/db/queryx/string_column.go b/internal/bench/go-queryx/db/queryx/string_column.go deleted file mode 100644 index 00601c96..00000000 --- a/internal/bench/go-queryx/db/queryx/string_column.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import "fmt" - -type StringColumn struct { - Name string - Table *Table -} - -func (t *Table) NewStringColumn(name string) *StringColumn { - return &StringColumn{ - Table: t, - Name: name, - } -} - -func (c *StringColumn) NE(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s <> ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} -func (c *StringColumn) EQ(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("lower(%s.%s) = lower(?)", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *StringColumn) IEQ(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s = ?", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *StringColumn) In(v []string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s IN (?)", c.Table.Name, c.Name), - args: []interface{}{v}, - } -} - -func (c *StringColumn) Like(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s ilike ?", c.Table.Name, c.Name), - args: []interface{}{fmt.Sprintf("%s%s%s", "%", v, "%")}, - } -} - -func (c *StringColumn) ILike(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s like ?", c.Table.Name, c.Name), - args: []interface{}{fmt.Sprintf("%s%s%s", "%", v, "%")}, - } -} -func (c *StringColumn) IStartsWith(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s like ?", c.Table.Name, c.Name), - args: []interface{}{fmt.Sprintf("%s%s", v, "%")}, - } -} - -func (c *StringColumn) StartsWith(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s ilike ?", c.Table.Name, c.Name), - args: []interface{}{fmt.Sprintf("%s%s", v, "%")}, - } -} - -func (c *StringColumn) EndsWith(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s ilike ?", c.Table.Name, c.Name), - args: []interface{}{fmt.Sprintf("%s%s", "%", v)}, - } -} - -func (c *StringColumn) IEndsWith(v string) *Clause { - return &Clause{ - fragment: fmt.Sprintf("%s.%s like ?", c.Table.Name, c.Name), - args: []interface{}{fmt.Sprintf("%s%s", "%", v)}, - } -} - -func (c *StringColumn) Asc() string { - return fmt.Sprintf("%s.%s ASC", c.Table.Name, c.Name) -} - -func (c *StringColumn) Desc() string { - return fmt.Sprintf("%s.%s DESC", c.Table.Name, c.Name) -} diff --git a/internal/bench/go-queryx/db/queryx/string_test.go b/internal/bench/go-queryx/db/queryx/string_test.go deleted file mode 100644 index d2e7644f..00000000 --- a/internal/bench/go-queryx/db/queryx/string_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewString(t *testing.T) { - s1 := NewString("ss") - require.Equal(t, "ss", s1.Val) - require.True(t, s1.Valid) - - s2 := NewNullableString(nil) - require.False(t, s2.Valid) -} - -func TestStringJSON(t *testing.T) { - type Foo struct { - X String `json:"x"` - Y String `json:"y"` - } - x := NewString("ss") - y := NewNullableString(nil) - s := `{"x":"ss","y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/table.go b/internal/bench/go-queryx/db/queryx/table.go deleted file mode 100644 index 75a2e9a8..00000000 --- a/internal/bench/go-queryx/db/queryx/table.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -type Table struct { - Name string -} - -func NewTable(name string) *Table { - return &Table{ - Name: name, - } -} diff --git a/internal/bench/go-queryx/db/queryx/time_test.go b/internal/bench/go-queryx/db/queryx/time_test.go deleted file mode 100644 index 55bb768f..00000000 --- a/internal/bench/go-queryx/db/queryx/time_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewTime(t *testing.T) { - t1 := NewTime("12:11:10") - require.Equal(t, "12:11:10", t1.Val.Format("15:04:05")) - require.True(t, t1.Valid) - - t2 := NewNullableTime(nil) - require.False(t, t2.Valid) -} - -func TestTimeJSON(t *testing.T) { - type Foo struct { - X Time `json:"x"` - Y Time `json:"y"` - } - x := NewTime("12:11:10") - y := NewNullableTime(nil) - s := `{"x":"12:11:10","y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} diff --git a/internal/bench/go-queryx/db/queryx/update.go b/internal/bench/go-queryx/db/queryx/update.go deleted file mode 100644 index 2388cfbe..00000000 --- a/internal/bench/go-queryx/db/queryx/update.go +++ /dev/null @@ -1,67 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "fmt" - "strings" -) - -type UpdateStatement struct { - table string - columns []string - values []interface{} - where *Clause - returning string -} - -func NewUpdate() *UpdateStatement { - return &UpdateStatement{} -} - -func (s *UpdateStatement) Table(table string) *UpdateStatement { - s.table = table - return s -} - -func (s *UpdateStatement) Columns(columns ...string) *UpdateStatement { - s.columns = columns - return s -} - -func (s *UpdateStatement) Values(values ...interface{}) *UpdateStatement { - s.values = values - return s -} - -func (s *UpdateStatement) Where(expr *Clause) *UpdateStatement { - s.where = expr - return s -} - -func (s *UpdateStatement) Returning(returning string) *UpdateStatement { - s.returning = returning - return s -} - -func (s *UpdateStatement) ToSQL() (string, []interface{}) { - sql, args := fmt.Sprintf("UPDATE %s SET", s.table), s.values - - sets := []string{} - for _, col := range s.columns { - sets = append(sets, fmt.Sprintf("%s = ?", col)) - } - - sql = fmt.Sprintf("%s %s", sql, strings.Join(sets, ", ")) - - if s.where != nil { - sql = fmt.Sprintf("%s WHERE %s", sql, s.where.fragment) - args = append(args, s.where.args...) - } - - if s.returning != "" { - sql = fmt.Sprintf("%s RETURNING %s", sql, s.returning) - } - - return sql, args -} diff --git a/internal/bench/go-queryx/db/queryx/update_test.go b/internal/bench/go-queryx/db/queryx/update_test.go deleted file mode 100644 index 0d5e40e6..00000000 --- a/internal/bench/go-queryx/db/queryx/update_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package queryx - -import ( - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewUpdate(t *testing.T) { - s := NewUpdate().Table("users").Columns("name", "email").Values("test", "test@example.com") - sql, args := s.ToSQL() - require.Equal(t, "UPDATE users SET name = ?, email = ?", sql) - require.Equal(t, []interface{}{"test", "test@example.com"}, args) -} diff --git a/internal/bench/go-queryx/db/queryx/uuid_test.go b/internal/bench/go-queryx/db/queryx/uuid_test.go deleted file mode 100644 index 3fcd2eeb..00000000 --- a/internal/bench/go-queryx/db/queryx/uuid_test.go +++ /dev/null @@ -1,40 +0,0 @@ -// Code generated by queryx, DO NOT EDIT. - -package queryx - -import ( - "encoding/json" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestNewUUID(t *testing.T) { - u1 := NewUUID("a81e44c5-7e18-4dfe-b9b3-d9280629d2ef") - require.Equal(t, "a81e44c5-7e18-4dfe-b9b3-d9280629d2ef", u1.Val) - require.True(t, u1.Valid) - - u2 := NewNullableUUID(nil) - require.False(t, u2.Valid) -} - -func TestUUIDJSON(t *testing.T) { - type Foo struct { - X UUID `json:"x"` - Y UUID `json:"y"` - } - x := NewUUID("a81e44c5-7e18-4dfe-b9b3-d9280629d2ef") - y := NewNullableUUID(nil) - s := `{"x":"a81e44c5-7e18-4dfe-b9b3-d9280629d2ef","y":null}` - - f1 := Foo{X: x, Y: y} - b, err := json.Marshal(f1) - require.NoError(t, err) - require.Equal(t, s, string(b)) - - var f2 Foo - err = json.Unmarshal([]byte(s), &f2) - require.NoError(t, err) - require.Equal(t, x, f2.X) - require.Equal(t, y, f2.Y) -} From e16b4cc854f2759311da83e858132e3f4c03794a Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 18 Jan 2024 21:35:36 +0800 Subject: [PATCH 04/18] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 46ba8aaf..03a01b42 100644 --- a/Makefile +++ b/Makefile @@ -57,16 +57,11 @@ test-migrate: install 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')" -build-orm: - cd internal/bench && go build -o bin/queryxorm main.go - -install-orm: build-orm - cd internal/bench && install bin/queryxorm /usr/local/bin - -benchmarks:install-orm install +benchmarks: cd internal/bench/go-queryx && queryx db:drop --schema schema.hcl cd internal/bench/go-queryx && queryx db:create --schema schema.hcl cd internal/bench/go-queryx && queryx db:migrate --schema schema.hcl cd internal/bench/go-queryx && queryx g --schema schema.hcl - #cd internal/bench/ts-queryx && queryx g --schema schema.hcl + cd internal/bench && go build -o bin/queryxorm main.go + cd internal/bench && install bin/queryxorm /usr/local/bin queryxorm -orm=go-queryx From 8e8c3787a4f606aab4112b36477dc77429581d0b Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Fri, 19 Jan 2024 11:53:59 +0800 Subject: [PATCH 05/18] =?UTF-8?q?=E6=B7=BB=E5=8A=A0mysql=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 40 ++++++++- internal/bench/go-queryx/helper/sql.go | 69 +++++----------- internal/bench/go-queryx/models.go | 10 +-- internal/bench/go-queryx/mysql.hcl | 41 ++++++++++ .../go-queryx/{schema.hcl => postgresql.hcl} | 82 +++++++++---------- internal/bench/go-queryx/queryx.go | 12 +-- internal/bench/go-queryx/sqlite.hcl | 41 ++++++++++ internal/bench/main.go | 9 +- 8 files changed, 191 insertions(+), 113 deletions(-) create mode 100644 internal/bench/go-queryx/mysql.hcl rename internal/bench/go-queryx/{schema.hcl => postgresql.hcl} (94%) create mode 100644 internal/bench/go-queryx/sqlite.hcl diff --git a/Makefile b/Makefile index 03a01b42..252298d8 100644 --- a/Makefile +++ b/Makefile @@ -57,11 +57,43 @@ test-migrate: install 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-postgresql: + cd internal/bench/go-queryx && rm -rf db + cd internal/bench/go-queryx && queryx db:drop --schema postgresql.hcl + cd internal/bench/go-queryx && queryx db:create --schema postgresql.hcl + cd internal/bench/go-queryx && queryx db:migrate --schema postgresql.hcl + cd internal/bench/go-queryx && queryx g --schema postgresql.hcl + cd internal/bench && go build -o bin/queryxorm main.go + cd internal/bench && install bin/queryxorm /usr/local/bin + queryxorm -orm=go-queryx + +benchmarks-mysql: + cd internal/bench/go-queryx && rm -rf db + cd internal/bench/go-queryx && queryx db:drop --schema mysql.hcl + cd internal/bench/go-queryx && queryx db:create --schema mysql.hcl + cd internal/bench/go-queryx && queryx db:migrate --schema mysql.hcl + cd internal/bench/go-queryx && queryx g --schema mysql.hcl + cd internal/bench && go build -o bin/queryxorm main.go + cd internal/bench && install bin/queryxorm /usr/local/bin + queryxorm -orm=go-queryx + +benchmarks-sqlite: + cd internal/bench/go-queryx && rm -rf db + cd internal/bench/go-queryx && queryx db:drop --schema sqlite.hcl + cd internal/bench/go-queryx && queryx db:create --schema sqlite.hcl + cd internal/bench/go-queryx && queryx db:migrate --schema sqlite.hcl + cd internal/bench/go-queryx && queryx g --schema sqlite.hcl + cd internal/bench && go build -o bin/queryxorm main.go + cd internal/bench && install bin/queryxorm /usr/local/bin + queryxorm -orm=go-queryx + benchmarks: - cd internal/bench/go-queryx && queryx db:drop --schema schema.hcl - cd internal/bench/go-queryx && queryx db:create --schema schema.hcl - cd internal/bench/go-queryx && queryx db:migrate --schema schema.hcl - cd internal/bench/go-queryx && queryx g --schema schema.hcl + cd internal/bench/go-queryx && rm -rf db + cd internal/bench/go-queryx && queryx db:drop --schema postgresql.hcl + cd internal/bench/go-queryx && queryx db:create --schema postgresql.hcl + cd internal/bench/go-queryx && queryx db:migrate --schema postgresql.hcl + cd internal/bench/go-queryx && queryx g --schema postgresql.hcl cd internal/bench && go build -o bin/queryxorm main.go cd internal/bench && install bin/queryxorm /usr/local/bin queryxorm -orm=go-queryx diff --git a/internal/bench/go-queryx/helper/sql.go b/internal/bench/go-queryx/helper/sql.go index e9f38cff..d9b1b48e 100644 --- a/internal/bench/go-queryx/helper/sql.go +++ b/internal/bench/go-queryx/helper/sql.go @@ -1,64 +1,35 @@ package helper import ( - "database/sql" - "fmt" - _ "github.com/lib/pq" + "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db" + "log" ) func CreateTables() error { - queries := [][]string{ - { - `DROP TABLE IF EXISTS models;`, - `CREATE TABLE models ( - id SERIAL NOT NULL, - name text NOT NULL, - title text NOT NULL, - fax text NOT NULL, - web text NOT NULL, - age integer NOT NULL, - "righ" boolean NOT NULL, - counter bigint NOT NULL, - CONSTRAINT models_pkey PRIMARY KEY (id) - ) WITH (OIDS=FALSE);`, - }, - { - `DROP TABLE IF EXISTS model5;`, - `CREATE TABLE model5 ( - id SERIAL NOT NULL, + client, err := db.NewClient() + if err != nil { + log.Fatal(err) + return err + } + _, err = client.Exec(`DROP TABLE IF EXISTS models;`) + if err != nil { + log.Fatal(err) + return err + } + _, err = client.Exec( + `CREATE TABLE models ( + id SERIAL NOT NULL PRIMARY KEY, name text NOT NULL, title text NOT NULL, fax text NOT NULL, web text NOT NULL, age integer NOT NULL, - "righ" boolean NOT NULL, + righ boolean NOT NULL, counter bigint NOT NULL - ) WITH (OIDS=FALSE);`, - }, - } - - db, err := sql.Open("postgres", OrmSource) + );`) if err != nil { - return fmt.Errorf("init_tables: %w", err) + log.Fatal(err) + return err } - - defer func() { - _ = db.Close() - }() - - err = db.Ping() - if err != nil { - return fmt.Errorf("init_tables: %w", err) - } - - for _, query := range queries { - for _, line := range query { - _, err = db.Exec(line) - if err != nil { - return fmt.Errorf("init_tables: %w", err) - } - } - } - - return nil + return err } diff --git a/internal/bench/go-queryx/models.go b/internal/bench/go-queryx/models.go index 9781d797..f20a8986 100644 --- a/internal/bench/go-queryx/models.go +++ b/internal/bench/go-queryx/models.go @@ -1,7 +1,7 @@ package go_queryx // Model for go-queryx -type Model8 struct { +type Model struct { ID int `column:"id"` Name string `column:"name"` Title string `column:"title"` @@ -12,16 +12,16 @@ type Model8 struct { Counter int64 `column:"counter"` } -func (entity *Model8) GetTableName() string { +func (entity *Model) GetTableName() string { return "models" } -func (entity *Model8) GetPKColumnName() string { +func (entity *Model) GetPKColumnName() string { return "id" } -func NewModel8() *Model8 { - m := new(Model8) +func NewModel() *Model { + m := new(Model) m.Name = "Orm Benchmark" m.Title = "Just a Benchmark for fun" m.Fax = "99909990" diff --git a/internal/bench/go-queryx/mysql.hcl b/internal/bench/go-queryx/mysql.hcl new file mode 100644 index 00000000..f60130de --- /dev/null +++ b/internal/bench/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/bench/go-queryx/schema.hcl b/internal/bench/go-queryx/postgresql.hcl similarity index 94% rename from internal/bench/go-queryx/schema.hcl rename to internal/bench/go-queryx/postgresql.hcl index 9c640497..f087591e 100644 --- a/internal/bench/go-queryx/schema.hcl +++ b/internal/bench/go-queryx/postgresql.hcl @@ -1,41 +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 - } - } - -} +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/bench/go-queryx/queryx.go b/internal/bench/go-queryx/queryx.go index 7ae65cc0..26eacb8c 100644 --- a/internal/bench/go-queryx/queryx.go +++ b/internal/bench/go-queryx/queryx.go @@ -43,7 +43,7 @@ func (Queryx *Queryx) Close() error { } func (Queryx *Queryx) Insert(b *testing.B) { - m := NewModel8() + m := NewModel() b.ReportAllocs() b.ResetTimer() @@ -59,7 +59,7 @@ func (Queryx *Queryx) Insert(b *testing.B) { } func (Queryx *Queryx) InsertMulti(b *testing.B) { - m := NewModel8() + m := NewModel() ms := make([]*queryx.ModelChange, 0, 100) for i := 0; i < 100; i++ { ms = append(ms, c.ChangeModel().SetName(m.Name). @@ -78,12 +78,12 @@ func (Queryx *Queryx) InsertMulti(b *testing.B) { } func (Queryx *Queryx) Update(b *testing.B) { - m := NewModel8() + m := NewModel() change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)) m8, err := c.QueryModel().Create(change) if err != nil { - helper.SetError(b, Queryx.Name(), "Update...", err.Error()) + helper.SetError(b, Queryx.Name(), "Update", err.Error()) } b.ReportAllocs() @@ -98,7 +98,7 @@ func (Queryx *Queryx) Update(b *testing.B) { } func (Queryx *Queryx) Read(b *testing.B) { - m := NewModel8() + m := NewModel() change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)) _, err := c.QueryModel().Create(change) @@ -118,7 +118,7 @@ func (Queryx *Queryx) Read(b *testing.B) { } func (Queryx *Queryx) ReadSlice(b *testing.B) { - m := NewModel8() + m := NewModel() change := c.ChangeModel().SetName(m.Name).SetRigh(m.Righ). SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)) for i := 0; i < 100; i++ { diff --git a/internal/bench/go-queryx/sqlite.hcl b/internal/bench/go-queryx/sqlite.hcl new file mode 100644 index 00000000..0faee326 --- /dev/null +++ b/internal/bench/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/bench/main.go b/internal/bench/main.go index 32461881..0020bf4e 100644 --- a/internal/bench/main.go +++ b/internal/bench/main.go @@ -19,14 +19,7 @@ import ( // VERSION constant const VERSION = "v1.0.2" -var defaultBenchmarkNames = []string{ - "beego", "bun", "dbr", "ent", - "godb", "gorm", "gorm_prep", "gorp", - "pg", "pgx", "pgx_pool", "pop", - "raw", "reform", "rel", "sqlboiler", - "sqlc", "sqlx", "upper", "xorm", - "zorm", "gen", "go-queryx", -} +var defaultBenchmarkNames = []string{"go-queryx"} type ListOpts []string From 944c93115437fd89d52cb42d6c8f14d86ca77806 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Tue, 23 Jan 2024 17:30:43 +0800 Subject: [PATCH 06/18] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AF=B9ts,pg=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E8=BF=9B=E8=A1=8C=E5=8E=8B=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 44 +- internal/bench/go-queryx/helper/suite.go | 6 +- internal/bench/go-queryx/queryx.go | 14 +- internal/bench/ts-queryx/benchmark.test.ts | 29 ++ internal/bench/ts-queryx/mysql.hcl | 41 ++ internal/bench/ts-queryx/package.json | 14 + internal/bench/ts-queryx/postgresql.hcl | 41 ++ internal/bench/ts-queryx/sqlite.hcl | 41 ++ internal/bench/ts-queryx/yarn.lock | 541 +++++++++++++++++++++ package.json | 7 + yarn.lock | 38 ++ 11 files changed, 794 insertions(+), 22 deletions(-) create mode 100644 internal/bench/ts-queryx/benchmark.test.ts create mode 100644 internal/bench/ts-queryx/mysql.hcl create mode 100644 internal/bench/ts-queryx/package.json create mode 100644 internal/bench/ts-queryx/postgresql.hcl create mode 100644 internal/bench/ts-queryx/sqlite.hcl create mode 100644 internal/bench/ts-queryx/yarn.lock diff --git a/Makefile b/Makefile index 50165203..60ef8f0f 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ test-migrate: install cd internal/migrate && sqlite3 test.sqlite3 "insert into users(name, email) values('test', 'test@example.com')" -benchmarks-postgresql: +benchmarks-golang-postgresql: cd internal/bench/go-queryx && rm -rf db cd internal/bench/go-queryx && queryx db:drop --schema postgresql.hcl cd internal/bench/go-queryx && queryx db:create --schema postgresql.hcl @@ -68,7 +68,7 @@ benchmarks-postgresql: cd internal/bench && install bin/queryxorm /usr/local/bin queryxorm -orm=go-queryx -benchmarks-mysql: +benchmarks-golang-mysql: cd internal/bench/go-queryx && rm -rf db cd internal/bench/go-queryx && queryx db:drop --schema mysql.hcl cd internal/bench/go-queryx && queryx db:create --schema mysql.hcl @@ -78,7 +78,7 @@ benchmarks-mysql: cd internal/bench && install bin/queryxorm /usr/local/bin queryxorm -orm=go-queryx -benchmarks-sqlite: +benchmarks-golang-sqlite: cd internal/bench/go-queryx && rm -rf db cd internal/bench/go-queryx && queryx db:drop --schema sqlite.hcl cd internal/bench/go-queryx && queryx db:create --schema sqlite.hcl @@ -88,12 +88,32 @@ benchmarks-sqlite: cd internal/bench && install bin/queryxorm /usr/local/bin queryxorm -orm=go-queryx -benchmarks: - cd internal/bench/go-queryx && rm -rf db - cd internal/bench/go-queryx && queryx db:drop --schema postgresql.hcl - cd internal/bench/go-queryx && queryx db:create --schema postgresql.hcl - cd internal/bench/go-queryx && queryx db:migrate --schema postgresql.hcl - cd internal/bench/go-queryx && queryx g --schema postgresql.hcl - cd internal/bench && go build -o bin/queryxorm main.go - cd internal/bench && install bin/queryxorm /usr/local/bin - queryxorm -orm=go-queryx +benchmarks-typescript-postgresql: + cd internal/bench/ts-queryx && rm -rf db + cd internal/bench/ts-queryx && queryx db:drop --schema postgresql.hcl + cd internal/bench/ts-queryx && queryx db:create --schema postgresql.hcl + cd internal/bench/ts-queryx && queryx db:migrate --schema postgresql.hcl + cd internal/bench/ts-queryx && queryx g --schema postgresql.hcl + cd internal/bench/ts-queryx && tsc benchmark.test.ts + cd internal/bench/ts-queryx && node benchmark.test.js + + +benchmarks-typescript-mysql: + cd internal/bench/ts-queryx && rm -rf db + cd internal/bench/ts-queryx && queryx db:drop --schema mysql.hcl + cd internal/bench/ts-queryx && queryx db:create --schema mysql.hcl + cd internal/bench/ts-queryx && queryx db:migrate --schema mysql.hcl + cd internal/bench/ts-queryx && queryx g --schema mysql.hcl + cd internal/bench/ts-queryx && yarn + cd internal/bench/ts-queryx && tsc benchmark.test.ts + cd internal/bench/ts-queryx && node benchmark.test.js + + +benchmarks-typescript-sqlite: + cd internal/bench/ts-queryx && rm -rf db + cd internal/bench/ts-queryx && queryx db:drop --schema sqlite.hcl + cd internal/bench/ts-queryx && queryx db:create --schema sqlite.hcl + cd internal/bench/ts-queryx && queryx db:migrate --schema sqlite.hcl + cd internal/bench/ts-queryx && queryx g --schema sqlite.hcl + cd internal/bench/ts-queryx && tsc benchmark.test.ts + cd internal/bench/ts-queryx && node benchmark.test.js \ No newline at end of file diff --git a/internal/bench/go-queryx/helper/suite.go b/internal/bench/go-queryx/helper/suite.go index 49540b8b..2228be45 100644 --- a/internal/bench/go-queryx/helper/suite.go +++ b/internal/bench/go-queryx/helper/suite.go @@ -8,8 +8,8 @@ type ORMInterface interface { Name() string Init() error Close() error - Insert(b *testing.B) - InsertMulti(b *testing.B) + Create(b *testing.B) + InsertAll(b *testing.B) Update(b *testing.B) Read(b *testing.B) ReadSlice(b *testing.B) @@ -58,7 +58,7 @@ func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) (Benchm }(orm) var result BenchmarkResult - operations := []func(b *testing.B){orm.Insert, orm.InsertMulti, orm.Update, orm.Read, orm.ReadSlice} + operations := []func(b *testing.B){orm.Create, orm.InsertAll, orm.Update, orm.Read, orm.ReadSlice} result.ORM = orm.Name() for _, operation := range operations { diff --git a/internal/bench/go-queryx/queryx.go b/internal/bench/go-queryx/queryx.go index 26eacb8c..7185f966 100644 --- a/internal/bench/go-queryx/queryx.go +++ b/internal/bench/go-queryx/queryx.go @@ -42,7 +42,7 @@ func (Queryx *Queryx) Close() error { return nil } -func (Queryx *Queryx) Insert(b *testing.B) { +func (Queryx *Queryx) Create(b *testing.B) { m := NewModel() b.ReportAllocs() @@ -53,12 +53,12 @@ func (Queryx *Queryx) Insert(b *testing.B) { _, err := c.QueryModel().Create(c.ChangeModel().SetName(m.Name). SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)).SetRigh(m.Righ)) if err != nil { - helper.SetError(b, Queryx.Name(), "Insert", err.Error()) + helper.SetError(b, Queryx.Name(), "Create", err.Error()) } } } -func (Queryx *Queryx) InsertMulti(b *testing.B) { +func (Queryx *Queryx) InsertAll(b *testing.B) { m := NewModel() ms := make([]*queryx.ModelChange, 0, 100) for i := 0; i < 100; i++ { @@ -72,7 +72,7 @@ func (Queryx *Queryx) InsertMulti(b *testing.B) { for i := 0; i < b.N; i++ { _, err := c.QueryModel().InsertAll(ms) if err != nil { - helper.SetError(b, Queryx.Name(), "InsertMulti", err.Error()) + helper.SetError(b, Queryx.Name(), "InsertAll", err.Error()) } } } @@ -92,7 +92,7 @@ func (Queryx *Queryx) Update(b *testing.B) { 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(), "Update", err.Error()) + helper.SetError(b, Queryx.Name(), "UpdateAll", err.Error()) } } } @@ -112,7 +112,7 @@ func (Queryx *Queryx) Read(b *testing.B) { for i := 0; i < b.N; i++ { _, err := c.QueryModel().FindBy(c.ModelName.EQ(m.Name)) if err != nil { - helper.SetError(b, Queryx.Name(), "Read", err.Error()) + helper.SetError(b, Queryx.Name(), "FindBy", err.Error()) } } } @@ -134,7 +134,7 @@ func (Queryx *Queryx) ReadSlice(b *testing.B) { for i := 0; i < b.N; i++ { _, err := c.QueryModel().FindBySQL(queryxSelectMultiSQL) if err != nil { - helper.SetError(b, Queryx.Name(), "ReadSlice", err.Error()) + helper.SetError(b, Queryx.Name(), "FindBySQL", err.Error()) } } } diff --git a/internal/bench/ts-queryx/benchmark.test.ts b/internal/bench/ts-queryx/benchmark.test.ts new file mode 100644 index 00000000..5815a39d --- /dev/null +++ b/internal/bench/ts-queryx/benchmark.test.ts @@ -0,0 +1,29 @@ +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:', () => { + model = c.queryModel().create({name: "benchmark", title: "title", fax: "fax", web: "web", age: 122, righ: true, counter: 1222}).then(); + }).run() + .add("insertAll:",()=>{ + let models = 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",()=>{ + let m = c.queryModel().find(model.id) + }).run() + .add( "update:", ()=>{ + let u = c.queryModel().where(c.modelName.eq(model.name)).updateAll({name:"benchmark-update",title:"title",fax:"fax",web:"web",age:122,righ: true,counter:1222}); + }).run() + ; +} +benchmarkCreate() + + diff --git a/internal/bench/ts-queryx/mysql.hcl b/internal/bench/ts-queryx/mysql.hcl new file mode 100644 index 00000000..c8709255 --- /dev/null +++ b/internal/bench/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/bench/ts-queryx/package.json b/internal/bench/ts-queryx/package.json new file mode 100644 index 00000000..1bcaf45f --- /dev/null +++ b/internal/bench/ts-queryx/package.json @@ -0,0 +1,14 @@ +{ + "name": "ts-queryx", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "@types/pg": "^8.10.2", + "better-sqlite3": "^8.5.0", + "date-fns": "^2.30.0", + "mysql2": "^3.7.1", + "pg": "^8.11.3", + "tsc": "^2.0.4" + } +} diff --git a/internal/bench/ts-queryx/postgresql.hcl b/internal/bench/ts-queryx/postgresql.hcl new file mode 100644 index 00000000..e559062f --- /dev/null +++ b/internal/bench/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/bench/ts-queryx/sqlite.hcl b/internal/bench/ts-queryx/sqlite.hcl new file mode 100644 index 00000000..8ef73803 --- /dev/null +++ b/internal/bench/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/bench/ts-queryx/yarn.lock b/internal/bench/ts-queryx/yarn.lock new file mode 100644 index 00000000..1f755f21 --- /dev/null +++ b/internal/bench/ts-queryx/yarn.lock @@ -0,0 +1,541 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/runtime@^7.21.0": + version "7.23.8" + resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" + integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== + dependencies: + regenerator-runtime "^0.14.0" + +"@types/node@*": + version "20.11.5" + resolved "https://registry.npmmirror.com/@types/node/-/node-20.11.5.tgz#be10c622ca7fcaa3cf226cf80166abc31389d86e" + integrity sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w== + dependencies: + undici-types "~5.26.4" + +"@types/pg@^8.10.2": + version "8.10.9" + resolved "https://registry.npmmirror.com/@types/pg/-/pg-8.10.9.tgz#d20bb948c6268c5bd847e2bf968f1194c5a2355a" + integrity sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ== + dependencies: + "@types/node" "*" + pg-protocol "*" + pg-types "^4.0.1" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +better-sqlite3@^8.5.0: + version "8.7.0" + resolved "https://registry.npmmirror.com/better-sqlite3/-/better-sqlite3-8.7.0.tgz#bcc341856187b1d110a8a47234fa89c48c8ef538" + integrity sha512-99jZU4le+f3G6aIl6PmmV0cxUIWqKieHxsiF7G34CVFiE+/UabpYqkU0NJIkY/96mQKikHeBjtR27vFfs5JpEw== + dependencies: + bindings "^1.5.0" + prebuild-install "^7.1.1" + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.3: + version "4.1.0" + resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + +date-fns@^2.30.0: + version "2.30.0" + resolved "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + +detect-libc@^2.0.0: + version "2.0.2" + resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + +generate-function@^2.3.1: + version "2.3.1" + resolved "https://registry.npmmirror.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + +iconv-lite@^0.6.3: + version "0.6.3" + resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +ini@~1.3.0: + version "1.3.8" + resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + +is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + +long@^5.2.1: + version "5.2.3" + resolved "https://registry.npmmirror.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" + integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + +lru-cache@^8.0.0: + version "8.0.5" + resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-8.0.5.tgz#983fe337f3e176667f8e567cfcce7cb064ea214e" + integrity sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +minimist@^1.2.0, minimist@^1.2.3: + version "1.2.8" + resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + +mysql2@^3.7.1: + version "3.7.1" + resolved "https://registry.npmmirror.com/mysql2/-/mysql2-3.7.1.tgz#bb088fa3f01deefbfe04adaf0d3ec18571b33410" + integrity sha512-4EEqYu57mnkW5+Bvp5wBebY7PpfyrmvJ3knHcmLkp8FyBu4kqgrF2GxIjsC2tbLNZWqJaL21v/MYH7bU5f03oA== + dependencies: + denque "^2.1.0" + generate-function "^2.3.1" + iconv-lite "^0.6.3" + long "^5.2.1" + lru-cache "^8.0.0" + named-placeholders "^1.1.3" + seq-queue "^0.0.5" + sqlstring "^2.3.2" + +named-placeholders@^1.1.3: + version "1.1.3" + resolved "https://registry.npmmirror.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351" + integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w== + dependencies: + lru-cache "^7.14.1" + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + +node-abi@^3.3.0: + version "3.54.0" + resolved "https://registry.npmmirror.com/node-abi/-/node-abi-3.54.0.tgz#f6386f7548817acac6434c6cba02999c9aebcc69" + integrity sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA== + dependencies: + semver "^7.3.5" + +obuf@~1.1.2: + version "1.1.2" + resolved "https://registry.npmmirror.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + +once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +packet-reader@1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== + +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.npmmirror.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + +pg-connection-string@^2.6.2: + version "2.6.2" + resolved "https://registry.npmmirror.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" + integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.npmmirror.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-numeric@1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" + integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== + +pg-pool@^3.6.1: + version "3.6.1" + resolved "https://registry.npmmirror.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7" + integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== + +pg-protocol@*, pg-protocol@^1.6.0: + version "1.6.0" + resolved "https://registry.npmmirror.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" + integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.npmmirror.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg-types@^4.0.1: + version "4.0.2" + resolved "https://registry.npmmirror.com/pg-types/-/pg-types-4.0.2.tgz#399209a57c326f162461faa870145bb0f918b76d" + integrity sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng== + dependencies: + pg-int8 "1.0.1" + pg-numeric "1.0.2" + postgres-array "~3.0.1" + postgres-bytea "~3.0.0" + postgres-date "~2.1.0" + postgres-interval "^3.0.0" + postgres-range "^1.1.1" + +pg@^8.11.3: + version "8.11.3" + resolved "https://registry.npmmirror.com/pg/-/pg-8.11.3.tgz#d7db6e3fe268fcedd65b8e4599cda0b8b4bf76cb" + integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g== + dependencies: + buffer-writer "2.0.0" + packet-reader "1.0.0" + pg-connection-string "^2.6.2" + pg-pool "^3.6.1" + pg-protocol "^1.6.0" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.npmmirror.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-array@~3.0.1: + version "3.0.2" + resolved "https://registry.npmmirror.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98" + integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-bytea@~3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089" + integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw== + dependencies: + obuf "~1.1.2" + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.npmmirror.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-date@~2.1.0: + version "2.1.0" + resolved "https://registry.npmmirror.com/postgres-date/-/postgres-date-2.1.0.tgz#b85d3c1fb6fb3c6c8db1e9942a13a3bf625189d0" + integrity sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + +postgres-interval@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a" + integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw== + +postgres-range@^1.1.1: + version "1.1.3" + resolved "https://registry.npmmirror.com/postgres-range/-/postgres-range-1.1.3.tgz#9ccd7b01ca2789eb3c2e0888b3184225fa859f76" + integrity sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g== + +prebuild-install@^7.1.1: + version "7.1.1" + resolved "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.2" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + +safe-buffer@^5.0.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^7.3.5: + version "7.5.4" + resolved "https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +seq-queue@^0.0.5: + version "0.0.5" + resolved "https://registry.npmmirror.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" + integrity sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q== + +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^4.0.0: + version "4.0.1" + resolved "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + +sqlstring@^2.3.2: + version "2.3.3" + resolved "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" + integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== + +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== + dependencies: + chownr "^1.1.1" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +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== + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +wrappy@1: + version "1.0.2" + resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/package.json b/package.json index 5887d165..f2b7ff85 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 edf3ac4b..d2d686ea 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" From 32e1b30e105bbe297bccb47d389b13e5fea2f8ab Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Tue, 23 Jan 2024 17:56:28 +0800 Subject: [PATCH 07/18] fmt makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 60ef8f0f..8ad9ec06 100644 --- a/Makefile +++ b/Makefile @@ -116,4 +116,4 @@ benchmarks-typescript-sqlite: cd internal/bench/ts-queryx && queryx db:migrate --schema sqlite.hcl cd internal/bench/ts-queryx && queryx g --schema sqlite.hcl cd internal/bench/ts-queryx && tsc benchmark.test.ts - cd internal/bench/ts-queryx && node benchmark.test.js \ No newline at end of file + cd internal/bench/ts-queryx && node benchmark.test.js From 60fffee1d592541e9415c5c2dc32e76e2222c901 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 10:34:03 +0800 Subject: [PATCH 08/18] =?UTF-8?q?=E8=B0=83=E6=9F=A5benchmark?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 26 +++---- internal/bench/go-queryx/queryx.go | 3 +- internal/bench/main.go | 114 +++++------------------------ 3 files changed, 33 insertions(+), 110 deletions(-) diff --git a/Makefile b/Makefile index 8ad9ec06..c4672b65 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 @@ -58,7 +58,7 @@ test-migrate: install cd internal/migrate && sqlite3 test.sqlite3 "insert into users(name, email) values('test', 'test@example.com')" -benchmarks-golang-postgresql: +benchmarks-golang-postgresql: install cd internal/bench/go-queryx && rm -rf db cd internal/bench/go-queryx && queryx db:drop --schema postgresql.hcl cd internal/bench/go-queryx && queryx db:create --schema postgresql.hcl @@ -66,9 +66,9 @@ benchmarks-golang-postgresql: cd internal/bench/go-queryx && queryx g --schema postgresql.hcl cd internal/bench && go build -o bin/queryxorm main.go cd internal/bench && install bin/queryxorm /usr/local/bin - queryxorm -orm=go-queryx + queryxorm -benchmarks-golang-mysql: +benchmarks-golang-mysql: install cd internal/bench/go-queryx && rm -rf db cd internal/bench/go-queryx && queryx db:drop --schema mysql.hcl cd internal/bench/go-queryx && queryx db:create --schema mysql.hcl @@ -76,19 +76,19 @@ benchmarks-golang-mysql: cd internal/bench/go-queryx && queryx g --schema mysql.hcl cd internal/bench && go build -o bin/queryxorm main.go cd internal/bench && install bin/queryxorm /usr/local/bin - queryxorm -orm=go-queryx + queryxorm -benchmarks-golang-sqlite: +benchmarks-golang-sqlite: install cd internal/bench/go-queryx && rm -rf db cd internal/bench/go-queryx && queryx db:drop --schema sqlite.hcl cd internal/bench/go-queryx && queryx db:create --schema sqlite.hcl cd internal/bench/go-queryx && queryx db:migrate --schema sqlite.hcl cd internal/bench/go-queryx && queryx g --schema sqlite.hcl - cd internal/bench && go build -o bin/queryxorm main.go + cd internal/bench && set CGO_ENABLED=1 && go build -o bin/queryxorm main.go cd internal/bench && install bin/queryxorm /usr/local/bin - queryxorm -orm=go-queryx + queryxorm -benchmarks-typescript-postgresql: +benchmarks-typescript-postgresql: install cd internal/bench/ts-queryx && rm -rf db cd internal/bench/ts-queryx && queryx db:drop --schema postgresql.hcl cd internal/bench/ts-queryx && queryx db:create --schema postgresql.hcl @@ -98,7 +98,7 @@ benchmarks-typescript-postgresql: cd internal/bench/ts-queryx && node benchmark.test.js -benchmarks-typescript-mysql: +benchmarks-typescript-mysql: install cd internal/bench/ts-queryx && rm -rf db cd internal/bench/ts-queryx && queryx db:drop --schema mysql.hcl cd internal/bench/ts-queryx && queryx db:create --schema mysql.hcl @@ -109,7 +109,7 @@ benchmarks-typescript-mysql: cd internal/bench/ts-queryx && node benchmark.test.js -benchmarks-typescript-sqlite: +benchmarks-typescript-sqlite: install cd internal/bench/ts-queryx && rm -rf db cd internal/bench/ts-queryx && queryx db:drop --schema sqlite.hcl cd internal/bench/ts-queryx && queryx db:create --schema sqlite.hcl diff --git a/internal/bench/go-queryx/queryx.go b/internal/bench/go-queryx/queryx.go index 7185f966..042bb92b 100644 --- a/internal/bench/go-queryx/queryx.go +++ b/internal/bench/go-queryx/queryx.go @@ -26,7 +26,7 @@ func CreateQueryx() helper.ORMInterface { } func (Queryx *Queryx) Name() string { - return "go-queryx" + return "queryx" } func (Queryx *Queryx) Init() error { @@ -79,6 +79,7 @@ func (Queryx *Queryx) InsertAll(b *testing.B) { 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(int64(m.Age)).SetCounter(int32(m.Counter)) m8, err := c.QueryModel().Create(change) diff --git a/internal/bench/main.go b/internal/bench/main.go index 0020bf4e..47f75114 100644 --- a/internal/bench/main.go +++ b/internal/bench/main.go @@ -1,17 +1,13 @@ package main import ( - "flag" "fmt" "github.com/swiftcarrot/queryx/internal/bench/go-queryx" "github.com/swiftcarrot/queryx/internal/bench/go-queryx/helper" - "math/rand" "os" "runtime" "sort" - "strings" "text/tabwriter" - "time" _ "github.com/lib/pq" ) @@ -19,114 +15,40 @@ import ( // VERSION constant const VERSION = "v1.0.2" -var defaultBenchmarkNames = []string{"go-queryx"} - -type ListOpts []string - -func (opts *ListOpts) String() string { - return fmt.Sprint(*opts) -} - -func (opts *ListOpts) Set(value string) error { - if value != "all" && !strings.Contains(" "+strings.Join(defaultBenchmarkNames, " ")+" ", " "+value+" ") { - return fmt.Errorf("wrong run name %s", value) - } - - *opts = append(*opts, value) - return nil -} - -func (opts ListOpts) Shuffle() { - rd := rand.New(rand.NewSource(time.Now().UnixNano())) - for i := 0; i < len(opts); i++ { - a := rd.Intn(len(opts)) - b := rd.Intn(len(opts)) - opts[a], opts[b] = opts[b], opts[a] - } -} - func main() { runtime.GOMAXPROCS(runtime.NumCPU()) - - var orms ListOpts - var all bool - - flag.StringVar(&helper.OrmSource, "source", "host=localhost user=postgres password=postgres dbname=test sslmode=disable", "postgres dsn source") - flag.Var(&orms, "orm", "orm name: all, "+strings.Join(defaultBenchmarkNames, ", ")) - flag.IntVar(&helper.OrmMaxIdle, "max_idle", 200, "max idle conns") - flag.IntVar(&helper.OrmMaxConn, "max_conn", 200, "max open conns") - flag.BoolVar(&helper.DebugMode, "debug", false, "Enable debug mode (also prints not-sorted results of ORMs)") - version := flag.Bool("version", false, "prints current roxy version") - flag.Parse() - - // Print version - if *version { - fmt.Println(VERSION) - os.Exit(0) - } - - // Check it is all - if len(orms) == 0 { - all = true - } else { - for _, n := range orms { - if n == "all" { - all = true - } - } - } - - if all { - orms = defaultBenchmarkNames - } - orms.Shuffle() - - // Init error map helper.Errors = make(map[string]map[string]string, 0) - for _, name := range defaultBenchmarkNames { - helper.Errors[name] = make(map[string]string, 0) - } - - runBenchmarks(orms) + helper.Errors["queryx"] = make(map[string]string, 0) + runBenchmarks() } -func runBenchmarks(orms ListOpts) { +func runBenchmarks() { // Run benchmarks benchmarks := map[string]helper.ORMInterface{ - "go-queryx": go_queryx.CreateQueryx(), + "queryx": go_queryx.CreateQueryx(), } table := new(tabwriter.Writer) table.Init(os.Stdout, 0, 8, 2, '\t', tabwriter.AlignRight) reports := make(map[string]helper.BenchmarkReport, 0) - i := 0 - for _, n := range orms { - orm := benchmarks[n] - if orm == nil { - panic(fmt.Sprintf("Unknown ORM: %s", n)) - } - res, err := helper.RunBenchmarks(orm, reports) - if err != nil { - panic(fmt.Sprintf("An error occured while running the benchmarks: %v", err)) - } + res, err := helper.RunBenchmarks(benchmarks["queryx"], reports) + if err != nil { + panic(fmt.Sprintf("An error occured while running the benchmarks: %v", err)) + } - if helper.DebugMode { - if i != 0 { - _, _ = fmt.Fprint(table, "\n") - } - _, _ = fmt.Fprintf(table, "%s Benchmark Results:\n", n) - for _, result := range res.Results { - if result.ErrorMsg == "" { - _, _ = fmt.Fprintf(table, "%s:\t%d\t%d ns/op\t%d B/op\t%d allocs/op\n", result.Method, result.N, result.NsPerOp, result.MemBytes, result.MemAllocs) - } else { - _, _ = fmt.Fprintf(table, "%s:\t%s\n", result.Method, result.ErrorMsg) - } + if helper.DebugMode { + + _, _ = fmt.Fprintf(table, "%s Benchmark Results:\n", "queryx") + for _, result := range res.Results { + if result.ErrorMsg == "" { + _, _ = fmt.Fprintf(table, "%s:\t%d\t%d ns/op\t%d B/op\t%d allocs/op\n", result.Method, result.N, result.NsPerOp, result.MemBytes, result.MemAllocs) + } else { + _, _ = fmt.Fprintf(table, "%s:\t%s\n", result.Method, result.ErrorMsg) } - _ = table.Flush() } - i++ + _ = table.Flush() } // Sort results @@ -140,7 +62,7 @@ func runBenchmarks(orms ListOpts) { } _, _ = fmt.Fprintf(table, "Reports:\n\n") - i = 1 + i := 1 for method, report := range reports { _, _ = fmt.Fprintf(table, "%s\n", method) for _, result := range report { From 6c751484216ebc12c16f61401c35bf67941f64ff Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 11:51:19 +0800 Subject: [PATCH 09/18] fmt benchmark --- Makefile | 2 +- internal/bench/go-queryx/helper/constants.go | 8 ----- internal/bench/go-queryx/helper/misc.go | 14 -------- internal/bench/go-queryx/helper/suite.go | 15 ++------ .../go-queryx/helper/{error.go => tools.go} | 10 ++++++ internal/bench/go-queryx/queryx.go | 4 --- internal/bench/main.go | 35 +------------------ 7 files changed, 15 insertions(+), 73 deletions(-) delete mode 100644 internal/bench/go-queryx/helper/constants.go delete mode 100644 internal/bench/go-queryx/helper/misc.go rename internal/bench/go-queryx/helper/{error.go => tools.go} (55%) diff --git a/Makefile b/Makefile index c4672b65..02d15243 100644 --- a/Makefile +++ b/Makefile @@ -84,7 +84,7 @@ benchmarks-golang-sqlite: install cd internal/bench/go-queryx && queryx db:create --schema sqlite.hcl cd internal/bench/go-queryx && queryx db:migrate --schema sqlite.hcl cd internal/bench/go-queryx && queryx g --schema sqlite.hcl - cd internal/bench && set CGO_ENABLED=1 && go build -o bin/queryxorm main.go + cd internal/bench && go build -o bin/queryxorm main.go cd internal/bench && install bin/queryxorm /usr/local/bin queryxorm diff --git a/internal/bench/go-queryx/helper/constants.go b/internal/bench/go-queryx/helper/constants.go deleted file mode 100644 index e8a58577..00000000 --- a/internal/bench/go-queryx/helper/constants.go +++ /dev/null @@ -1,8 +0,0 @@ -package helper - -var ( - OrmMaxIdle int - OrmMaxConn int - OrmSource string - DebugMode bool -) diff --git a/internal/bench/go-queryx/helper/misc.go b/internal/bench/go-queryx/helper/misc.go deleted file mode 100644 index 067887b3..00000000 --- a/internal/bench/go-queryx/helper/misc.go +++ /dev/null @@ -1,14 +0,0 @@ -package helper - -import ( - "reflect" - "runtime" - "strings" -) - -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/bench/go-queryx/helper/suite.go b/internal/bench/go-queryx/helper/suite.go index 2228be45..b5d21bb2 100644 --- a/internal/bench/go-queryx/helper/suite.go +++ b/internal/bench/go-queryx/helper/suite.go @@ -7,7 +7,6 @@ import ( type ORMInterface interface { Name() string Init() error - Close() error Create(b *testing.B) InsertAll(b *testing.B) Update(b *testing.B) @@ -47,22 +46,15 @@ func (s BenchmarkReport) Less(i, j int) bool { return s[i].NsPerOp < s[j].NsPerOp } -func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) (BenchmarkResult, error) { +func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) error { err := orm.Init() if err != nil { - return BenchmarkResult{}, err + return err } - defer func(orm ORMInterface) { - _ = orm.Close() - }(orm) - - var result BenchmarkResult operations := []func(b *testing.B){orm.Create, orm.InsertAll, orm.Update, orm.Read, orm.ReadSlice} - result.ORM = orm.Name() for _, operation := range operations { - // Clean tables for each run err := CreateTables() if err != nil { panic(err) @@ -82,8 +74,7 @@ func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) (Benchm } reports[method] = append(reports[method], gotResult) - result.Results = append(result.Results, *gotResult) } - return result, nil + return err } diff --git a/internal/bench/go-queryx/helper/error.go b/internal/bench/go-queryx/helper/tools.go similarity index 55% rename from internal/bench/go-queryx/helper/error.go rename to internal/bench/go-queryx/helper/tools.go index a532fd7b..32de89f3 100644 --- a/internal/bench/go-queryx/helper/error.go +++ b/internal/bench/go-queryx/helper/tools.go @@ -1,6 +1,9 @@ package helper import ( + "reflect" + "runtime" + "strings" "sync" "testing" ) @@ -21,3 +24,10 @@ func SetError(b *testing.B, orm, method, err string) { 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/bench/go-queryx/queryx.go b/internal/bench/go-queryx/queryx.go index 042bb92b..9ab1728c 100644 --- a/internal/bench/go-queryx/queryx.go +++ b/internal/bench/go-queryx/queryx.go @@ -38,10 +38,6 @@ func (Queryx *Queryx) Init() error { return err } -func (Queryx *Queryx) Close() error { - return nil -} - func (Queryx *Queryx) Create(b *testing.B) { m := NewModel() diff --git a/internal/bench/main.go b/internal/bench/main.go index 47f75114..82259b29 100644 --- a/internal/bench/main.go +++ b/internal/bench/main.go @@ -8,13 +8,8 @@ import ( "runtime" "sort" "text/tabwriter" - - _ "github.com/lib/pq" ) -// VERSION constant -const VERSION = "v1.0.2" - func main() { runtime.GOMAXPROCS(runtime.NumCPU()) helper.Errors = make(map[string]map[string]string, 0) @@ -23,45 +18,17 @@ func main() { } func runBenchmarks() { - // Run benchmarks - benchmarks := map[string]helper.ORMInterface{ - "queryx": go_queryx.CreateQueryx(), - } - table := new(tabwriter.Writer) table.Init(os.Stdout, 0, 8, 2, '\t', tabwriter.AlignRight) - reports := make(map[string]helper.BenchmarkReport, 0) - - res, err := helper.RunBenchmarks(benchmarks["queryx"], reports) + err := helper.RunBenchmarks(go_queryx.CreateQueryx(), reports) if err != nil { panic(fmt.Sprintf("An error occured while running the benchmarks: %v", err)) } - - if helper.DebugMode { - - _, _ = fmt.Fprintf(table, "%s Benchmark Results:\n", "queryx") - for _, result := range res.Results { - if result.ErrorMsg == "" { - _, _ = fmt.Fprintf(table, "%s:\t%d\t%d ns/op\t%d B/op\t%d allocs/op\n", result.Method, result.N, result.NsPerOp, result.MemBytes, result.MemAllocs) - } else { - _, _ = fmt.Fprintf(table, "%s:\t%s\n", result.Method, result.ErrorMsg) - } - } - _ = table.Flush() - } - - // Sort results for _, v := range reports { sort.Sort(v) } - - // Print final reports - if helper.DebugMode { - _, _ = fmt.Fprint(table, "\n") - } _, _ = fmt.Fprintf(table, "Reports:\n\n") - i := 1 for method, report := range reports { _, _ = fmt.Fprintf(table, "%s\n", method) From 5a5d820b7cf7f2661ccb7939d82171e67817a926 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 15:58:22 +0800 Subject: [PATCH 10/18] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=BC=96=E8=AF=91?= =?UTF-8?q?=E5=90=8E=E5=BC=95=E7=94=A8=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/queryx/adapter.mysql.ts | 4 +- .../benchmarks/ts-queryx/benchmark.test.ts | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 internal/benchmarks/ts-queryx/benchmark.test.ts diff --git a/generator/client/typescript/templates/queryx/adapter.mysql.ts b/generator/client/typescript/templates/queryx/adapter.mysql.ts index 22c21bfe..bb35f899 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/ts-queryx/benchmark.test.ts b/internal/benchmarks/ts-queryx/benchmark.test.ts new file mode 100644 index 00000000..059370c6 --- /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 + }).then(); + }).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() From 152cd5a4e798d69c49e63b2390d4f49e19799372 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 15:59:40 +0800 Subject: [PATCH 11/18] fmt benchmarks --- internal/benchmarks/go-queryx/helper/sql.go | 35 +++++ internal/benchmarks/go-queryx/helper/suite.go | 80 ++++++++++ internal/benchmarks/go-queryx/helper/tools.go | 33 +++++ internal/benchmarks/go-queryx/models.go | 26 ++++ internal/benchmarks/go-queryx/queryx.go | 139 ++++++++++++++++++ 5 files changed, 313 insertions(+) create mode 100644 internal/benchmarks/go-queryx/helper/sql.go create mode 100644 internal/benchmarks/go-queryx/helper/suite.go create mode 100644 internal/benchmarks/go-queryx/helper/tools.go create mode 100644 internal/benchmarks/go-queryx/models.go create mode 100644 internal/benchmarks/go-queryx/queryx.go diff --git a/internal/benchmarks/go-queryx/helper/sql.go b/internal/benchmarks/go-queryx/helper/sql.go new file mode 100644 index 00000000..040315df --- /dev/null +++ b/internal/benchmarks/go-queryx/helper/sql.go @@ -0,0 +1,35 @@ +package helper + +import ( + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db" + "log" +) + +func CreateTables() error { + client, err := db.NewClient() + if err != nil { + log.Fatal(err) + return err + } + _, err = client.Exec(`DROP TABLE IF EXISTS models;`) + if err != nil { + log.Fatal(err) + return err + } + _, err = client.Exec( + `CREATE TABLE models ( + id SERIAL PRIMARY KEY, + name text NOT NULL, + title text NOT NULL, + fax text NOT NULL, + web text NOT NULL, + age integer NOT NULL, + righ boolean NOT NULL, + counter bigint NOT NULL + );`) + 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 00000000..b4ac5911 --- /dev/null +++ b/internal/benchmarks/go-queryx/helper/suite.go @@ -0,0 +1,80 @@ +package helper + +import ( + "testing" +) + +type ORMInterface interface { + Name() string + Init() 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(orm ORMInterface, reports map[string]BenchmarkReport) error { + 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() + if err != nil { + panic(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 err +} diff --git a/internal/benchmarks/go-queryx/helper/tools.go b/internal/benchmarks/go-queryx/helper/tools.go new file mode 100644 index 00000000..32de89f3 --- /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 00000000..80376364 --- /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 int `column:"age"` + Righ bool `column:"righ"` + Counter int64 `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/queryx.go b/internal/benchmarks/go-queryx/queryx.go new file mode 100644 index 00000000..337a60f5 --- /dev/null +++ b/internal/benchmarks/go-queryx/queryx.go @@ -0,0 +1,139 @@ +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() error { + client, err := db.NewClient() + if err != nil { + return err + } + c = client + return err +} + +func (Queryx *Queryx) Create(b *testing.B) { + m := NewModel() + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + m.ID = 0 + _, err := c.QueryModel().Create(c.ChangeModel().SetName(m.Name). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)).SetRigh(m.Righ)) + if err != nil { + helper.SetError(b, Queryx.Name(), "Create", err.Error()) + } + } +} + +func (Queryx *Queryx) InsertAll(b *testing.B) { + _, err := c.QueryModel().DeleteAll() + if err != nil { + helper.SetError(b, Queryx.Name(), "delete", err.Error()) + } + m := NewModel() + ms := make([]*queryx.ModelChange, 0, 100) + for i := 0; i < 100; i++ { + ms = append(ms, c.ChangeModel().SetName(m.Name).SetID(int64(i)). + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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()) + } + } +} From a6f69b17f03de6779623212a7003c4850b3a3e04 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 16:00:23 +0800 Subject: [PATCH 12/18] fmt benchmarks --- internal/bench/go-queryx/helper/sql.go | 35 -- internal/bench/go-queryx/helper/suite.go | 80 --- internal/bench/go-queryx/helper/tools.go | 33 -- internal/bench/go-queryx/queryx.go | 137 ----- internal/bench/main.go | 49 -- internal/bench/ts-queryx/benchmark.test.ts | 29 - internal/bench/ts-queryx/yarn.lock | 541 ------------------ .../{bench => benchmarks}/go-queryx/mysql.hcl | 0 .../go-queryx/postgresql.hcl | 0 .../go-queryx/sqlite.hcl | 0 .../{bench => benchmarks}/ts-queryx/mysql.hcl | 0 .../ts-queryx/package.json | 2 +- .../ts-queryx/postgresql.hcl | 0 .../ts-queryx/sqlite.hcl | 0 internal/benchmarks/ts-queryx/tsconfig.json | 18 + 15 files changed, 19 insertions(+), 905 deletions(-) delete mode 100644 internal/bench/go-queryx/helper/sql.go delete mode 100644 internal/bench/go-queryx/helper/suite.go delete mode 100644 internal/bench/go-queryx/helper/tools.go delete mode 100644 internal/bench/go-queryx/queryx.go delete mode 100644 internal/bench/main.go delete mode 100644 internal/bench/ts-queryx/benchmark.test.ts delete mode 100644 internal/bench/ts-queryx/yarn.lock rename internal/{bench => benchmarks}/go-queryx/mysql.hcl (100%) rename internal/{bench => benchmarks}/go-queryx/postgresql.hcl (100%) rename internal/{bench => benchmarks}/go-queryx/sqlite.hcl (100%) rename internal/{bench => benchmarks}/ts-queryx/mysql.hcl (100%) rename internal/{bench => benchmarks}/ts-queryx/package.json (91%) rename internal/{bench => benchmarks}/ts-queryx/postgresql.hcl (100%) rename internal/{bench => benchmarks}/ts-queryx/sqlite.hcl (100%) create mode 100644 internal/benchmarks/ts-queryx/tsconfig.json diff --git a/internal/bench/go-queryx/helper/sql.go b/internal/bench/go-queryx/helper/sql.go deleted file mode 100644 index d9b1b48e..00000000 --- a/internal/bench/go-queryx/helper/sql.go +++ /dev/null @@ -1,35 +0,0 @@ -package helper - -import ( - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db" - "log" -) - -func CreateTables() error { - client, err := db.NewClient() - if err != nil { - log.Fatal(err) - return err - } - _, err = client.Exec(`DROP TABLE IF EXISTS models;`) - if err != nil { - log.Fatal(err) - return err - } - _, err = client.Exec( - `CREATE TABLE models ( - id SERIAL NOT NULL PRIMARY KEY, - name text NOT NULL, - title text NOT NULL, - fax text NOT NULL, - web text NOT NULL, - age integer NOT NULL, - righ boolean NOT NULL, - counter bigint NOT NULL - );`) - if err != nil { - log.Fatal(err) - return err - } - return err -} diff --git a/internal/bench/go-queryx/helper/suite.go b/internal/bench/go-queryx/helper/suite.go deleted file mode 100644 index b5d21bb2..00000000 --- a/internal/bench/go-queryx/helper/suite.go +++ /dev/null @@ -1,80 +0,0 @@ -package helper - -import ( - "testing" -) - -type ORMInterface interface { - Name() string - Init() 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(orm ORMInterface, reports map[string]BenchmarkReport) error { - err := orm.Init() - if err != nil { - return err - } - - operations := []func(b *testing.B){orm.Create, orm.InsertAll, orm.Update, orm.Read, orm.ReadSlice} - - for _, operation := range operations { - err := CreateTables() - if err != nil { - panic(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 err -} diff --git a/internal/bench/go-queryx/helper/tools.go b/internal/bench/go-queryx/helper/tools.go deleted file mode 100644 index 32de89f3..00000000 --- a/internal/bench/go-queryx/helper/tools.go +++ /dev/null @@ -1,33 +0,0 @@ -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/bench/go-queryx/queryx.go b/internal/bench/go-queryx/queryx.go deleted file mode 100644 index 9ab1728c..00000000 --- a/internal/bench/go-queryx/queryx.go +++ /dev/null @@ -1,137 +0,0 @@ -package go_queryx - -import ( - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db" - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/db/queryx" - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/helper" - "testing" - - _ "github.com/lib/pq" -) - -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() error { - client, err := db.NewClient() - if err != nil { - return err - } - c = client - return err -} - -func (Queryx *Queryx) Create(b *testing.B) { - m := NewModel() - - b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - m.ID = 0 - _, err := c.QueryModel().Create(c.ChangeModel().SetName(m.Name). - SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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(int64(m.Age)).SetCounter(int32(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/bench/main.go b/internal/bench/main.go deleted file mode 100644 index 82259b29..00000000 --- a/internal/bench/main.go +++ /dev/null @@ -1,49 +0,0 @@ -package main - -import ( - "fmt" - "github.com/swiftcarrot/queryx/internal/bench/go-queryx" - "github.com/swiftcarrot/queryx/internal/bench/go-queryx/helper" - "os" - "runtime" - "sort" - "text/tabwriter" -) - -func main() { - runtime.GOMAXPROCS(runtime.NumCPU()) - helper.Errors = make(map[string]map[string]string, 0) - helper.Errors["queryx"] = make(map[string]string, 0) - runBenchmarks() -} - -func runBenchmarks() { - table := new(tabwriter.Writer) - table.Init(os.Stdout, 0, 8, 2, '\t', tabwriter.AlignRight) - reports := make(map[string]helper.BenchmarkReport, 0) - err := helper.RunBenchmarks(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/bench/ts-queryx/benchmark.test.ts b/internal/bench/ts-queryx/benchmark.test.ts deleted file mode 100644 index 5815a39d..00000000 --- a/internal/bench/ts-queryx/benchmark.test.ts +++ /dev/null @@ -1,29 +0,0 @@ -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:', () => { - model = c.queryModel().create({name: "benchmark", title: "title", fax: "fax", web: "web", age: 122, righ: true, counter: 1222}).then(); - }).run() - .add("insertAll:",()=>{ - let models = 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",()=>{ - let m = c.queryModel().find(model.id) - }).run() - .add( "update:", ()=>{ - let u = c.queryModel().where(c.modelName.eq(model.name)).updateAll({name:"benchmark-update",title:"title",fax:"fax",web:"web",age:122,righ: true,counter:1222}); - }).run() - ; -} -benchmarkCreate() - - diff --git a/internal/bench/ts-queryx/yarn.lock b/internal/bench/ts-queryx/yarn.lock deleted file mode 100644 index 1f755f21..00000000 --- a/internal/bench/ts-queryx/yarn.lock +++ /dev/null @@ -1,541 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@babel/runtime@^7.21.0": - version "7.23.8" - resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.23.8.tgz#8ee6fe1ac47add7122902f257b8ddf55c898f650" - integrity sha512-Y7KbAP984rn1VGMbGqKmBLio9V7y5Je9GvU4rQPCPinCyNfUcToxIXl06d59URp/F3LwinvODxab5N/G6qggkw== - dependencies: - regenerator-runtime "^0.14.0" - -"@types/node@*": - version "20.11.5" - resolved "https://registry.npmmirror.com/@types/node/-/node-20.11.5.tgz#be10c622ca7fcaa3cf226cf80166abc31389d86e" - integrity sha512-g557vgQjUUfN76MZAN/dt1z3dzcUsimuysco0KeluHgrPdJXkP/XdAURgyO2W9fZWHRtRBiVKzKn8vyOAwlG+w== - dependencies: - undici-types "~5.26.4" - -"@types/pg@^8.10.2": - version "8.10.9" - resolved "https://registry.npmmirror.com/@types/pg/-/pg-8.10.9.tgz#d20bb948c6268c5bd847e2bf968f1194c5a2355a" - integrity sha512-UksbANNE/f8w0wOMxVKKIrLCbEMV+oM1uKejmwXr39olg4xqcfBDbXxObJAt6XxHbDa4XTKOlUEcEltXDX+XLQ== - dependencies: - "@types/node" "*" - pg-protocol "*" - pg-types "^4.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -better-sqlite3@^8.5.0: - version "8.7.0" - resolved "https://registry.npmmirror.com/better-sqlite3/-/better-sqlite3-8.7.0.tgz#bcc341856187b1d110a8a47234fa89c48c8ef538" - integrity sha512-99jZU4le+f3G6aIl6PmmV0cxUIWqKieHxsiF7G34CVFiE+/UabpYqkU0NJIkY/96mQKikHeBjtR27vFfs5JpEw== - dependencies: - bindings "^1.5.0" - prebuild-install "^7.1.1" - -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.npmmirror.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bl@^4.0.3: - version "4.1.0" - resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -buffer-writer@2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" - integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.npmmirror.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -date-fns@^2.30.0: - version "2.30.0" - resolved "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.npmmirror.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.npmmirror.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -denque@^2.1.0: - version "2.1.0" - resolved "https://registry.npmmirror.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" - integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== - -detect-libc@^2.0.0: - version "2.0.2" - resolved "https://registry.npmmirror.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - -end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.npmmirror.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -generate-function@^2.3.1: - version "2.3.1" - resolved "https://registry.npmmirror.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" - integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== - dependencies: - is-property "^1.0.2" - -github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.npmmirror.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== - -iconv-lite@^0.6.3: - version "0.6.3" - resolved "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -ieee754@^1.1.13: - version "1.2.1" - resolved "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -inherits@^2.0.3, inherits@^2.0.4: - version "2.0.4" - resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@~1.3.0: - version "1.3.8" - resolved "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -is-property@^1.0.2: - version "1.0.2" - resolved "https://registry.npmmirror.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" - integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== - -long@^5.2.1: - version "5.2.3" - resolved "https://registry.npmmirror.com/long/-/long-5.2.3.tgz#a3ba97f3877cf1d778eccbcb048525ebb77499e1" - integrity sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru-cache@^7.14.1: - version "7.18.3" - resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -lru-cache@^8.0.0: - version "8.0.5" - resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-8.0.5.tgz#983fe337f3e176667f8e567cfcce7cb064ea214e" - integrity sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.npmmirror.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -minimist@^1.2.0, minimist@^1.2.3: - version "1.2.8" - resolved "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.npmmirror.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - -mysql2@^3.7.1: - version "3.7.1" - resolved "https://registry.npmmirror.com/mysql2/-/mysql2-3.7.1.tgz#bb088fa3f01deefbfe04adaf0d3ec18571b33410" - integrity sha512-4EEqYu57mnkW5+Bvp5wBebY7PpfyrmvJ3knHcmLkp8FyBu4kqgrF2GxIjsC2tbLNZWqJaL21v/MYH7bU5f03oA== - dependencies: - denque "^2.1.0" - generate-function "^2.3.1" - iconv-lite "^0.6.3" - long "^5.2.1" - lru-cache "^8.0.0" - named-placeholders "^1.1.3" - seq-queue "^0.0.5" - sqlstring "^2.3.2" - -named-placeholders@^1.1.3: - version "1.1.3" - resolved "https://registry.npmmirror.com/named-placeholders/-/named-placeholders-1.1.3.tgz#df595799a36654da55dda6152ba7a137ad1d9351" - integrity sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w== - dependencies: - lru-cache "^7.14.1" - -napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.npmmirror.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - -node-abi@^3.3.0: - version "3.54.0" - resolved "https://registry.npmmirror.com/node-abi/-/node-abi-3.54.0.tgz#f6386f7548817acac6434c6cba02999c9aebcc69" - integrity sha512-p7eGEiQil0YUV3ItH4/tBb781L5impVmmx2E9FRKF7d18XXzp4PGT2tdYMFY6wQqgxD0IwNZOiSJ0/K0fSi/OA== - dependencies: - semver "^7.3.5" - -obuf@~1.1.2: - version "1.1.2" - resolved "https://registry.npmmirror.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.npmmirror.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -packet-reader@1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" - integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== - -pg-cloudflare@^1.1.1: - version "1.1.1" - resolved "https://registry.npmmirror.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" - integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== - -pg-connection-string@^2.6.2: - version "2.6.2" - resolved "https://registry.npmmirror.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" - integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== - -pg-int8@1.0.1: - version "1.0.1" - resolved "https://registry.npmmirror.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" - integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== - -pg-numeric@1.0.2: - version "1.0.2" - resolved "https://registry.npmmirror.com/pg-numeric/-/pg-numeric-1.0.2.tgz#816d9a44026086ae8ae74839acd6a09b0636aa3a" - integrity sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw== - -pg-pool@^3.6.1: - version "3.6.1" - resolved "https://registry.npmmirror.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7" - integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== - -pg-protocol@*, pg-protocol@^1.6.0: - version "1.6.0" - resolved "https://registry.npmmirror.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" - integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== - -pg-types@^2.1.0: - version "2.2.0" - resolved "https://registry.npmmirror.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" - integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== - dependencies: - pg-int8 "1.0.1" - postgres-array "~2.0.0" - postgres-bytea "~1.0.0" - postgres-date "~1.0.4" - postgres-interval "^1.1.0" - -pg-types@^4.0.1: - version "4.0.2" - resolved "https://registry.npmmirror.com/pg-types/-/pg-types-4.0.2.tgz#399209a57c326f162461faa870145bb0f918b76d" - integrity sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng== - dependencies: - pg-int8 "1.0.1" - pg-numeric "1.0.2" - postgres-array "~3.0.1" - postgres-bytea "~3.0.0" - postgres-date "~2.1.0" - postgres-interval "^3.0.0" - postgres-range "^1.1.1" - -pg@^8.11.3: - version "8.11.3" - resolved "https://registry.npmmirror.com/pg/-/pg-8.11.3.tgz#d7db6e3fe268fcedd65b8e4599cda0b8b4bf76cb" - integrity sha512-+9iuvG8QfaaUrrph+kpF24cXkH1YOOUeArRNYIxq1viYHZagBxrTno7cecY1Fa44tJeZvaoG+Djpkc3JwehN5g== - dependencies: - buffer-writer "2.0.0" - packet-reader "1.0.0" - pg-connection-string "^2.6.2" - pg-pool "^3.6.1" - pg-protocol "^1.6.0" - pg-types "^2.1.0" - pgpass "1.x" - optionalDependencies: - pg-cloudflare "^1.1.1" - -pgpass@1.x: - version "1.0.5" - resolved "https://registry.npmmirror.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" - integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== - dependencies: - split2 "^4.1.0" - -postgres-array@~2.0.0: - version "2.0.0" - resolved "https://registry.npmmirror.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" - integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== - -postgres-array@~3.0.1: - version "3.0.2" - resolved "https://registry.npmmirror.com/postgres-array/-/postgres-array-3.0.2.tgz#68d6182cb0f7f152a7e60dc6a6889ed74b0a5f98" - integrity sha512-6faShkdFugNQCLwucjPcY5ARoW1SlbnrZjmGl0IrrqewpvxvhSLHimCVzqeuULCbG0fQv7Dtk1yDbG3xv7Veog== - -postgres-bytea@~1.0.0: - version "1.0.0" - resolved "https://registry.npmmirror.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" - integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== - -postgres-bytea@~3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/postgres-bytea/-/postgres-bytea-3.0.0.tgz#9048dc461ac7ba70a6a42d109221619ecd1cb089" - integrity sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw== - dependencies: - obuf "~1.1.2" - -postgres-date@~1.0.4: - version "1.0.7" - resolved "https://registry.npmmirror.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" - integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== - -postgres-date@~2.1.0: - version "2.1.0" - resolved "https://registry.npmmirror.com/postgres-date/-/postgres-date-2.1.0.tgz#b85d3c1fb6fb3c6c8db1e9942a13a3bf625189d0" - integrity sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA== - -postgres-interval@^1.1.0: - version "1.2.0" - resolved "https://registry.npmmirror.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" - integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== - dependencies: - xtend "^4.0.0" - -postgres-interval@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/postgres-interval/-/postgres-interval-3.0.0.tgz#baf7a8b3ebab19b7f38f07566c7aab0962f0c86a" - integrity sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw== - -postgres-range@^1.1.1: - version "1.1.3" - resolved "https://registry.npmmirror.com/postgres-range/-/postgres-range-1.1.3.tgz#9ccd7b01ca2789eb3c2e0888b3184225fa859f76" - integrity sha512-VdlZoocy5lCP0c/t66xAfclglEapXPCIVhqqJRncYpvbCgImF0w67aPKfbqUMr72tO2k5q0TdTZwCLjPTI6C9g== - -prebuild-install@^7.1.1: - version "7.1.1" - resolved "https://registry.npmmirror.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -rc@^1.2.7: - version "1.2.8" - resolved "https://registry.npmmirror.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - -readable-stream@^3.1.1, readable-stream@^3.4.0: - version "3.6.2" - resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -regenerator-runtime@^0.14.0: - version "0.14.1" - resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" - integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== - -safe-buffer@^5.0.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -semver@^7.3.5: - version "7.5.4" - resolved "https://registry.npmmirror.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -seq-queue@^0.0.5: - version "0.0.5" - resolved "https://registry.npmmirror.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" - integrity sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.npmmirror.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^4.0.0: - version "4.0.1" - resolved "https://registry.npmmirror.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" - integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== - dependencies: - decompress-response "^6.0.0" - once "^1.3.1" - simple-concat "^1.0.0" - -split2@^4.1.0: - version "4.2.0" - resolved "https://registry.npmmirror.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" - integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== - -sqlstring@^2.3.2: - version "2.3.3" - resolved "https://registry.npmmirror.com/sqlstring/-/sqlstring-2.3.3.tgz#2ddc21f03bce2c387ed60680e739922c65751d0c" - integrity sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg== - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - -tar-fs@^2.0.0: - version "2.1.1" - resolved "https://registry.npmmirror.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== - dependencies: - chownr "^1.1.1" - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^2.1.4" - -tar-stream@^2.1.4: - version "2.2.0" - resolved "https://registry.npmmirror.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -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== - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.npmmirror.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.npmmirror.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/internal/bench/go-queryx/mysql.hcl b/internal/benchmarks/go-queryx/mysql.hcl similarity index 100% rename from internal/bench/go-queryx/mysql.hcl rename to internal/benchmarks/go-queryx/mysql.hcl diff --git a/internal/bench/go-queryx/postgresql.hcl b/internal/benchmarks/go-queryx/postgresql.hcl similarity index 100% rename from internal/bench/go-queryx/postgresql.hcl rename to internal/benchmarks/go-queryx/postgresql.hcl diff --git a/internal/bench/go-queryx/sqlite.hcl b/internal/benchmarks/go-queryx/sqlite.hcl similarity index 100% rename from internal/bench/go-queryx/sqlite.hcl rename to internal/benchmarks/go-queryx/sqlite.hcl diff --git a/internal/bench/ts-queryx/mysql.hcl b/internal/benchmarks/ts-queryx/mysql.hcl similarity index 100% rename from internal/bench/ts-queryx/mysql.hcl rename to internal/benchmarks/ts-queryx/mysql.hcl diff --git a/internal/bench/ts-queryx/package.json b/internal/benchmarks/ts-queryx/package.json similarity index 91% rename from internal/bench/ts-queryx/package.json rename to internal/benchmarks/ts-queryx/package.json index 1bcaf45f..faa66f05 100644 --- a/internal/bench/ts-queryx/package.json +++ b/internal/benchmarks/ts-queryx/package.json @@ -7,7 +7,7 @@ "@types/pg": "^8.10.2", "better-sqlite3": "^8.5.0", "date-fns": "^2.30.0", - "mysql2": "^3.7.1", + "mysql2": "^3.8.0", "pg": "^8.11.3", "tsc": "^2.0.4" } diff --git a/internal/bench/ts-queryx/postgresql.hcl b/internal/benchmarks/ts-queryx/postgresql.hcl similarity index 100% rename from internal/bench/ts-queryx/postgresql.hcl rename to internal/benchmarks/ts-queryx/postgresql.hcl diff --git a/internal/bench/ts-queryx/sqlite.hcl b/internal/benchmarks/ts-queryx/sqlite.hcl similarity index 100% rename from internal/bench/ts-queryx/sqlite.hcl rename to internal/benchmarks/ts-queryx/sqlite.hcl diff --git a/internal/benchmarks/ts-queryx/tsconfig.json b/internal/benchmarks/ts-queryx/tsconfig.json new file mode 100644 index 00000000..75a94b9c --- /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. */ + } +} From 12f5f2239251664194c62c8eafb9e8efc94d7dc2 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 16:03:41 +0800 Subject: [PATCH 13/18] fmt table --- Makefile | 86 +++++++++++++++--------------- internal/bench/go-queryx/models.go | 34 ------------ internal/benchmarks/main.go | 49 +++++++++++++++++ 3 files changed, 92 insertions(+), 77 deletions(-) delete mode 100644 internal/bench/go-queryx/models.go create mode 100644 internal/benchmarks/main.go diff --git a/Makefile b/Makefile index 02d15243..d2590aad 100644 --- a/Makefile +++ b/Makefile @@ -59,61 +59,61 @@ test-migrate: install benchmarks-golang-postgresql: install - cd internal/bench/go-queryx && rm -rf db - cd internal/bench/go-queryx && queryx db:drop --schema postgresql.hcl - cd internal/bench/go-queryx && queryx db:create --schema postgresql.hcl - cd internal/bench/go-queryx && queryx db:migrate --schema postgresql.hcl - cd internal/bench/go-queryx && queryx g --schema postgresql.hcl - cd internal/bench && go build -o bin/queryxorm main.go - cd internal/bench && install bin/queryxorm /usr/local/bin + 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 benchmarks-golang-mysql: install - cd internal/bench/go-queryx && rm -rf db - cd internal/bench/go-queryx && queryx db:drop --schema mysql.hcl - cd internal/bench/go-queryx && queryx db:create --schema mysql.hcl - cd internal/bench/go-queryx && queryx db:migrate --schema mysql.hcl - cd internal/bench/go-queryx && queryx g --schema mysql.hcl - cd internal/bench && go build -o bin/queryxorm main.go - cd internal/bench && install bin/queryxorm /usr/local/bin + 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 benchmarks-golang-sqlite: install - cd internal/bench/go-queryx && rm -rf db - cd internal/bench/go-queryx && queryx db:drop --schema sqlite.hcl - cd internal/bench/go-queryx && queryx db:create --schema sqlite.hcl - cd internal/bench/go-queryx && queryx db:migrate --schema sqlite.hcl - cd internal/bench/go-queryx && queryx g --schema sqlite.hcl - cd internal/bench && go build -o bin/queryxorm main.go - cd internal/bench && install bin/queryxorm /usr/local/bin + 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 benchmarks-typescript-postgresql: install - cd internal/bench/ts-queryx && rm -rf db - cd internal/bench/ts-queryx && queryx db:drop --schema postgresql.hcl - cd internal/bench/ts-queryx && queryx db:create --schema postgresql.hcl - cd internal/bench/ts-queryx && queryx db:migrate --schema postgresql.hcl - cd internal/bench/ts-queryx && queryx g --schema postgresql.hcl - cd internal/bench/ts-queryx && tsc benchmark.test.ts - cd internal/bench/ts-queryx && node benchmark.test.js + 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/bench/ts-queryx && rm -rf db - cd internal/bench/ts-queryx && queryx db:drop --schema mysql.hcl - cd internal/bench/ts-queryx && queryx db:create --schema mysql.hcl - cd internal/bench/ts-queryx && queryx db:migrate --schema mysql.hcl - cd internal/bench/ts-queryx && queryx g --schema mysql.hcl - cd internal/bench/ts-queryx && yarn - cd internal/bench/ts-queryx && tsc benchmark.test.ts - cd internal/bench/ts-queryx && node benchmark.test.js + 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/bench/ts-queryx && rm -rf db - cd internal/bench/ts-queryx && queryx db:drop --schema sqlite.hcl - cd internal/bench/ts-queryx && queryx db:create --schema sqlite.hcl - cd internal/bench/ts-queryx && queryx db:migrate --schema sqlite.hcl - cd internal/bench/ts-queryx && queryx g --schema sqlite.hcl - cd internal/bench/ts-queryx && tsc benchmark.test.ts - cd internal/bench/ts-queryx && node benchmark.test.js + 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/internal/bench/go-queryx/models.go b/internal/bench/go-queryx/models.go deleted file mode 100644 index f20a8986..00000000 --- a/internal/bench/go-queryx/models.go +++ /dev/null @@ -1,34 +0,0 @@ -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 int `column:"age"` - Righ bool `column:"righ"` - Counter int64 `column:"counter"` -} - -func (entity *Model) GetTableName() string { - return "models" -} - -func (entity *Model) GetPKColumnName() string { - return "id" -} - -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/main.go b/internal/benchmarks/main.go new file mode 100644 index 00000000..4d72ebd2 --- /dev/null +++ b/internal/benchmarks/main.go @@ -0,0 +1,49 @@ +package main + +import ( + "fmt" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx" + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/helper" + "os" + "runtime" + "sort" + "text/tabwriter" +) + +func main() { + runtime.GOMAXPROCS(runtime.NumCPU()) + helper.Errors = make(map[string]map[string]string, 0) + helper.Errors["queryx"] = make(map[string]string, 0) + runBenchmarks() +} + +func runBenchmarks() { + table := new(tabwriter.Writer) + table.Init(os.Stdout, 0, 8, 2, '\t', tabwriter.AlignRight) + reports := make(map[string]helper.BenchmarkReport, 0) + err := helper.RunBenchmarks(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() +} From 4fa8d98f8984a4e876adc75a029d862b47a49757 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Thu, 25 Jan 2024 16:33:07 +0800 Subject: [PATCH 14/18] =?UTF-8?q?id=E8=87=AA=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/benchmarks/go-queryx/queryx.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/benchmarks/go-queryx/queryx.go b/internal/benchmarks/go-queryx/queryx.go index 337a60f5..7a734a62 100644 --- a/internal/benchmarks/go-queryx/queryx.go +++ b/internal/benchmarks/go-queryx/queryx.go @@ -60,7 +60,7 @@ 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).SetID(int64(i)). + ms = append(ms, c.ChangeModel().SetName(m.Name). SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)).SetRigh(m.Righ)) } From 38a8b8cafb34357e853fbc808fb7e07df581ed79 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Fri, 26 Jan 2024 16:58:29 +0800 Subject: [PATCH 15/18] =?UTF-8?q?=E5=85=BC=E5=AE=B9sqlite?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/benchmarks/go-queryx/helper/sql.go | 63 +++++++++++++------ internal/benchmarks/go-queryx/helper/suite.go | 13 ++-- internal/benchmarks/go-queryx/models.go | 4 +- internal/benchmarks/go-queryx/queryx.go | 21 +++---- internal/benchmarks/main.go | 11 +++- 5 files changed, 70 insertions(+), 42 deletions(-) diff --git a/internal/benchmarks/go-queryx/helper/sql.go b/internal/benchmarks/go-queryx/helper/sql.go index 040315df..567d799c 100644 --- a/internal/benchmarks/go-queryx/helper/sql.go +++ b/internal/benchmarks/go-queryx/helper/sql.go @@ -1,32 +1,59 @@ package helper import ( + "fmt" "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db" "log" ) -func CreateTables() error { - client, err := db.NewClient() - if err != nil { - log.Fatal(err) - return err +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;`) + _, err := client.Exec(`DROP TABLE IF EXISTS models;`) if err != nil { - log.Fatal(err) return err } - _, err = client.Exec( - `CREATE TABLE models ( - id SERIAL PRIMARY KEY, - name text NOT NULL, - title text NOT NULL, - fax text NOT NULL, - web text NOT NULL, - age integer NOT NULL, - righ boolean NOT NULL, - counter bigint NOT NULL - );`) + _, err = client.Exec(sql) if err != nil { log.Fatal(err) return err diff --git a/internal/benchmarks/go-queryx/helper/suite.go b/internal/benchmarks/go-queryx/helper/suite.go index b4ac5911..2f0b68b2 100644 --- a/internal/benchmarks/go-queryx/helper/suite.go +++ b/internal/benchmarks/go-queryx/helper/suite.go @@ -1,12 +1,13 @@ package helper import ( + "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/db" "testing" ) type ORMInterface interface { Name() string - Init() error + Init() (*db.QXClient, error) Create(b *testing.B) InsertAll(b *testing.B) Update(b *testing.B) @@ -46,8 +47,8 @@ func (s BenchmarkReport) Less(i, j int) bool { return s[i].NsPerOp < s[j].NsPerOp } -func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) error { - err := orm.Init() +func RunBenchmarks(adapter string, orm ORMInterface, reports map[string]BenchmarkReport) error { + c, err := orm.Init() if err != nil { return err } @@ -55,9 +56,9 @@ func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) error { operations := []func(b *testing.B){orm.InsertAll, orm.Create, orm.Update, orm.Read, orm.ReadSlice} for _, operation := range operations { - err := CreateTables() + err = CreateTables(c, adapter) if err != nil { - panic(err) + return err } br := testing.Benchmark(operation) @@ -76,5 +77,5 @@ func RunBenchmarks(orm ORMInterface, reports map[string]BenchmarkReport) error { reports[method] = append(reports[method], gotResult) } - return err + return nil } diff --git a/internal/benchmarks/go-queryx/models.go b/internal/benchmarks/go-queryx/models.go index 80376364..2623eeda 100644 --- a/internal/benchmarks/go-queryx/models.go +++ b/internal/benchmarks/go-queryx/models.go @@ -7,9 +7,9 @@ type Model struct { Title string `column:"title"` Fax string `column:"fax"` Web string `column:"web"` - Age int `column:"age"` + Age int64 `column:"age"` Righ bool `column:"righ"` - Counter int64 `column:"counter"` + Counter int32 `column:"counter"` } func NewModel() *Model { diff --git a/internal/benchmarks/go-queryx/queryx.go b/internal/benchmarks/go-queryx/queryx.go index 7a734a62..b3b0092f 100644 --- a/internal/benchmarks/go-queryx/queryx.go +++ b/internal/benchmarks/go-queryx/queryx.go @@ -27,13 +27,13 @@ func (Queryx *Queryx) Name() string { return "queryx" } -func (Queryx *Queryx) Init() error { +func (Queryx *Queryx) Init() (*db.QXClient, error) { client, err := db.NewClient() if err != nil { - return err + return nil, err } c = client - return err + return client, err } func (Queryx *Queryx) Create(b *testing.B) { @@ -43,9 +43,8 @@ func (Queryx *Queryx) Create(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - m.ID = 0 _, err := c.QueryModel().Create(c.ChangeModel().SetName(m.Name). - SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(int64(m.Age)).SetCounter(int32(m.Counter)).SetRigh(m.Righ)) + 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()) } @@ -53,15 +52,11 @@ func (Queryx *Queryx) Create(b *testing.B) { } func (Queryx *Queryx) InsertAll(b *testing.B) { - _, err := c.QueryModel().DeleteAll() - if err != nil { - helper.SetError(b, Queryx.Name(), "delete", err.Error()) - } 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(int64(m.Age)).SetCounter(int32(m.Counter)).SetRigh(m.Righ)) + SetTitle(m.Title).SetFax(m.Fax).SetWeb(m.Web).SetAge(m.Age).SetCounter(m.Counter).SetRigh(m.Righ)) } b.ReportAllocs() @@ -79,7 +74,7 @@ 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(int64(m.Age)).SetCounter(int32(m.Counter)) + 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()) @@ -99,7 +94,7 @@ func (Queryx *Queryx) Update(b *testing.B) { 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(int64(m.Age)).SetCounter(int32(m.Counter)) + 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()) @@ -119,7 +114,7 @@ func (Queryx *Queryx) Read(b *testing.B) { 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(int64(m.Age)).SetCounter(int32(m.Counter)) + 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 { diff --git a/internal/benchmarks/main.go b/internal/benchmarks/main.go index 4d72ebd2..46775a3a 100644 --- a/internal/benchmarks/main.go +++ b/internal/benchmarks/main.go @@ -1,6 +1,7 @@ package main import ( + "flag" "fmt" "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx" "github.com/swiftcarrot/queryx/internal/benchmarks/go-queryx/helper" @@ -10,18 +11,22 @@ import ( "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() + runBenchmarks(adapter) } -func runBenchmarks() { +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(go_queryx.CreateQueryx(), reports) + err := helper.RunBenchmarks(adapter, go_queryx.CreateQueryx(), reports) if err != nil { panic(fmt.Sprintf("An error occured while running the benchmarks: %v", err)) } From 6e08edb32298d9d1381b612c43043d5d17aa07d4 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Fri, 26 Jan 2024 17:09:25 +0800 Subject: [PATCH 16/18] fix makefile --- Makefile | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index d2590aad..1bac9620 100644 --- a/Makefile +++ b/Makefile @@ -66,7 +66,7 @@ benchmarks-golang-postgresql: install 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 + queryxorm -adapter=postgresql benchmarks-golang-mysql: install cd internal/benchmarks/go-queryx && rm -rf db @@ -76,17 +76,19 @@ benchmarks-golang-mysql: install 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 + 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: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 + 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 From e98b19b274b331e8b67f945f940a7a93ecd96039 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Fri, 26 Jan 2024 17:35:33 +0800 Subject: [PATCH 17/18] =?UTF-8?q?=E6=B7=BB=E5=8A=A0golang=E5=8E=8B?= =?UTF-8?q?=E6=B5=8B=E6=8A=A5=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- benchmarks-results.md | 54 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 benchmarks-results.md diff --git a/benchmarks-results.md b/benchmarks-results.md new file mode 100644 index 00000000..d8448e23 --- /dev/null +++ b/benchmarks-results.md @@ -0,0 +1,54 @@ +# 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 +``` From 87aae2a1c679d14ce70af2a032f62554e28d6349 Mon Sep 17 00:00:00 2001 From: fujian liang <860478944@qq.com> Date: Fri, 26 Jan 2024 18:59:46 +0800 Subject: [PATCH 18/18] =?UTF-8?q?=E6=B7=BB=E5=8A=A0ts=E7=9A=84benchmarks?= =?UTF-8?q?=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- benchmarks-results.md | 19 +++++++++++++++++++ .../benchmarks/ts-queryx/benchmark.test.ts | 4 ++-- internal/benchmarks/ts-queryx/package.json | 3 ++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/benchmarks-results.md b/benchmarks-results.md index d8448e23..02d783b6 100644 --- a/benchmarks-results.md +++ b/benchmarks-results.md @@ -51,4 +51,23 @@ 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/internal/benchmarks/ts-queryx/benchmark.test.ts b/internal/benchmarks/ts-queryx/benchmark.test.ts index 059370c6..51421c4d 100644 --- a/internal/benchmarks/ts-queryx/benchmark.test.ts +++ b/internal/benchmarks/ts-queryx/benchmark.test.ts @@ -19,7 +19,7 @@ function benchmarkCreate(){ age: 122, righ: true, counter: 1222 - }).then(); + }); }).run() .add("insertAll:",async () => { await c.queryModel().insertAll([{ @@ -48,7 +48,7 @@ function benchmarkCreate(){ counter: 1222 }]) }).run() - .add("find",async () => { + .add("find:",async () => { await c.queryModel().find(model.id) }).run() .add( "update:", async () => { diff --git a/internal/benchmarks/ts-queryx/package.json b/internal/benchmarks/ts-queryx/package.json index faa66f05..b0e124b8 100644 --- a/internal/benchmarks/ts-queryx/package.json +++ b/internal/benchmarks/ts-queryx/package.json @@ -4,8 +4,9 @@ "main": "index.js", "license": "MIT", "dependencies": { + "@types/better-sqlite3": "^7.6.4", "@types/pg": "^8.10.2", - "better-sqlite3": "^8.5.0", + "better-sqlite3": "^9.3.0", "date-fns": "^2.30.0", "mysql2": "^3.8.0", "pg": "^8.11.3",