pax_global_header00006660000000000000000000000064151443523670014524gustar00rootroot0000000000000052 comment=02b216417462abde5f829a70f5a2743d76b09fcb golang-ariga-sqlcomment-0.1.0/000077500000000000000000000000001514435236700162325ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/.github/000077500000000000000000000000001514435236700175725ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/.github/workflows/000077500000000000000000000000001514435236700216275ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/.github/workflows/go.yml000066400000000000000000000005621514435236700227620ustar00rootroot00000000000000name: Go on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Go uses: actions/setup-go@v2 with: go-version: 1.17 - name: Build run: go build -v ./... - name: Test run: | go test -v ./...golang-ariga-sqlcomment-0.1.0/LICENSE000066400000000000000000000261351514435236700172460ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.golang-ariga-sqlcomment-0.1.0/README.md000066400000000000000000000031241514435236700175110ustar00rootroot00000000000000# sqlcomm**ent** sqlcomm**ent** is an [ent](https://entgo.io) driver that adds SQL comments following [sqlcommenter specification](https://google.github.io/sqlcommenter/spec/). sqlcomment includes support for OpenTelemetry and OpenCensus (see [examples](examples/)). # Installing ```bash go install ariga.io/sqlcomment ``` # Basic Usage ```go // Create db driver. // make sure to import "entgo.io/ent/dialect/sql" instead of "database/sql" db, err := sql.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") if err != nil { log.Fatalf("Failed to connect to database: %v", err) } // Create sqlcomment driver which wraps sqlite driver. drv := sqlcomment.NewDriver(db, sqlcomment.WithDriverVerTag(), sqlcomment.WithTags(sqlcomment.Tags{ sqlcomment.KeyApplication: "my-app", sqlcomment.KeyFramework: "net/http", }), ) // Create and configure ent client client := ent.NewClient(ent.Driver(drv)) ``` # Adding context level tags Suppose you have a REST API and you want to add a tag with the request URL (typically `route` tag). You can achieve that by using `sqlcomment.WithTag(ctx, key, val)` which adds the given tag to the context to later be serialized by sqlcomment driver. (see full example [here](examples/otel/example_test.go)) ```go // Add a middleware to your HTTP server which puts the `route` tag on the context for every request. middleware := func(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { ctx := sqlcomment.WithTag(r.Context(), "route", r.URL.Path) next.ServeHTTP(w, r.WithContext(ctx)) } return http.HandlerFunc(fn) } ``` golang-ariga-sqlcomment-0.1.0/config.go000066400000000000000000000016521514435236700200320ustar00rootroot00000000000000package sqlcomment import ( "context" ) // A Tagger is used by the driver to add tags to SQL queries. type Tagger interface { Tag(context.Context) Tags } type ( Option func(*options) options struct { taggers []Tagger } ) // WithTagger sets the taggers to be used to populate the SQL comment. func WithTagger(taggers ...Tagger) Option { return func(opts *options) { opts.taggers = append(opts.taggers, taggers...) } } // WithTags appends the given tags to every SQL query. func WithTags(tags Tags) Option { return func(opts *options) { opts.taggers = append(opts.taggers, NewStaticTagger(tags)) } } // WithDriverVerTag adds `db_driver` tag with the current version of ent. func WithDriverVerTag() Option { return func(opts *options) { opts.taggers = append(opts.taggers, NewDriverVersionTagger()) } } func buildOptions(opts []Option) options { var o options for _, opt := range opts { opt(&o) } return o } golang-ariga-sqlcomment-0.1.0/context.go000066400000000000000000000026401514435236700202470ustar00rootroot00000000000000package sqlcomment import ( "context" ) type ( // ctxOptions allows injecting runtime options. ctxOptions struct { skip bool // i.e. skip entry. tags Tags } ctxKeyType struct{} ) var ctxOptionsKey ctxKeyType // Skip returns a new Context that tells the Driver // to skip the commenting on Query. // // client.T.Query().All(sqlcomment.Skip(ctx)) // func Skip(ctx context.Context) context.Context { c, ok := ctx.Value(ctxOptionsKey).(*ctxOptions) if !ok { return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{skip: true}) } c.skip = true return ctx } // WithTag stores the key and val pair on the context. // for example, if you want to add `route` tag to your SQL comment, put the url path on request context: // middleware := func(next http.Handler) http.Handler { // fn := func(w http.ResponseWriter, r *http.Request) { // ctx := sqlcomment.WithTag(r.Context(), "route", r.URL.Path) // next.ServeHTTP(w, r.WithContext(ctx)) // } // return http.HandlerFunc(fn) // } func WithTag(ctx context.Context, key, val string) context.Context { t, ok := ctx.Value(ctxOptionsKey).(*ctxOptions) if !ok { return context.WithValue(ctx, ctxOptionsKey, &ctxOptions{tags: Tags{key: val}}) } t.tags[key] = val return ctx } // FromContext returns the tags stored in ctx, if any. func FromContext(ctx context.Context) Tags { t, ok := ctx.Value(ctxOptionsKey).(*ctxOptions) if !ok { return Tags{} } return t.tags } golang-ariga-sqlcomment-0.1.0/driver.go000066400000000000000000000111731514435236700200570ustar00rootroot00000000000000package sqlcomment import ( "context" "database/sql" "fmt" "entgo.io/ent/dialect" ) type ( // Driver is a driver that adds an SQL comment. // See: https://google.github.io/sqlcommenter. Driver struct { dialect.Driver // underlying driver. commenter } // Tx is a transaction implementation that adds an SQL comment. Tx struct { dialect.Tx // underlying transaction. ctx context.Context // underlying transaction context. commenter } commenter struct { options } ) // NewDriver decorates the given driver and adds an SQL comment to every query. func NewDriver(drv dialect.Driver, options ...Option) dialect.Driver { taggers := []Tagger{contextTagger{}} opts := buildOptions(append(options, WithTagger(taggers...))) return &Driver{drv, commenter{opts}} } func (c commenter) withComment(ctx context.Context, query string) string { tags := make(Tags) for _, h := range c.taggers { tags.Merge(h.Tag(ctx)) } return fmt.Sprintf("%s /*%s*/", query, tags.Marshal()) } // Query adds an SQL comment to the original query and calls the underlying driver Query method. func (d *Driver) Query(ctx context.Context, query string, args, v interface{}) error { return d.Driver.Query(ctx, d.withComment(ctx, query), args, v) } // QueryContext calls QueryContext of the underlying driver, or fails if it is not supported. func (d *Driver) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { drv, ok := d.Driver.(interface { QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) }) if !ok { return nil, fmt.Errorf("Driver.QueryContext is not supported") } return drv.QueryContext(ctx, d.withComment(ctx, query), args...) } // Exec adds an SQL comment to the original query and calls the underlying driver Exec method. func (d *Driver) Exec(ctx context.Context, query string, args, v interface{}) error { return d.Driver.Exec(ctx, d.withComment(ctx, query), args, v) } // ExecContext calls ExecContext of the underlying driver, or fails if it is not supported. func (d *Driver) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { drv, ok := d.Driver.(interface { ExecContext(context.Context, string, ...interface{}) (sql.Result, error) }) if !ok { return nil, fmt.Errorf("Driver.ExecContext is not supported") } return drv.ExecContext(ctx, d.withComment(ctx, query), args...) } // Tx wraps the underlying Tx command with a commenter. func (d *Driver) Tx(ctx context.Context) (dialect.Tx, error) { tx, err := d.Driver.Tx(ctx) if err != nil { return nil, err } return &Tx{tx, ctx, d.commenter}, nil } // BeginTx wraps the underlying transaction with commenter and calls the underlying driver BeginTx command if it's supported. func (d *Driver) BeginTx(ctx context.Context, opts *sql.TxOptions) (dialect.Tx, error) { drv, ok := d.Driver.(interface { BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error) }) if !ok { return nil, fmt.Errorf("Driver.BeginTx is not supported") } tx, err := drv.BeginTx(ctx, opts) if err != nil { return nil, err } return &Tx{tx, ctx, d.commenter}, nil } // Exec adds an SQL comment and calls the underlying transaction Exec method. func (d *Tx) Exec(ctx context.Context, query string, args, v interface{}) error { return d.Tx.Exec(ctx, d.withComment(ctx, query), args, v) } // ExecContext logs its params and calls the underlying transaction ExecContext method if it is supported. func (d *Tx) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) { tx, ok := d.Tx.(interface { ExecContext(context.Context, string, ...interface{}) (sql.Result, error) }) if !ok { return nil, fmt.Errorf("Tx.ExecContext is not supported") } return tx.ExecContext(ctx, d.withComment(ctx, query), args...) } // Query adds an SQL comment and calls the underlying transaction Query method. func (d *Tx) Query(ctx context.Context, query string, args, v interface{}) error { return d.Tx.Query(ctx, d.withComment(ctx, query), args, v) } // QueryContext logs its params and calls the underlying transaction QueryContext method if it is supported. func (d *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) { tx, ok := d.Tx.(interface { QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) }) if !ok { return nil, fmt.Errorf("Tx.QueryContext is not supported") } return tx.QueryContext(ctx, d.withComment(ctx, query), args...) } // Commit commits the underlying Tx. func (d *Tx) Commit() error { return d.Tx.Commit() } // Rollback rolls back the underlying Tx. func (d *Tx) Rollback() error { return d.Tx.Rollback() } golang-ariga-sqlcomment-0.1.0/examples/000077500000000000000000000000001514435236700200505ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/000077500000000000000000000000001514435236700206365ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/client.go000066400000000000000000000136761514435236700224600ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "fmt" "log" "ariga.io/sqlcomment/examples/ent/migrate" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" ) // Client is the client that holds all ent builders. type Client struct { config // Schema is the client for creating, migrating and dropping schema. Schema *migrate.Schema // User is the client for interacting with the User builders. User *UserClient } // NewClient creates a new client configured with the given options. func NewClient(opts ...Option) *Client { cfg := config{log: log.Println, hooks: &hooks{}} cfg.options(opts...) client := &Client{config: cfg} client.init() return client } func (c *Client) init() { c.Schema = migrate.NewSchema(c.driver) c.User = NewUserClient(c.config) } // Open opens a database/sql.DB specified by the driver name and // the data source name, and returns a new client attached to it. // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { case dialect.MySQL, dialect.Postgres, dialect.SQLite: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err } return NewClient(append(options, Driver(drv))...), nil default: return nil, fmt.Errorf("unsupported driver: %q", driverName) } } // Tx returns a new transactional client. The provided context // is used until the transaction is committed or rolled back. func (c *Client) Tx(ctx context.Context) (*Tx, error) { if _, ok := c.driver.(*txDriver); ok { return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") } tx, err := newTx(ctx, c.driver) if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %w", err) } cfg := c.config cfg.driver = tx return &Tx{ ctx: ctx, config: cfg, User: NewUserClient(cfg), }, nil } // BeginTx returns a transactional client with specified options. func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) { if _, ok := c.driver.(*txDriver); ok { return nil, fmt.Errorf("ent: cannot start a transaction within a transaction") } tx, err := c.driver.(interface { BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error) }).BeginTx(ctx, opts) if err != nil { return nil, fmt.Errorf("ent: starting a transaction: %w", err) } cfg := c.config cfg.driver = &txDriver{tx: tx, drv: c.driver} return &Tx{ config: cfg, User: NewUserClient(cfg), }, nil } // Debug returns a new debug-client. It's used to get verbose logging on specific operations. // // client.Debug(). // User. // Query(). // Count(ctx) // func (c *Client) Debug() *Client { if c.debug { return c } cfg := c.config cfg.driver = dialect.Debug(c.driver, c.log) client := &Client{config: cfg} client.init() return client } // Close closes the database connection and prevents new queries from starting. func (c *Client) Close() error { return c.driver.Close() } // Use adds the mutation hooks to all the entity clients. // In order to add hooks to a specific client, call: `client.Node.Use(...)`. func (c *Client) Use(hooks ...Hook) { c.User.Use(hooks...) } // UserClient is a client for the User schema. type UserClient struct { config } // NewUserClient returns a client for the User from the given config. func NewUserClient(c config) *UserClient { return &UserClient{config: c} } // Use adds a list of mutation hooks to the hooks stack. // A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. func (c *UserClient) Use(hooks ...Hook) { c.hooks.User = append(c.hooks.User, hooks...) } // Create returns a create builder for User. func (c *UserClient) Create() *UserCreate { mutation := newUserMutation(c.config, OpCreate) return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // CreateBulk returns a builder for creating a bulk of User entities. func (c *UserClient) CreateBulk(builders ...*UserCreate) *UserCreateBulk { return &UserCreateBulk{config: c.config, builders: builders} } // Update returns an update builder for User. func (c *UserClient) Update() *UserUpdate { mutation := newUserMutation(c.config, OpUpdate) return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOne returns an update builder for the given entity. func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { mutation := newUserMutation(c.config, OpUpdateOne, withUser(u)) return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // UpdateOneID returns an update builder for the given id. func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { mutation := newUserMutation(c.config, OpUpdateOne, withUserID(id)) return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} } // Delete returns a delete builder for User. func (c *UserClient) Delete() *UserDelete { mutation := newUserMutation(c.config, OpDelete) return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} } // DeleteOne returns a delete builder for the given entity. func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { return c.DeleteOneID(u.ID) } // DeleteOneID returns a delete builder for the given id. func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { builder := c.Delete().Where(user.ID(id)) builder.mutation.id = &id builder.mutation.op = OpDeleteOne return &UserDeleteOne{builder} } // Query returns a query builder for User. func (c *UserClient) Query() *UserQuery { return &UserQuery{ config: c.config, } } // Get returns a User entity by its id. func (c *UserClient) Get(ctx context.Context, id int) (*User, error) { return c.Query().Where(user.ID(id)).Only(ctx) } // GetX is like Get, but panics if an error occurs. func (c *UserClient) GetX(ctx context.Context, id int) *User { obj, err := c.Get(ctx, id) if err != nil { panic(err) } return obj } // Hooks returns the client hooks. func (c *UserClient) Hooks() []Hook { return c.hooks.User } golang-ariga-sqlcomment-0.1.0/examples/ent/config.go000066400000000000000000000022201514435236700224260ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "entgo.io/ent" "entgo.io/ent/dialect" ) // Option function to configure the client. type Option func(*config) // Config is the configuration for the client and its builder. type config struct { // driver used for executing database requests. driver dialect.Driver // debug enable a debug logging. debug bool // log used for logging on debug mode. log func(...interface{}) // hooks to execute on mutations. hooks *hooks } // hooks per client, for fast access. type hooks struct { User []ent.Hook } // Options applies the options on the config object. func (c *config) options(opts ...Option) { for _, opt := range opts { opt(c) } if c.debug { c.driver = dialect.Debug(c.driver, c.log) } } // Debug enables debug logging on the ent.Driver. func Debug() Option { return func(c *config) { c.debug = true } } // Log sets the logging function for debug mode. func Log(fn func(...interface{})) Option { return func(c *config) { c.log = fn } } // Driver configures the client driver. func Driver(driver dialect.Driver) Option { return func(c *config) { c.driver = driver } } golang-ariga-sqlcomment-0.1.0/examples/ent/context.go000066400000000000000000000015561514435236700226600ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" ) type clientCtxKey struct{} // FromContext returns a Client stored inside a context, or nil if there isn't one. func FromContext(ctx context.Context) *Client { c, _ := ctx.Value(clientCtxKey{}).(*Client) return c } // NewContext returns a new context with the given Client attached. func NewContext(parent context.Context, c *Client) context.Context { return context.WithValue(parent, clientCtxKey{}, c) } type txCtxKey struct{} // TxFromContext returns a Tx stored inside a context, or nil if there isn't one. func TxFromContext(ctx context.Context) *Tx { tx, _ := ctx.Value(txCtxKey{}).(*Tx) return tx } // NewTxContext returns a new context with the given Tx attached. func NewTxContext(parent context.Context, tx *Tx) context.Context { return context.WithValue(parent, txCtxKey{}, tx) } golang-ariga-sqlcomment-0.1.0/examples/ent/ent.go000066400000000000000000000150741514435236700217620ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "errors" "fmt" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent" "entgo.io/ent/dialect/sql" ) // ent aliases to avoid import conflicts in user's code. type ( Op = ent.Op Hook = ent.Hook Value = ent.Value Query = ent.Query Policy = ent.Policy Mutator = ent.Mutator Mutation = ent.Mutation MutateFunc = ent.MutateFunc ) // OrderFunc applies an ordering on the sql selector. type OrderFunc func(*sql.Selector) // columnChecker returns a function indicates if the column exists in the given column. func columnChecker(table string) func(string) error { checks := map[string]func(string) bool{ user.Table: user.ValidColumn, } check, ok := checks[table] if !ok { return func(string) error { return fmt.Errorf("unknown table %q", table) } } return func(column string) error { if !check(column) { return fmt.Errorf("unknown column %q for table %q", column, table) } return nil } } // Asc applies the given fields in ASC order. func Asc(fields ...string) OrderFunc { return func(s *sql.Selector) { check := columnChecker(s.TableName()) for _, f := range fields { if err := check(f); err != nil { s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) } s.OrderBy(sql.Asc(s.C(f))) } } } // Desc applies the given fields in DESC order. func Desc(fields ...string) OrderFunc { return func(s *sql.Selector) { check := columnChecker(s.TableName()) for _, f := range fields { if err := check(f); err != nil { s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) } s.OrderBy(sql.Desc(s.C(f))) } } } // AggregateFunc applies an aggregation step on the group-by traversal/selector. type AggregateFunc func(*sql.Selector) string // As is a pseudo aggregation function for renaming another other functions with custom names. For example: // // GroupBy(field1, field2). // Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). // Scan(ctx, &v) // func As(fn AggregateFunc, end string) AggregateFunc { return func(s *sql.Selector) string { return sql.As(fn(s), end) } } // Count applies the "count" aggregation function on each group. func Count() AggregateFunc { return func(s *sql.Selector) string { return sql.Count("*") } } // Max applies the "max" aggregation function on the given field of each group. func Max(field string) AggregateFunc { return func(s *sql.Selector) string { check := columnChecker(s.TableName()) if err := check(field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) return "" } return sql.Max(s.C(field)) } } // Mean applies the "mean" aggregation function on the given field of each group. func Mean(field string) AggregateFunc { return func(s *sql.Selector) string { check := columnChecker(s.TableName()) if err := check(field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) return "" } return sql.Avg(s.C(field)) } } // Min applies the "min" aggregation function on the given field of each group. func Min(field string) AggregateFunc { return func(s *sql.Selector) string { check := columnChecker(s.TableName()) if err := check(field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) return "" } return sql.Min(s.C(field)) } } // Sum applies the "sum" aggregation function on the given field of each group. func Sum(field string) AggregateFunc { return func(s *sql.Selector) string { check := columnChecker(s.TableName()) if err := check(field); err != nil { s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) return "" } return sql.Sum(s.C(field)) } } // ValidationError returns when validating a field fails. type ValidationError struct { Name string // Field or edge name. err error } // Error implements the error interface. func (e *ValidationError) Error() string { return e.err.Error() } // Unwrap implements the errors.Wrapper interface. func (e *ValidationError) Unwrap() error { return e.err } // IsValidationError returns a boolean indicating whether the error is a validation error. func IsValidationError(err error) bool { if err == nil { return false } var e *ValidationError return errors.As(err, &e) } // NotFoundError returns when trying to fetch a specific entity and it was not found in the database. type NotFoundError struct { label string } // Error implements the error interface. func (e *NotFoundError) Error() string { return "ent: " + e.label + " not found" } // IsNotFound returns a boolean indicating whether the error is a not found error. func IsNotFound(err error) bool { if err == nil { return false } var e *NotFoundError return errors.As(err, &e) } // MaskNotFound masks not found error. func MaskNotFound(err error) error { if IsNotFound(err) { return nil } return err } // NotSingularError returns when trying to fetch a singular entity and more then one was found in the database. type NotSingularError struct { label string } // Error implements the error interface. func (e *NotSingularError) Error() string { return "ent: " + e.label + " not singular" } // IsNotSingular returns a boolean indicating whether the error is a not singular error. func IsNotSingular(err error) bool { if err == nil { return false } var e *NotSingularError return errors.As(err, &e) } // NotLoadedError returns when trying to get a node that was not loaded by the query. type NotLoadedError struct { edge string } // Error implements the error interface. func (e *NotLoadedError) Error() string { return "ent: " + e.edge + " edge was not loaded" } // IsNotLoaded returns a boolean indicating whether the error is a not loaded error. func IsNotLoaded(err error) bool { if err == nil { return false } var e *NotLoadedError return errors.As(err, &e) } // ConstraintError returns when trying to create/update one or more entities and // one or more of their constraints failed. For example, violation of edge or // field uniqueness. type ConstraintError struct { msg string wrap error } // Error implements the error interface. func (e ConstraintError) Error() string { return "ent: constraint failed: " + e.msg } // Unwrap implements the errors.Wrapper interface. func (e *ConstraintError) Unwrap() error { return e.wrap } // IsConstraintError returns a boolean indicating whether the error is a constraint failure. func IsConstraintError(err error) bool { if err == nil { return false } var e *ConstraintError return errors.As(err, &e) } golang-ariga-sqlcomment-0.1.0/examples/ent/enttest/000077500000000000000000000000001514435236700223245ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/enttest/enttest.go000066400000000000000000000032651514435236700243470ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package enttest import ( "context" "ariga.io/sqlcomment/examples/ent" // required by schema hooks. _ "ariga.io/sqlcomment/examples/ent/runtime" "entgo.io/ent/dialect/sql/schema" ) type ( // TestingT is the interface that is shared between // testing.T and testing.B and used by enttest. TestingT interface { FailNow() Error(...interface{}) } // Option configures client creation. Option func(*options) options struct { opts []ent.Option migrateOpts []schema.MigrateOption } ) // WithOptions forwards options to client creation. func WithOptions(opts ...ent.Option) Option { return func(o *options) { o.opts = append(o.opts, opts...) } } // WithMigrateOptions forwards options to auto migration. func WithMigrateOptions(opts ...schema.MigrateOption) Option { return func(o *options) { o.migrateOpts = append(o.migrateOpts, opts...) } } func newOptions(opts []Option) *options { o := &options{} for _, opt := range opts { opt(o) } return o } // Open calls ent.Open and auto-run migration. func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client { o := newOptions(opts) c, err := ent.Open(driverName, dataSourceName, o.opts...) if err != nil { t.Error(err) t.FailNow() } if err := c.Schema.Create(context.Background(), o.migrateOpts...); err != nil { t.Error(err) t.FailNow() } return c } // NewClient calls ent.NewClient and auto-run migration. func NewClient(t TestingT, opts ...Option) *ent.Client { o := newOptions(opts) c := ent.NewClient(o.opts...) if err := c.Schema.Create(context.Background(), o.migrateOpts...); err != nil { t.Error(err) t.FailNow() } return c } golang-ariga-sqlcomment-0.1.0/examples/ent/generate.go000066400000000000000000000001221514435236700227520ustar00rootroot00000000000000package ent //go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema golang-ariga-sqlcomment-0.1.0/examples/ent/hook/000077500000000000000000000000001514435236700215765ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/hook/hook.go000066400000000000000000000120041514435236700230620ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package hook import ( "context" "fmt" "ariga.io/sqlcomment/examples/ent" ) // The UserFunc type is an adapter to allow the use of ordinary // function as User mutator. type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) // Mutate calls f(ctx, m). func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { mv, ok := m.(*ent.UserMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", m) } return f(ctx, mv) } // Condition is a hook condition function. type Condition func(context.Context, ent.Mutation) bool // And groups conditions with the AND operator. func And(first, second Condition, rest ...Condition) Condition { return func(ctx context.Context, m ent.Mutation) bool { if !first(ctx, m) || !second(ctx, m) { return false } for _, cond := range rest { if !cond(ctx, m) { return false } } return true } } // Or groups conditions with the OR operator. func Or(first, second Condition, rest ...Condition) Condition { return func(ctx context.Context, m ent.Mutation) bool { if first(ctx, m) || second(ctx, m) { return true } for _, cond := range rest { if cond(ctx, m) { return true } } return false } } // Not negates a given condition. func Not(cond Condition) Condition { return func(ctx context.Context, m ent.Mutation) bool { return !cond(ctx, m) } } // HasOp is a condition testing mutation operation. func HasOp(op ent.Op) Condition { return func(_ context.Context, m ent.Mutation) bool { return m.Op().Is(op) } } // HasAddedFields is a condition validating `.AddedField` on fields. func HasAddedFields(field string, fields ...string) Condition { return func(_ context.Context, m ent.Mutation) bool { if _, exists := m.AddedField(field); !exists { return false } for _, field := range fields { if _, exists := m.AddedField(field); !exists { return false } } return true } } // HasClearedFields is a condition validating `.FieldCleared` on fields. func HasClearedFields(field string, fields ...string) Condition { return func(_ context.Context, m ent.Mutation) bool { if exists := m.FieldCleared(field); !exists { return false } for _, field := range fields { if exists := m.FieldCleared(field); !exists { return false } } return true } } // HasFields is a condition validating `.Field` on fields. func HasFields(field string, fields ...string) Condition { return func(_ context.Context, m ent.Mutation) bool { if _, exists := m.Field(field); !exists { return false } for _, field := range fields { if _, exists := m.Field(field); !exists { return false } } return true } } // If executes the given hook under condition. // // hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...))) // func If(hk ent.Hook, cond Condition) ent.Hook { return func(next ent.Mutator) ent.Mutator { return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { if cond(ctx, m) { return hk(next).Mutate(ctx, m) } return next.Mutate(ctx, m) }) } } // On executes the given hook only for the given operation. // // hook.On(Log, ent.Delete|ent.Create) // func On(hk ent.Hook, op ent.Op) ent.Hook { return If(hk, HasOp(op)) } // Unless skips the given hook only for the given operation. // // hook.Unless(Log, ent.Update|ent.UpdateOne) // func Unless(hk ent.Hook, op ent.Op) ent.Hook { return If(hk, Not(HasOp(op))) } // FixedError is a hook returning a fixed error. func FixedError(err error) ent.Hook { return func(ent.Mutator) ent.Mutator { return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) { return nil, err }) } } // Reject returns a hook that rejects all operations that match op. // // func (T) Hooks() []ent.Hook { // return []ent.Hook{ // Reject(ent.Delete|ent.Update), // } // } // func Reject(op ent.Op) ent.Hook { hk := FixedError(fmt.Errorf("%s operation is not allowed", op)) return On(hk, op) } // Chain acts as a list of hooks and is effectively immutable. // Once created, it will always hold the same set of hooks in the same order. type Chain struct { hooks []ent.Hook } // NewChain creates a new chain of hooks. func NewChain(hooks ...ent.Hook) Chain { return Chain{append([]ent.Hook(nil), hooks...)} } // Hook chains the list of hooks and returns the final hook. func (c Chain) Hook() ent.Hook { return func(mutator ent.Mutator) ent.Mutator { for i := len(c.hooks) - 1; i >= 0; i-- { mutator = c.hooks[i](mutator) } return mutator } } // Append extends a chain, adding the specified hook // as the last ones in the mutation flow. func (c Chain) Append(hooks ...ent.Hook) Chain { newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks)) newHooks = append(newHooks, c.hooks...) newHooks = append(newHooks, hooks...) return Chain{newHooks} } // Extend extends a chain, adding the specified chain // as the last ones in the mutation flow. func (c Chain) Extend(chain Chain) Chain { return c.Append(chain.hooks...) } golang-ariga-sqlcomment-0.1.0/examples/ent/migrate/000077500000000000000000000000001514435236700222665ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/migrate/migrate.go000066400000000000000000000046421514435236700242530ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package migrate import ( "context" "fmt" "io" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql/schema" ) var ( // WithGlobalUniqueID sets the universal ids options to the migration. // If this option is enabled, ent migration will allocate a 1<<32 range // for the ids of each entity (table). // Note that this option cannot be applied on tables that already exist. WithGlobalUniqueID = schema.WithGlobalUniqueID // WithDropColumn sets the drop column option to the migration. // If this option is enabled, ent migration will drop old columns // that were used for both fields and edges. This defaults to false. WithDropColumn = schema.WithDropColumn // WithDropIndex sets the drop index option to the migration. // If this option is enabled, ent migration will drop old indexes // that were defined in the schema. This defaults to false. // Note that unique constraints are defined using `UNIQUE INDEX`, // and therefore, it's recommended to enable this option to get more // flexibility in the schema changes. WithDropIndex = schema.WithDropIndex // WithFixture sets the foreign-key renaming option to the migration when upgrading // ent from v0.1.0 (issue-#285). Defaults to false. WithFixture = schema.WithFixture // WithForeignKeys enables creating foreign-key in schema DDL. This defaults to true. WithForeignKeys = schema.WithForeignKeys ) // Schema is the API for creating, migrating and dropping a schema. type Schema struct { drv dialect.Driver universalID bool } // NewSchema creates a new schema client. func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } // Create creates all schema resources. func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { migrate, err := schema.NewMigrate(s.drv, opts...) if err != nil { return fmt.Errorf("ent/migrate: %w", err) } return migrate.Create(ctx, Tables...) } // WriteTo writes the schema changes to w instead of running them against the database. // // if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { // log.Fatal(err) // } // func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { drv := &schema.WriteDriver{ Writer: w, Driver: s.drv, } migrate, err := schema.NewMigrate(drv, opts...) if err != nil { return fmt.Errorf("ent/migrate: %w", err) } return migrate.Create(ctx, Tables...) } golang-ariga-sqlcomment-0.1.0/examples/ent/migrate/schema.go000066400000000000000000000012001514435236700240460ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package migrate import ( "entgo.io/ent/dialect/sql/schema" "entgo.io/ent/schema/field" ) var ( // UsersColumns holds the columns for the "users" table. UsersColumns = []*schema.Column{ {Name: "id", Type: field.TypeInt, Increment: true}, {Name: "name", Type: field.TypeString}, } // UsersTable holds the schema information for the "users" table. UsersTable = &schema.Table{ Name: "users", Columns: UsersColumns, PrimaryKey: []*schema.Column{UsersColumns[0]}, } // Tables holds all the tables in the schema. Tables = []*schema.Table{ UsersTable, } ) func init() { } golang-ariga-sqlcomment-0.1.0/examples/ent/mutation.go000066400000000000000000000214761514435236700230370ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "fmt" "sync" "ariga.io/sqlcomment/examples/ent/predicate" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent" ) const ( // Operation types. OpCreate = ent.OpCreate OpDelete = ent.OpDelete OpDeleteOne = ent.OpDeleteOne OpUpdate = ent.OpUpdate OpUpdateOne = ent.OpUpdateOne // Node types. TypeUser = "User" ) // UserMutation represents an operation that mutates the User nodes in the graph. type UserMutation struct { config op Op typ string id *int name *string clearedFields map[string]struct{} done bool oldValue func(context.Context) (*User, error) predicates []predicate.User } var _ ent.Mutation = (*UserMutation)(nil) // userOption allows management of the mutation configuration using functional options. type userOption func(*UserMutation) // newUserMutation creates new mutation for the User entity. func newUserMutation(c config, op Op, opts ...userOption) *UserMutation { m := &UserMutation{ config: c, op: op, typ: TypeUser, clearedFields: make(map[string]struct{}), } for _, opt := range opts { opt(m) } return m } // withUserID sets the ID field of the mutation. func withUserID(id int) userOption { return func(m *UserMutation) { var ( err error once sync.Once value *User ) m.oldValue = func(ctx context.Context) (*User, error) { once.Do(func() { if m.done { err = fmt.Errorf("querying old values post mutation is not allowed") } else { value, err = m.Client().User.Get(ctx, id) } }) return value, err } m.id = &id } } // withUser sets the old User of the mutation. func withUser(node *User) userOption { return func(m *UserMutation) { m.oldValue = func(context.Context) (*User, error) { return node, nil } m.id = &node.ID } } // Client returns a new `ent.Client` from the mutation. If the mutation was // executed in a transaction (ent.Tx), a transactional client is returned. func (m UserMutation) Client() *Client { client := &Client{config: m.config} client.init() return client } // Tx returns an `ent.Tx` for mutations that were executed in transactions; // it returns an error otherwise. func (m UserMutation) Tx() (*Tx, error) { if _, ok := m.driver.(*txDriver); !ok { return nil, fmt.Errorf("ent: mutation is not running in a transaction") } tx := &Tx{config: m.config} tx.init() return tx, nil } // ID returns the ID value in the mutation. Note that the ID is only available // if it was provided to the builder or after it was returned from the database. func (m *UserMutation) ID() (id int, exists bool) { if m.id == nil { return } return *m.id, true } // SetName sets the "name" field. func (m *UserMutation) SetName(s string) { m.name = &s } // Name returns the value of the "name" field in the mutation. func (m *UserMutation) Name() (r string, exists bool) { v := m.name if v == nil { return } return *v, true } // OldName returns the old "name" field's value of the User entity. // If the User object wasn't provided to the builder, the object is fetched from the database. // An error is returned if the mutation operation is not UpdateOne, or the database query fails. func (m *UserMutation) OldName(ctx context.Context) (v string, err error) { if !m.op.Is(OpUpdateOne) { return v, fmt.Errorf("OldName is only allowed on UpdateOne operations") } if m.id == nil || m.oldValue == nil { return v, fmt.Errorf("OldName requires an ID field in the mutation") } oldValue, err := m.oldValue(ctx) if err != nil { return v, fmt.Errorf("querying old value for OldName: %w", err) } return oldValue.Name, nil } // ResetName resets all changes to the "name" field. func (m *UserMutation) ResetName() { m.name = nil } // Where appends a list predicates to the UserMutation builder. func (m *UserMutation) Where(ps ...predicate.User) { m.predicates = append(m.predicates, ps...) } // Op returns the operation name. func (m *UserMutation) Op() Op { return m.op } // Type returns the node type of this mutation (User). func (m *UserMutation) Type() string { return m.typ } // Fields returns all fields that were changed during this mutation. Note that in // order to get all numeric fields that were incremented/decremented, call // AddedFields(). func (m *UserMutation) Fields() []string { fields := make([]string, 0, 1) if m.name != nil { fields = append(fields, user.FieldName) } return fields } // Field returns the value of a field with the given name. The second boolean // return value indicates that this field was not set, or was not defined in the // schema. func (m *UserMutation) Field(name string) (ent.Value, bool) { switch name { case user.FieldName: return m.Name() } return nil, false } // OldField returns the old value of the field from the database. An error is // returned if the mutation operation is not UpdateOne, or the query to the // database failed. func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, error) { switch name { case user.FieldName: return m.OldName(ctx) } return nil, fmt.Errorf("unknown User field %s", name) } // SetField sets the value of a field with the given name. It returns an error if // the field is not defined in the schema, or if the type mismatched the field // type. func (m *UserMutation) SetField(name string, value ent.Value) error { switch name { case user.FieldName: v, ok := value.(string) if !ok { return fmt.Errorf("unexpected type %T for field %s", value, name) } m.SetName(v) return nil } return fmt.Errorf("unknown User field %s", name) } // AddedFields returns all numeric fields that were incremented/decremented during // this mutation. func (m *UserMutation) AddedFields() []string { return nil } // AddedField returns the numeric value that was incremented/decremented on a field // with the given name. The second boolean return value indicates that this field // was not set, or was not defined in the schema. func (m *UserMutation) AddedField(name string) (ent.Value, bool) { return nil, false } // AddField adds the value to the field with the given name. It returns an error if // the field is not defined in the schema, or if the type mismatched the field // type. func (m *UserMutation) AddField(name string, value ent.Value) error { switch name { } return fmt.Errorf("unknown User numeric field %s", name) } // ClearedFields returns all nullable fields that were cleared during this // mutation. func (m *UserMutation) ClearedFields() []string { return nil } // FieldCleared returns a boolean indicating if a field with the given name was // cleared in this mutation. func (m *UserMutation) FieldCleared(name string) bool { _, ok := m.clearedFields[name] return ok } // ClearField clears the value of the field with the given name. It returns an // error if the field is not defined in the schema. func (m *UserMutation) ClearField(name string) error { return fmt.Errorf("unknown User nullable field %s", name) } // ResetField resets all changes in the mutation for the field with the given name. // It returns an error if the field is not defined in the schema. func (m *UserMutation) ResetField(name string) error { switch name { case user.FieldName: m.ResetName() return nil } return fmt.Errorf("unknown User field %s", name) } // AddedEdges returns all edge names that were set/added in this mutation. func (m *UserMutation) AddedEdges() []string { edges := make([]string, 0, 0) return edges } // AddedIDs returns all IDs (to other nodes) that were added for the given edge // name in this mutation. func (m *UserMutation) AddedIDs(name string) []ent.Value { return nil } // RemovedEdges returns all edge names that were removed in this mutation. func (m *UserMutation) RemovedEdges() []string { edges := make([]string, 0, 0) return edges } // RemovedIDs returns all IDs (to other nodes) that were removed for the edge with // the given name in this mutation. func (m *UserMutation) RemovedIDs(name string) []ent.Value { return nil } // ClearedEdges returns all edge names that were cleared in this mutation. func (m *UserMutation) ClearedEdges() []string { edges := make([]string, 0, 0) return edges } // EdgeCleared returns a boolean which indicates if the edge with the given name // was cleared in this mutation. func (m *UserMutation) EdgeCleared(name string) bool { return false } // ClearEdge clears the value of the edge with the given name. It returns an error // if that edge is not defined in the schema. func (m *UserMutation) ClearEdge(name string) error { return fmt.Errorf("unknown User unique edge %s", name) } // ResetEdge resets all changes to the edge with the given name in this mutation. // It returns an error if the edge is not defined in the schema. func (m *UserMutation) ResetEdge(name string) error { return fmt.Errorf("unknown User edge %s", name) } golang-ariga-sqlcomment-0.1.0/examples/ent/predicate/000077500000000000000000000000001514435236700225765ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/predicate/predicate.go000066400000000000000000000002671514435236700250720ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package predicate import ( "entgo.io/ent/dialect/sql" ) // User is the predicate function for user builders. type User func(*sql.Selector) golang-ariga-sqlcomment-0.1.0/examples/ent/runtime.go000066400000000000000000000003551514435236700226530ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent // The init function reads all schema descriptors with runtime code // (default values, validators, hooks and policies) and stitches it // to their package variables. func init() { } golang-ariga-sqlcomment-0.1.0/examples/ent/runtime/000077500000000000000000000000001514435236700223215ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/runtime/runtime.go000066400000000000000000000005131514435236700243320ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package runtime // The schema-stitching logic is generated in ariga.io/sqlcomment/examples/ent/runtime.go const ( Version = "v0.9.2-0.20210821141344-368a8f7a2e9a" // Version of ent codegen. Sum = "h1:ONZ5BfDxYM5/YMv6cceUXLAkxtCPNSNBUXyVBg6YucU=" // Sum of ent codegen. ) golang-ariga-sqlcomment-0.1.0/examples/ent/schema/000077500000000000000000000000001514435236700220765ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/schema/user.go000066400000000000000000000004201514435236700233770ustar00rootroot00000000000000package schema import ( "entgo.io/ent" "entgo.io/ent/schema/field" ) // User holds the schema definition for the User entity. type User struct { ent.Schema } // Fields of the User. func (User) Fields() []ent.Field { return []ent.Field{ field.String("name"), } } golang-ariga-sqlcomment-0.1.0/examples/ent/tx.go000066400000000000000000000137201514435236700216230ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "sync" "entgo.io/ent/dialect" ) // Tx is a transactional client that is created by calling Client.Tx(). type Tx struct { config // User is the client for interacting with the User builders. User *UserClient // lazily loaded. client *Client clientOnce sync.Once // completion callbacks. mu sync.Mutex onCommit []CommitHook onRollback []RollbackHook // ctx lives for the life of the transaction. It is // the same context used by the underlying connection. ctx context.Context } type ( // Committer is the interface that wraps the Committer method. Committer interface { Commit(context.Context, *Tx) error } // The CommitFunc type is an adapter to allow the use of ordinary // function as a Committer. If f is a function with the appropriate // signature, CommitFunc(f) is a Committer that calls f. CommitFunc func(context.Context, *Tx) error // CommitHook defines the "commit middleware". A function that gets a Committer // and returns a Committer. For example: // // hook := func(next ent.Committer) ent.Committer { // return ent.CommitFunc(func(context.Context, tx *ent.Tx) error { // // Do some stuff before. // if err := next.Commit(ctx, tx); err != nil { // return err // } // // Do some stuff after. // return nil // }) // } // CommitHook func(Committer) Committer ) // Commit calls f(ctx, m). func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error { return f(ctx, tx) } // Commit commits the transaction. func (tx *Tx) Commit() error { txDriver := tx.config.driver.(*txDriver) var fn Committer = CommitFunc(func(context.Context, *Tx) error { return txDriver.tx.Commit() }) tx.mu.Lock() hooks := append([]CommitHook(nil), tx.onCommit...) tx.mu.Unlock() for i := len(hooks) - 1; i >= 0; i-- { fn = hooks[i](fn) } return fn.Commit(tx.ctx, tx) } // OnCommit adds a hook to call on commit. func (tx *Tx) OnCommit(f CommitHook) { tx.mu.Lock() defer tx.mu.Unlock() tx.onCommit = append(tx.onCommit, f) } type ( // Rollbacker is the interface that wraps the Rollbacker method. Rollbacker interface { Rollback(context.Context, *Tx) error } // The RollbackFunc type is an adapter to allow the use of ordinary // function as a Rollbacker. If f is a function with the appropriate // signature, RollbackFunc(f) is a Rollbacker that calls f. RollbackFunc func(context.Context, *Tx) error // RollbackHook defines the "rollback middleware". A function that gets a Rollbacker // and returns a Rollbacker. For example: // // hook := func(next ent.Rollbacker) ent.Rollbacker { // return ent.RollbackFunc(func(context.Context, tx *ent.Tx) error { // // Do some stuff before. // if err := next.Rollback(ctx, tx); err != nil { // return err // } // // Do some stuff after. // return nil // }) // } // RollbackHook func(Rollbacker) Rollbacker ) // Rollback calls f(ctx, m). func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error { return f(ctx, tx) } // Rollback rollbacks the transaction. func (tx *Tx) Rollback() error { txDriver := tx.config.driver.(*txDriver) var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error { return txDriver.tx.Rollback() }) tx.mu.Lock() hooks := append([]RollbackHook(nil), tx.onRollback...) tx.mu.Unlock() for i := len(hooks) - 1; i >= 0; i-- { fn = hooks[i](fn) } return fn.Rollback(tx.ctx, tx) } // OnRollback adds a hook to call on rollback. func (tx *Tx) OnRollback(f RollbackHook) { tx.mu.Lock() defer tx.mu.Unlock() tx.onRollback = append(tx.onRollback, f) } // Client returns a Client that binds to current transaction. func (tx *Tx) Client() *Client { tx.clientOnce.Do(func() { tx.client = &Client{config: tx.config} tx.client.init() }) return tx.client } func (tx *Tx) init() { tx.User = NewUserClient(tx.config) } // txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. // The idea is to support transactions without adding any extra code to the builders. // When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. // Commit and Rollback are nop for the internal builders and the user must call one // of them in order to commit or rollback the transaction. // // If a closed transaction is embedded in one of the generated entities, and the entity // applies a query, for example: User.QueryXXX(), the query will be executed // through the driver which created this transaction. // // Note that txDriver is not goroutine safe. type txDriver struct { // the driver we started the transaction from. drv dialect.Driver // tx is the underlying transaction. tx dialect.Tx } // newTx creates a new transactional driver. func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { tx, err := drv.Tx(ctx) if err != nil { return nil, err } return &txDriver{tx: tx, drv: drv}, nil } // Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls // from the internal builders. Should be called only by the internal builders. func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } // Dialect returns the dialect of the driver we started the transaction from. func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } // Close is a nop close. func (*txDriver) Close() error { return nil } // Commit is a nop commit for the internal builders. // User must call `Tx.Commit` in order to commit the transaction. func (*txDriver) Commit() error { return nil } // Rollback is a nop rollback for the internal builders. // User must call `Tx.Rollback` in order to rollback the transaction. func (*txDriver) Rollback() error { return nil } // Exec calls tx.Exec. func (tx *txDriver) Exec(ctx context.Context, query string, args, v interface{}) error { return tx.tx.Exec(ctx, query, args, v) } // Query calls tx.Query. func (tx *txDriver) Query(ctx context.Context, query string, args, v interface{}) error { return tx.tx.Query(ctx, query, args, v) } var _ dialect.Driver = (*txDriver)(nil) golang-ariga-sqlcomment-0.1.0/examples/ent/user.go000066400000000000000000000052141514435236700221450ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "fmt" "strings" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent/dialect/sql" ) // User is the model entity for the User schema. type User struct { config `json:"-"` // ID of the ent. ID int `json:"id,omitempty"` // Name holds the value of the "name" field. Name string `json:"name,omitempty"` } // scanValues returns the types for scanning values from sql.Rows. func (*User) scanValues(columns []string) ([]interface{}, error) { values := make([]interface{}, len(columns)) for i := range columns { switch columns[i] { case user.FieldID: values[i] = new(sql.NullInt64) case user.FieldName: values[i] = new(sql.NullString) default: return nil, fmt.Errorf("unexpected column %q for type User", columns[i]) } } return values, nil } // assignValues assigns the values that were returned from sql.Rows (after scanning) // to the User fields. func (u *User) assignValues(columns []string, values []interface{}) error { if m, n := len(values), len(columns); m < n { return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) } for i := range columns { switch columns[i] { case user.FieldID: value, ok := values[i].(*sql.NullInt64) if !ok { return fmt.Errorf("unexpected type %T for field id", value) } u.ID = int(value.Int64) case user.FieldName: if value, ok := values[i].(*sql.NullString); !ok { return fmt.Errorf("unexpected type %T for field name", values[i]) } else if value.Valid { u.Name = value.String } } } return nil } // Update returns a builder for updating this User. // Note that you need to call User.Unwrap() before calling this method if this User // was returned from a transaction, and the transaction was committed or rolled back. func (u *User) Update() *UserUpdateOne { return (&UserClient{config: u.config}).UpdateOne(u) } // Unwrap unwraps the User entity that was returned from a transaction after it was closed, // so that all future queries will be executed through the driver which created the transaction. func (u *User) Unwrap() *User { tx, ok := u.config.driver.(*txDriver) if !ok { panic("ent: User is not a transactional entity") } u.config.driver = tx.drv return u } // String implements the fmt.Stringer. func (u *User) String() string { var builder strings.Builder builder.WriteString("User(") builder.WriteString(fmt.Sprintf("id=%v", u.ID)) builder.WriteString(", name=") builder.WriteString(u.Name) builder.WriteByte(')') return builder.String() } // Users is a parsable slice of User. type Users []*User func (u Users) config(cfg config) { for _i := range u { u[_i].config = cfg } } golang-ariga-sqlcomment-0.1.0/examples/ent/user/000077500000000000000000000000001514435236700216145ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/ent/user/user.go000066400000000000000000000013161514435236700231220ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package user const ( // Label holds the string label denoting the user type in the database. Label = "user" // FieldID holds the string denoting the id field in the database. FieldID = "id" // FieldName holds the string denoting the name field in the database. FieldName = "name" // Table holds the table name of the user in the database. Table = "users" ) // Columns holds all SQL columns for user fields. var Columns = []string{ FieldID, FieldName, } // ValidColumn reports if the column name is valid (part of the table columns). func ValidColumn(column string) bool { for i := range Columns { if column == Columns[i] { return true } } return false } golang-ariga-sqlcomment-0.1.0/examples/ent/user/where.go000066400000000000000000000143441514435236700232630ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package user import ( "ariga.io/sqlcomment/examples/ent/predicate" "entgo.io/ent/dialect/sql" ) // ID filters vertices based on their ID field. func ID(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.EQ(s.C(FieldID), id)) }) } // IDEQ applies the EQ predicate on the ID field. func IDEQ(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.EQ(s.C(FieldID), id)) }) } // IDNEQ applies the NEQ predicate on the ID field. func IDNEQ(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.NEQ(s.C(FieldID), id)) }) } // IDIn applies the In predicate on the ID field. func IDIn(ids ...int) predicate.User { return predicate.User(func(s *sql.Selector) { // if not arguments were provided, append the FALSE constants, // since we can't apply "IN ()". This will make this predicate falsy. if len(ids) == 0 { s.Where(sql.False()) return } v := make([]interface{}, len(ids)) for i := range v { v[i] = ids[i] } s.Where(sql.In(s.C(FieldID), v...)) }) } // IDNotIn applies the NotIn predicate on the ID field. func IDNotIn(ids ...int) predicate.User { return predicate.User(func(s *sql.Selector) { // if not arguments were provided, append the FALSE constants, // since we can't apply "IN ()". This will make this predicate falsy. if len(ids) == 0 { s.Where(sql.False()) return } v := make([]interface{}, len(ids)) for i := range v { v[i] = ids[i] } s.Where(sql.NotIn(s.C(FieldID), v...)) }) } // IDGT applies the GT predicate on the ID field. func IDGT(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.GT(s.C(FieldID), id)) }) } // IDGTE applies the GTE predicate on the ID field. func IDGTE(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.GTE(s.C(FieldID), id)) }) } // IDLT applies the LT predicate on the ID field. func IDLT(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.LT(s.C(FieldID), id)) }) } // IDLTE applies the LTE predicate on the ID field. func IDLTE(id int) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.LTE(s.C(FieldID), id)) }) } // Name applies equality check predicate on the "name" field. It's identical to NameEQ. func Name(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.EQ(s.C(FieldName), v)) }) } // NameEQ applies the EQ predicate on the "name" field. func NameEQ(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.EQ(s.C(FieldName), v)) }) } // NameNEQ applies the NEQ predicate on the "name" field. func NameNEQ(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.NEQ(s.C(FieldName), v)) }) } // NameIn applies the In predicate on the "name" field. func NameIn(vs ...string) predicate.User { v := make([]interface{}, len(vs)) for i := range v { v[i] = vs[i] } return predicate.User(func(s *sql.Selector) { // if not arguments were provided, append the FALSE constants, // since we can't apply "IN ()". This will make this predicate falsy. if len(v) == 0 { s.Where(sql.False()) return } s.Where(sql.In(s.C(FieldName), v...)) }) } // NameNotIn applies the NotIn predicate on the "name" field. func NameNotIn(vs ...string) predicate.User { v := make([]interface{}, len(vs)) for i := range v { v[i] = vs[i] } return predicate.User(func(s *sql.Selector) { // if not arguments were provided, append the FALSE constants, // since we can't apply "IN ()". This will make this predicate falsy. if len(v) == 0 { s.Where(sql.False()) return } s.Where(sql.NotIn(s.C(FieldName), v...)) }) } // NameGT applies the GT predicate on the "name" field. func NameGT(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.GT(s.C(FieldName), v)) }) } // NameGTE applies the GTE predicate on the "name" field. func NameGTE(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.GTE(s.C(FieldName), v)) }) } // NameLT applies the LT predicate on the "name" field. func NameLT(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.LT(s.C(FieldName), v)) }) } // NameLTE applies the LTE predicate on the "name" field. func NameLTE(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.LTE(s.C(FieldName), v)) }) } // NameContains applies the Contains predicate on the "name" field. func NameContains(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.Contains(s.C(FieldName), v)) }) } // NameHasPrefix applies the HasPrefix predicate on the "name" field. func NameHasPrefix(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.HasPrefix(s.C(FieldName), v)) }) } // NameHasSuffix applies the HasSuffix predicate on the "name" field. func NameHasSuffix(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.HasSuffix(s.C(FieldName), v)) }) } // NameEqualFold applies the EqualFold predicate on the "name" field. func NameEqualFold(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.EqualFold(s.C(FieldName), v)) }) } // NameContainsFold applies the ContainsFold predicate on the "name" field. func NameContainsFold(v string) predicate.User { return predicate.User(func(s *sql.Selector) { s.Where(sql.ContainsFold(s.C(FieldName), v)) }) } // And groups predicates with the AND operator between them. func And(predicates ...predicate.User) predicate.User { return predicate.User(func(s *sql.Selector) { s1 := s.Clone().SetP(nil) for _, p := range predicates { p(s1) } s.Where(s1.P()) }) } // Or groups predicates with the OR operator between them. func Or(predicates ...predicate.User) predicate.User { return predicate.User(func(s *sql.Selector) { s1 := s.Clone().SetP(nil) for i, p := range predicates { if i > 0 { s1.Or() } p(s1) } s.Where(s1.P()) }) } // Not applies the not operator on the given predicate. func Not(p predicate.User) predicate.User { return predicate.User(func(s *sql.Selector) { p(s.Not()) }) } golang-ariga-sqlcomment-0.1.0/examples/ent/user_create.go000066400000000000000000000125211514435236700234670ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "errors" "fmt" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" ) // UserCreate is the builder for creating a User entity. type UserCreate struct { config mutation *UserMutation hooks []Hook } // SetName sets the "name" field. func (uc *UserCreate) SetName(s string) *UserCreate { uc.mutation.SetName(s) return uc } // Mutation returns the UserMutation object of the builder. func (uc *UserCreate) Mutation() *UserMutation { return uc.mutation } // Save creates the User in the database. func (uc *UserCreate) Save(ctx context.Context) (*User, error) { var ( err error node *User ) if len(uc.hooks) == 0 { if err = uc.check(); err != nil { return nil, err } node, err = uc.sqlSave(ctx) } else { var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*UserMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T", m) } if err = uc.check(); err != nil { return nil, err } uc.mutation = mutation if node, err = uc.sqlSave(ctx); err != nil { return nil, err } mutation.id = &node.ID mutation.done = true return node, err }) for i := len(uc.hooks) - 1; i >= 0; i-- { if uc.hooks[i] == nil { return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") } mut = uc.hooks[i](mut) } if _, err := mut.Mutate(ctx, uc.mutation); err != nil { return nil, err } } return node, err } // SaveX calls Save and panics if Save returns an error. func (uc *UserCreate) SaveX(ctx context.Context) *User { v, err := uc.Save(ctx) if err != nil { panic(err) } return v } // Exec executes the query. func (uc *UserCreate) Exec(ctx context.Context) error { _, err := uc.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. func (uc *UserCreate) ExecX(ctx context.Context) { if err := uc.Exec(ctx); err != nil { panic(err) } } // check runs all checks and user-defined validators on the builder. func (uc *UserCreate) check() error { if _, ok := uc.mutation.Name(); !ok { return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "name"`)} } return nil } func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { _node, _spec := uc.createSpec() if err := sqlgraph.CreateNode(ctx, uc.driver, _spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{err.Error(), err} } return nil, err } id := _spec.ID.Value.(int64) _node.ID = int(id) return _node, nil } func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { var ( _node = &User{config: uc.config} _spec = &sqlgraph.CreateSpec{ Table: user.Table, ID: &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldID, }, } ) if value, ok := uc.mutation.Name(); ok { _spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{ Type: field.TypeString, Value: value, Column: user.FieldName, }) _node.Name = value } return _node, _spec } // UserCreateBulk is the builder for creating many User entities in bulk. type UserCreateBulk struct { config builders []*UserCreate } // Save creates the User entities in the database. func (ucb *UserCreateBulk) Save(ctx context.Context) ([]*User, error) { specs := make([]*sqlgraph.CreateSpec, len(ucb.builders)) nodes := make([]*User, len(ucb.builders)) mutators := make([]Mutator, len(ucb.builders)) for i := range ucb.builders { func(i int, root context.Context) { builder := ucb.builders[i] var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*UserMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T", m) } if err := builder.check(); err != nil { return nil, err } builder.mutation = mutation nodes[i], specs[i] = builder.createSpec() var err error if i < len(mutators)-1 { _, err = mutators[i+1].Mutate(root, ucb.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, ucb.driver, spec); err != nil { if sqlgraph.IsConstraintError(err) { err = &ConstraintError{err.Error(), err} } } } if err != nil { return nil, err } mutation.id = &nodes[i].ID mutation.done = true if specs[i].ID.Value != nil { id := specs[i].ID.Value.(int64) nodes[i].ID = int(id) } return nodes[i], nil }) for i := len(builder.hooks) - 1; i >= 0; i-- { mut = builder.hooks[i](mut) } mutators[i] = mut }(i, ctx) } if len(mutators) > 0 { if _, err := mutators[0].Mutate(ctx, ucb.builders[0].mutation); err != nil { return nil, err } } return nodes, nil } // SaveX is like Save, but panics if an error occurs. func (ucb *UserCreateBulk) SaveX(ctx context.Context) []*User { v, err := ucb.Save(ctx) if err != nil { panic(err) } return v } // Exec executes the query. func (ucb *UserCreateBulk) Exec(ctx context.Context) error { _, err := ucb.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. func (ucb *UserCreateBulk) ExecX(ctx context.Context) { if err := ucb.Exec(ctx); err != nil { panic(err) } } golang-ariga-sqlcomment-0.1.0/examples/ent/user_delete.go000066400000000000000000000047701514435236700234750ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "fmt" "ariga.io/sqlcomment/examples/ent/predicate" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" ) // UserDelete is the builder for deleting a User entity. type UserDelete struct { config hooks []Hook mutation *UserMutation } // Where appends a list predicates to the UserDelete builder. func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { ud.mutation.Where(ps...) return ud } // Exec executes the deletion query and returns how many vertices were deleted. func (ud *UserDelete) Exec(ctx context.Context) (int, error) { var ( err error affected int ) if len(ud.hooks) == 0 { affected, err = ud.sqlExec(ctx) } else { var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*UserMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T", m) } ud.mutation = mutation affected, err = ud.sqlExec(ctx) mutation.done = true return affected, err }) for i := len(ud.hooks) - 1; i >= 0; i-- { if ud.hooks[i] == nil { return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") } mut = ud.hooks[i](mut) } if _, err := mut.Mutate(ctx, ud.mutation); err != nil { return 0, err } } return affected, err } // ExecX is like Exec, but panics if an error occurs. func (ud *UserDelete) ExecX(ctx context.Context) int { n, err := ud.Exec(ctx) if err != nil { panic(err) } return n } func (ud *UserDelete) sqlExec(ctx context.Context) (int, error) { _spec := &sqlgraph.DeleteSpec{ Node: &sqlgraph.NodeSpec{ Table: user.Table, ID: &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldID, }, }, } if ps := ud.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } return sqlgraph.DeleteNodes(ctx, ud.driver, _spec) } // UserDeleteOne is the builder for deleting a single User entity. type UserDeleteOne struct { ud *UserDelete } // Exec executes the deletion query. func (udo *UserDeleteOne) Exec(ctx context.Context) error { n, err := udo.ud.Exec(ctx) switch { case err != nil: return err case n == 0: return &NotFoundError{user.Label} default: return nil } } // ExecX is like Exec, but panics if an error occurs. func (udo *UserDeleteOne) ExecX(ctx context.Context) { udo.ud.ExecX(ctx) } golang-ariga-sqlcomment-0.1.0/examples/ent/user_query.go000066400000000000000000000556371514435236700234100ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "errors" "fmt" "math" "ariga.io/sqlcomment/examples/ent/predicate" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" ) // UserQuery is the builder for querying User entities. type UserQuery struct { config limit *int offset *int unique *bool order []OrderFunc fields []string predicates []predicate.User // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) } // Where adds a new predicate for the UserQuery builder. func (uq *UserQuery) Where(ps ...predicate.User) *UserQuery { uq.predicates = append(uq.predicates, ps...) return uq } // Limit adds a limit step to the query. func (uq *UserQuery) Limit(limit int) *UserQuery { uq.limit = &limit return uq } // Offset adds an offset step to the query. func (uq *UserQuery) Offset(offset int) *UserQuery { uq.offset = &offset return uq } // Unique configures the query builder to filter duplicate records on query. // By default, unique is set to true, and can be disabled using this method. func (uq *UserQuery) Unique(unique bool) *UserQuery { uq.unique = &unique return uq } // Order adds an order step to the query. func (uq *UserQuery) Order(o ...OrderFunc) *UserQuery { uq.order = append(uq.order, o...) return uq } // First returns the first User entity from the query. // Returns a *NotFoundError when no User was found. func (uq *UserQuery) First(ctx context.Context) (*User, error) { nodes, err := uq.Limit(1).All(ctx) if err != nil { return nil, err } if len(nodes) == 0 { return nil, &NotFoundError{user.Label} } return nodes[0], nil } // FirstX is like First, but panics if an error occurs. func (uq *UserQuery) FirstX(ctx context.Context) *User { node, err := uq.First(ctx) if err != nil && !IsNotFound(err) { panic(err) } return node } // FirstID returns the first User ID from the query. // Returns a *NotFoundError when no User ID was found. func (uq *UserQuery) FirstID(ctx context.Context) (id int, err error) { var ids []int if ids, err = uq.Limit(1).IDs(ctx); err != nil { return } if len(ids) == 0 { err = &NotFoundError{user.Label} return } return ids[0], nil } // FirstIDX is like FirstID, but panics if an error occurs. func (uq *UserQuery) FirstIDX(ctx context.Context) int { id, err := uq.FirstID(ctx) if err != nil && !IsNotFound(err) { panic(err) } return id } // Only returns a single User entity found by the query, ensuring it only returns one. // Returns a *NotSingularError when exactly one User entity is not found. // Returns a *NotFoundError when no User entities are found. func (uq *UserQuery) Only(ctx context.Context) (*User, error) { nodes, err := uq.Limit(2).All(ctx) if err != nil { return nil, err } switch len(nodes) { case 1: return nodes[0], nil case 0: return nil, &NotFoundError{user.Label} default: return nil, &NotSingularError{user.Label} } } // OnlyX is like Only, but panics if an error occurs. func (uq *UserQuery) OnlyX(ctx context.Context) *User { node, err := uq.Only(ctx) if err != nil { panic(err) } return node } // OnlyID is like Only, but returns the only User ID in the query. // Returns a *NotSingularError when exactly one User ID is not found. // Returns a *NotFoundError when no entities are found. func (uq *UserQuery) OnlyID(ctx context.Context) (id int, err error) { var ids []int if ids, err = uq.Limit(2).IDs(ctx); err != nil { return } switch len(ids) { case 1: id = ids[0] case 0: err = &NotFoundError{user.Label} default: err = &NotSingularError{user.Label} } return } // OnlyIDX is like OnlyID, but panics if an error occurs. func (uq *UserQuery) OnlyIDX(ctx context.Context) int { id, err := uq.OnlyID(ctx) if err != nil { panic(err) } return id } // All executes the query and returns a list of Users. func (uq *UserQuery) All(ctx context.Context) ([]*User, error) { if err := uq.prepareQuery(ctx); err != nil { return nil, err } return uq.sqlAll(ctx) } // AllX is like All, but panics if an error occurs. func (uq *UserQuery) AllX(ctx context.Context) []*User { nodes, err := uq.All(ctx) if err != nil { panic(err) } return nodes } // IDs executes the query and returns a list of User IDs. func (uq *UserQuery) IDs(ctx context.Context) ([]int, error) { var ids []int if err := uq.Select(user.FieldID).Scan(ctx, &ids); err != nil { return nil, err } return ids, nil } // IDsX is like IDs, but panics if an error occurs. func (uq *UserQuery) IDsX(ctx context.Context) []int { ids, err := uq.IDs(ctx) if err != nil { panic(err) } return ids } // Count returns the count of the given query. func (uq *UserQuery) Count(ctx context.Context) (int, error) { if err := uq.prepareQuery(ctx); err != nil { return 0, err } return uq.sqlCount(ctx) } // CountX is like Count, but panics if an error occurs. func (uq *UserQuery) CountX(ctx context.Context) int { count, err := uq.Count(ctx) if err != nil { panic(err) } return count } // Exist returns true if the query has elements in the graph. func (uq *UserQuery) Exist(ctx context.Context) (bool, error) { if err := uq.prepareQuery(ctx); err != nil { return false, err } return uq.sqlExist(ctx) } // ExistX is like Exist, but panics if an error occurs. func (uq *UserQuery) ExistX(ctx context.Context) bool { exist, err := uq.Exist(ctx) if err != nil { panic(err) } return exist } // Clone returns a duplicate of the UserQuery builder, including all associated steps. It can be // used to prepare common query builders and use them differently after the clone is made. func (uq *UserQuery) Clone() *UserQuery { if uq == nil { return nil } return &UserQuery{ config: uq.config, limit: uq.limit, offset: uq.offset, order: append([]OrderFunc{}, uq.order...), predicates: append([]predicate.User{}, uq.predicates...), // clone intermediate query. sql: uq.sql.Clone(), path: uq.path, } } // GroupBy is used to group vertices by one or more fields/columns. // It is often used with aggregate functions, like: count, max, mean, min, sum. // // Example: // // var v []struct { // Name string `json:"name,omitempty"` // Count int `json:"count,omitempty"` // } // // client.User.Query(). // GroupBy(user.FieldName). // Aggregate(ent.Count()). // Scan(ctx, &v) // func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy { group := &UserGroupBy{config: uq.config} group.fields = append([]string{field}, fields...) group.path = func(ctx context.Context) (prev *sql.Selector, err error) { if err := uq.prepareQuery(ctx); err != nil { return nil, err } return uq.sqlQuery(ctx), nil } return group } // Select allows the selection one or more fields/columns for the given query, // instead of selecting all fields in the entity. // // Example: // // var v []struct { // Name string `json:"name,omitempty"` // } // // client.User.Query(). // Select(user.FieldName). // Scan(ctx, &v) // func (uq *UserQuery) Select(fields ...string) *UserSelect { uq.fields = append(uq.fields, fields...) return &UserSelect{UserQuery: uq} } func (uq *UserQuery) prepareQuery(ctx context.Context) error { for _, f := range uq.fields { if !user.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} } } if uq.path != nil { prev, err := uq.path(ctx) if err != nil { return err } uq.sql = prev } return nil } func (uq *UserQuery) sqlAll(ctx context.Context) ([]*User, error) { var ( nodes = []*User{} _spec = uq.querySpec() ) _spec.ScanValues = func(columns []string) ([]interface{}, error) { node := &User{config: uq.config} nodes = append(nodes, node) return node.scanValues(columns) } _spec.Assign = func(columns []string, values []interface{}) error { if len(nodes) == 0 { return fmt.Errorf("ent: Assign called without calling ScanValues") } node := nodes[len(nodes)-1] return node.assignValues(columns, values) } if err := sqlgraph.QueryNodes(ctx, uq.driver, _spec); err != nil { return nil, err } if len(nodes) == 0 { return nodes, nil } return nodes, nil } func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) { _spec := uq.querySpec() return sqlgraph.CountNodes(ctx, uq.driver, _spec) } func (uq *UserQuery) sqlExist(ctx context.Context) (bool, error) { n, err := uq.sqlCount(ctx) if err != nil { return false, fmt.Errorf("ent: check existence: %w", err) } return n > 0, nil } func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec { _spec := &sqlgraph.QuerySpec{ Node: &sqlgraph.NodeSpec{ Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldID, }, }, From: uq.sql, Unique: true, } if unique := uq.unique; unique != nil { _spec.Unique = *unique } if fields := uq.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, user.FieldID) for i := range fields { if fields[i] != user.FieldID { _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) } } } if ps := uq.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } if limit := uq.limit; limit != nil { _spec.Limit = *limit } if offset := uq.offset; offset != nil { _spec.Offset = *offset } if ps := uq.order; len(ps) > 0 { _spec.Order = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } return _spec } func (uq *UserQuery) sqlQuery(ctx context.Context) *sql.Selector { builder := sql.Dialect(uq.driver.Dialect()) t1 := builder.Table(user.Table) columns := uq.fields if len(columns) == 0 { columns = user.Columns } selector := builder.Select(t1.Columns(columns...)...).From(t1) if uq.sql != nil { selector = uq.sql selector.Select(selector.Columns(columns...)...) } for _, p := range uq.predicates { p(selector) } for _, p := range uq.order { p(selector) } if offset := uq.offset; offset != nil { // limit is mandatory for offset clause. We start // with default value, and override it below if needed. selector.Offset(*offset).Limit(math.MaxInt32) } if limit := uq.limit; limit != nil { selector.Limit(*limit) } return selector } // UserGroupBy is the group-by builder for User entities. type UserGroupBy struct { config fields []string fns []AggregateFunc // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) } // Aggregate adds the given aggregation functions to the group-by query. func (ugb *UserGroupBy) Aggregate(fns ...AggregateFunc) *UserGroupBy { ugb.fns = append(ugb.fns, fns...) return ugb } // Scan applies the group-by query and scans the result into the given value. func (ugb *UserGroupBy) Scan(ctx context.Context, v interface{}) error { query, err := ugb.path(ctx) if err != nil { return err } ugb.sql = query return ugb.sqlScan(ctx, v) } // ScanX is like Scan, but panics if an error occurs. func (ugb *UserGroupBy) ScanX(ctx context.Context, v interface{}) { if err := ugb.Scan(ctx, v); err != nil { panic(err) } } // Strings returns list of strings from group-by. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Strings(ctx context.Context) ([]string, error) { if len(ugb.fields) > 1 { return nil, errors.New("ent: UserGroupBy.Strings is not achievable when grouping more than 1 field") } var v []string if err := ugb.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // StringsX is like Strings, but panics if an error occurs. func (ugb *UserGroupBy) StringsX(ctx context.Context) []string { v, err := ugb.Strings(ctx) if err != nil { panic(err) } return v } // String returns a single string from a group-by query. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) String(ctx context.Context) (_ string, err error) { var v []string if v, err = ugb.Strings(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserGroupBy.Strings returned %d results when one was expected", len(v)) } return } // StringX is like String, but panics if an error occurs. func (ugb *UserGroupBy) StringX(ctx context.Context) string { v, err := ugb.String(ctx) if err != nil { panic(err) } return v } // Ints returns list of ints from group-by. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Ints(ctx context.Context) ([]int, error) { if len(ugb.fields) > 1 { return nil, errors.New("ent: UserGroupBy.Ints is not achievable when grouping more than 1 field") } var v []int if err := ugb.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // IntsX is like Ints, but panics if an error occurs. func (ugb *UserGroupBy) IntsX(ctx context.Context) []int { v, err := ugb.Ints(ctx) if err != nil { panic(err) } return v } // Int returns a single int from a group-by query. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Int(ctx context.Context) (_ int, err error) { var v []int if v, err = ugb.Ints(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserGroupBy.Ints returned %d results when one was expected", len(v)) } return } // IntX is like Int, but panics if an error occurs. func (ugb *UserGroupBy) IntX(ctx context.Context) int { v, err := ugb.Int(ctx) if err != nil { panic(err) } return v } // Float64s returns list of float64s from group-by. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Float64s(ctx context.Context) ([]float64, error) { if len(ugb.fields) > 1 { return nil, errors.New("ent: UserGroupBy.Float64s is not achievable when grouping more than 1 field") } var v []float64 if err := ugb.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // Float64sX is like Float64s, but panics if an error occurs. func (ugb *UserGroupBy) Float64sX(ctx context.Context) []float64 { v, err := ugb.Float64s(ctx) if err != nil { panic(err) } return v } // Float64 returns a single float64 from a group-by query. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Float64(ctx context.Context) (_ float64, err error) { var v []float64 if v, err = ugb.Float64s(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserGroupBy.Float64s returned %d results when one was expected", len(v)) } return } // Float64X is like Float64, but panics if an error occurs. func (ugb *UserGroupBy) Float64X(ctx context.Context) float64 { v, err := ugb.Float64(ctx) if err != nil { panic(err) } return v } // Bools returns list of bools from group-by. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Bools(ctx context.Context) ([]bool, error) { if len(ugb.fields) > 1 { return nil, errors.New("ent: UserGroupBy.Bools is not achievable when grouping more than 1 field") } var v []bool if err := ugb.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // BoolsX is like Bools, but panics if an error occurs. func (ugb *UserGroupBy) BoolsX(ctx context.Context) []bool { v, err := ugb.Bools(ctx) if err != nil { panic(err) } return v } // Bool returns a single bool from a group-by query. // It is only allowed when executing a group-by query with one field. func (ugb *UserGroupBy) Bool(ctx context.Context) (_ bool, err error) { var v []bool if v, err = ugb.Bools(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserGroupBy.Bools returned %d results when one was expected", len(v)) } return } // BoolX is like Bool, but panics if an error occurs. func (ugb *UserGroupBy) BoolX(ctx context.Context) bool { v, err := ugb.Bool(ctx) if err != nil { panic(err) } return v } func (ugb *UserGroupBy) sqlScan(ctx context.Context, v interface{}) error { for _, f := range ugb.fields { if !user.ValidColumn(f) { return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)} } } selector := ugb.sqlQuery() if err := selector.Err(); err != nil { return err } rows := &sql.Rows{} query, args := selector.Query() if err := ugb.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } func (ugb *UserGroupBy) sqlQuery() *sql.Selector { selector := ugb.sql.Select() aggregation := make([]string, 0, len(ugb.fns)) for _, fn := range ugb.fns { aggregation = append(aggregation, fn(selector)) } // If no columns were selected in a custom aggregation function, the default // selection is the fields used for "group-by", and the aggregation functions. if len(selector.SelectedColumns()) == 0 { columns := make([]string, 0, len(ugb.fields)+len(ugb.fns)) for _, f := range ugb.fields { columns = append(columns, selector.C(f)) } for _, c := range aggregation { columns = append(columns, c) } selector.Select(columns...) } return selector.GroupBy(selector.Columns(ugb.fields...)...) } // UserSelect is the builder for selecting fields of User entities. type UserSelect struct { *UserQuery // intermediate query (i.e. traversal path). sql *sql.Selector } // Scan applies the selector query and scans the result into the given value. func (us *UserSelect) Scan(ctx context.Context, v interface{}) error { if err := us.prepareQuery(ctx); err != nil { return err } us.sql = us.UserQuery.sqlQuery(ctx) return us.sqlScan(ctx, v) } // ScanX is like Scan, but panics if an error occurs. func (us *UserSelect) ScanX(ctx context.Context, v interface{}) { if err := us.Scan(ctx, v); err != nil { panic(err) } } // Strings returns list of strings from a selector. It is only allowed when selecting one field. func (us *UserSelect) Strings(ctx context.Context) ([]string, error) { if len(us.fields) > 1 { return nil, errors.New("ent: UserSelect.Strings is not achievable when selecting more than 1 field") } var v []string if err := us.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // StringsX is like Strings, but panics if an error occurs. func (us *UserSelect) StringsX(ctx context.Context) []string { v, err := us.Strings(ctx) if err != nil { panic(err) } return v } // String returns a single string from a selector. It is only allowed when selecting one field. func (us *UserSelect) String(ctx context.Context) (_ string, err error) { var v []string if v, err = us.Strings(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserSelect.Strings returned %d results when one was expected", len(v)) } return } // StringX is like String, but panics if an error occurs. func (us *UserSelect) StringX(ctx context.Context) string { v, err := us.String(ctx) if err != nil { panic(err) } return v } // Ints returns list of ints from a selector. It is only allowed when selecting one field. func (us *UserSelect) Ints(ctx context.Context) ([]int, error) { if len(us.fields) > 1 { return nil, errors.New("ent: UserSelect.Ints is not achievable when selecting more than 1 field") } var v []int if err := us.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // IntsX is like Ints, but panics if an error occurs. func (us *UserSelect) IntsX(ctx context.Context) []int { v, err := us.Ints(ctx) if err != nil { panic(err) } return v } // Int returns a single int from a selector. It is only allowed when selecting one field. func (us *UserSelect) Int(ctx context.Context) (_ int, err error) { var v []int if v, err = us.Ints(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserSelect.Ints returned %d results when one was expected", len(v)) } return } // IntX is like Int, but panics if an error occurs. func (us *UserSelect) IntX(ctx context.Context) int { v, err := us.Int(ctx) if err != nil { panic(err) } return v } // Float64s returns list of float64s from a selector. It is only allowed when selecting one field. func (us *UserSelect) Float64s(ctx context.Context) ([]float64, error) { if len(us.fields) > 1 { return nil, errors.New("ent: UserSelect.Float64s is not achievable when selecting more than 1 field") } var v []float64 if err := us.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // Float64sX is like Float64s, but panics if an error occurs. func (us *UserSelect) Float64sX(ctx context.Context) []float64 { v, err := us.Float64s(ctx) if err != nil { panic(err) } return v } // Float64 returns a single float64 from a selector. It is only allowed when selecting one field. func (us *UserSelect) Float64(ctx context.Context) (_ float64, err error) { var v []float64 if v, err = us.Float64s(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserSelect.Float64s returned %d results when one was expected", len(v)) } return } // Float64X is like Float64, but panics if an error occurs. func (us *UserSelect) Float64X(ctx context.Context) float64 { v, err := us.Float64(ctx) if err != nil { panic(err) } return v } // Bools returns list of bools from a selector. It is only allowed when selecting one field. func (us *UserSelect) Bools(ctx context.Context) ([]bool, error) { if len(us.fields) > 1 { return nil, errors.New("ent: UserSelect.Bools is not achievable when selecting more than 1 field") } var v []bool if err := us.Scan(ctx, &v); err != nil { return nil, err } return v, nil } // BoolsX is like Bools, but panics if an error occurs. func (us *UserSelect) BoolsX(ctx context.Context) []bool { v, err := us.Bools(ctx) if err != nil { panic(err) } return v } // Bool returns a single bool from a selector. It is only allowed when selecting one field. func (us *UserSelect) Bool(ctx context.Context) (_ bool, err error) { var v []bool if v, err = us.Bools(ctx); err != nil { return } switch len(v) { case 1: return v[0], nil case 0: err = &NotFoundError{user.Label} default: err = fmt.Errorf("ent: UserSelect.Bools returned %d results when one was expected", len(v)) } return } // BoolX is like Bool, but panics if an error occurs. func (us *UserSelect) BoolX(ctx context.Context) bool { v, err := us.Bool(ctx) if err != nil { panic(err) } return v } func (us *UserSelect) sqlScan(ctx context.Context, v interface{}) error { rows := &sql.Rows{} query, args := us.sql.Query() if err := us.driver.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() return sql.ScanSlice(rows, v) } golang-ariga-sqlcomment-0.1.0/examples/ent/user_update.go000066400000000000000000000151671514435236700235170ustar00rootroot00000000000000// Code generated by entc, DO NOT EDIT. package ent import ( "context" "fmt" "ariga.io/sqlcomment/examples/ent/predicate" "ariga.io/sqlcomment/examples/ent/user" "entgo.io/ent/dialect/sql" "entgo.io/ent/dialect/sql/sqlgraph" "entgo.io/ent/schema/field" ) // UserUpdate is the builder for updating User entities. type UserUpdate struct { config hooks []Hook mutation *UserMutation } // Where appends a list predicates to the UserUpdate builder. func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { uu.mutation.Where(ps...) return uu } // SetName sets the "name" field. func (uu *UserUpdate) SetName(s string) *UserUpdate { uu.mutation.SetName(s) return uu } // Mutation returns the UserMutation object of the builder. func (uu *UserUpdate) Mutation() *UserMutation { return uu.mutation } // Save executes the query and returns the number of nodes affected by the update operation. func (uu *UserUpdate) Save(ctx context.Context) (int, error) { var ( err error affected int ) if len(uu.hooks) == 0 { affected, err = uu.sqlSave(ctx) } else { var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*UserMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T", m) } uu.mutation = mutation affected, err = uu.sqlSave(ctx) mutation.done = true return affected, err }) for i := len(uu.hooks) - 1; i >= 0; i-- { if uu.hooks[i] == nil { return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") } mut = uu.hooks[i](mut) } if _, err := mut.Mutate(ctx, uu.mutation); err != nil { return 0, err } } return affected, err } // SaveX is like Save, but panics if an error occurs. func (uu *UserUpdate) SaveX(ctx context.Context) int { affected, err := uu.Save(ctx) if err != nil { panic(err) } return affected } // Exec executes the query. func (uu *UserUpdate) Exec(ctx context.Context) error { _, err := uu.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. func (uu *UserUpdate) ExecX(ctx context.Context) { if err := uu.Exec(ctx); err != nil { panic(err) } } func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { _spec := &sqlgraph.UpdateSpec{ Node: &sqlgraph.NodeSpec{ Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldID, }, }, } if ps := uu.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } if value, ok := uu.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, Value: value, Column: user.FieldName, }) } if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{err.Error(), err} } return 0, err } return n, nil } // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config fields []string hooks []Hook mutation *UserMutation } // SetName sets the "name" field. func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { uuo.mutation.SetName(s) return uuo } // Mutation returns the UserMutation object of the builder. func (uuo *UserUpdateOne) Mutation() *UserMutation { return uuo.mutation } // Select allows selecting one or more fields (columns) of the returned entity. // The default is selecting all fields defined in the entity schema. func (uuo *UserUpdateOne) Select(field string, fields ...string) *UserUpdateOne { uuo.fields = append([]string{field}, fields...) return uuo } // Save executes the query and returns the updated User entity. func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { var ( err error node *User ) if len(uuo.hooks) == 0 { node, err = uuo.sqlSave(ctx) } else { var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { mutation, ok := m.(*UserMutation) if !ok { return nil, fmt.Errorf("unexpected mutation type %T", m) } uuo.mutation = mutation node, err = uuo.sqlSave(ctx) mutation.done = true return node, err }) for i := len(uuo.hooks) - 1; i >= 0; i-- { if uuo.hooks[i] == nil { return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") } mut = uuo.hooks[i](mut) } if _, err := mut.Mutate(ctx, uuo.mutation); err != nil { return nil, err } } return node, err } // SaveX is like Save, but panics if an error occurs. func (uuo *UserUpdateOne) SaveX(ctx context.Context) *User { node, err := uuo.Save(ctx) if err != nil { panic(err) } return node } // Exec executes the query on the entity. func (uuo *UserUpdateOne) Exec(ctx context.Context) error { _, err := uuo.Save(ctx) return err } // ExecX is like Exec, but panics if an error occurs. func (uuo *UserUpdateOne) ExecX(ctx context.Context) { if err := uuo.Exec(ctx); err != nil { panic(err) } } func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec := &sqlgraph.UpdateSpec{ Node: &sqlgraph.NodeSpec{ Table: user.Table, Columns: user.Columns, ID: &sqlgraph.FieldSpec{ Type: field.TypeInt, Column: user.FieldID, }, }, } id, ok := uuo.mutation.ID() if !ok { return nil, &ValidationError{Name: "ID", err: fmt.Errorf("missing User.ID for update")} } _spec.Node.ID.Value = id if fields := uuo.fields; len(fields) > 0 { _spec.Node.Columns = make([]string, 0, len(fields)) _spec.Node.Columns = append(_spec.Node.Columns, user.FieldID) for _, f := range fields { if !user.ValidColumn(f) { return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} } if f != user.FieldID { _spec.Node.Columns = append(_spec.Node.Columns, f) } } } if ps := uuo.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { ps[i](selector) } } } if value, ok := uuo.mutation.Name(); ok { _spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{ Type: field.TypeString, Value: value, Column: user.FieldName, }) } _node = &User{config: uuo.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, uuo.driver, _spec); err != nil { if _, ok := err.(*sqlgraph.NotFoundError); ok { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{err.Error(), err} } return nil, err } return _node, nil } golang-ariga-sqlcomment-0.1.0/examples/oc/000077500000000000000000000000001514435236700204515ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/oc/example_test.go000066400000000000000000000050561514435236700235000ustar00rootroot00000000000000package main import ( "context" "encoding/json" "log" "net/http" "net/http/httptest" "time" "ariga.io/sqlcomment" "ariga.io/sqlcomment/examples/ent" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "go.opencensus.io/examples/exporter" "go.opencensus.io/plugin/ochttp" "go.opencensus.io/stats/view" "go.opencensus.io/trace" _ "github.com/mattn/go-sqlite3" ) const ( metricsLogFile = "/tmp/metrics.log" tracesLogFile = "/tmp/trace.log" ) func initTracer() func() { // Using log exporter to export metrics but you can choose any supported exporter. exporter, err := exporter.NewLogExporter(exporter.Options{ ReportingInterval: 10 * time.Second, MetricsLogFile: metricsLogFile, TracesLogFile: tracesLogFile, }) if err != nil { log.Fatalf("Error creating log exporter: %v", err) } exporter.Start() trace.ApplyConfig(trace.Config{DefaultSampler: trace.AlwaysSample()}) // Report stats at every second. view.SetReportingPeriod(1 * time.Second) return func() { exporter.Stop() exporter.Close() } } func main() { closeTracer := initTracer() defer closeTracer() // Create db driver. db, err := sql.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") if err != nil { log.Fatalf("Failed to connect to database: %v", err) } // create sqlcommenter driver which wraps debug driver which wraps sqlite driver // we should have sqlcommenter and debug logs on every query to our sqlite DB commentedDriver := sqlcomment.NewDriver(dialect.Debug(db), // add OpenCensus tracing tags sqlcomment.WithTagger(sqlcomment.NewOCTagger()), sqlcomment.WithDriverVerTag(), sqlcomment.WithTags(sqlcomment.Tags{ sqlcomment.KeyApplication: "users", sqlcomment.KeyFramework: "net/http", }), ) // create and configure ent client client := ent.NewClient(ent.Driver(commentedDriver)) defer client.Close() // Run the auto migration tool. if err := client.Schema.Create(context.Background()); err != nil { log.Fatalf("failed creating schema resources: %v", err) } client.User.Create().SetName("hedwigz").SaveX(context.Background()) getUsersHandler := func(rw http.ResponseWriter, r *http.Request) { users := client.User.Query().AllX(r.Context()) b, _ := json.Marshal(users) rw.WriteHeader(http.StatusOK) rw.Write(b) } backend := &ochttp.Handler{ Handler: http.HandlerFunc(getUsersHandler), } testRequest(backend) } func testRequest(handler http.Handler) { req := httptest.NewRequest(http.MethodGet, "/", nil) w := httptest.NewRecorder() // debug printer should print sql statement with comment handler.ServeHTTP(w, req) } golang-ariga-sqlcomment-0.1.0/examples/otel/000077500000000000000000000000001514435236700210135ustar00rootroot00000000000000golang-ariga-sqlcomment-0.1.0/examples/otel/example_test.go000066400000000000000000000070561514435236700240440ustar00rootroot00000000000000package main import ( "context" "encoding/json" "io" "log" "net/http" "net/http/httptest" "ariga.io/sqlcomment" "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" _ "github.com/mattn/go-sqlite3" "ariga.io/sqlcomment/examples/ent" "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp" "go.opentelemetry.io/otel" stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" "go.opentelemetry.io/otel/propagation" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) type CustomCommenter struct{} func (mcc CustomCommenter) Tag(ctx context.Context) sqlcomment.Tags { return sqlcomment.Tags{ "key": "value", } } func Example_OTELIntegration() { tp := initTracer() defer func() { if err := tp.Shutdown(context.Background()); err != nil { log.Printf("Error shutting down tracer provider: %v", err) } }() // Create db driver. db, err := sql.Open("sqlite3", "file:ent?mode=memory&cache=shared&_fk=1") if err != nil { log.Fatalf("Failed to connect to database: %v", err) } commentedDriver := sqlcomment.NewDriver(dialect.Debug(db), sqlcomment.WithTagger( // add tracing info with Open Telemetry. sqlcomment.NewOTELTagger(), // use your custom commenter CustomCommenter{}, ), // add `db_driver` version tag sqlcomment.WithDriverVerTag(), // add some global tags to all queries sqlcomment.WithTags(sqlcomment.Tags{ sqlcomment.KeyApplication: "bootcamp", sqlcomment.KeyFramework: "go-chi", })) // create and configure ent client client := ent.NewClient(ent.Driver(commentedDriver)) defer client.Close() // Run the auto migration tool. if err := client.Schema.Create(context.Background()); err != nil { log.Fatalf("failed creating schema resources: %v", err) } client.User.Create().SetName("hedwigz").SaveX(context.Background()) // An HTTP middleware that adds the URL path to sqlcomment tags, under the key "route". middleware := func(next http.Handler) http.Handler { fn := func(w http.ResponseWriter, r *http.Request) { ctx := sqlcomment.WithTag(r.Context(), "route", r.URL.Path) next.ServeHTTP(w, r.WithContext(ctx)) } return http.HandlerFunc(fn) } // Application-level http handler. getUsersHandler := func(rw http.ResponseWriter, r *http.Request) { users := client.User.Query().AllX(r.Context()) b, _ := json.Marshal(users) rw.WriteHeader(http.StatusOK) rw.Write(b) } backend := otelhttp.NewHandler(middleware(http.HandlerFunc(getUsersHandler)), "app") testRequest(backend) } func initTracer() *sdktrace.TracerProvider { exporter, err := stdout.New(stdout.WithWriter(io.Discard)) if err != nil { log.Fatal(err) } // For the demonstration, use sdktrace.AlwaysSample sampler to sample all traces. // In a production application, use sdktrace.ProbabilitySampler with a desired probability. tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithBatcher(exporter), sdktrace.WithResource(resource.NewWithAttributes(semconv.SchemaURL, semconv.ServiceNameKey.String("ExampleService"))), ) otel.SetTracerProvider(tp) // Add propagation.TaceContext{} which will be used by OtelTagger to inject trace information. otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) return tp } func testRequest(handler http.Handler) { req := httptest.NewRequest(http.MethodGet, "/api/resource", nil) w := httptest.NewRecorder() // Debug printer should print SQL statement with comment. handler.ServeHTTP(w, req) } golang-ariga-sqlcomment-0.1.0/go.mod000066400000000000000000000027061514435236700173450ustar00rootroot00000000000000module ariga.io/sqlcomment go 1.19 require ( entgo.io/ent v0.11.3-0.20220816070906-2b54aadcce3a github.com/mattn/go-sqlite3 v1.14.14 github.com/stretchr/testify v1.8.0 go.opencensus.io v0.23.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.25.0 go.opentelemetry.io/otel v1.0.1 go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.1 go.opentelemetry.io/otel/sdk v1.0.1 ) require ( ariga.io/atlas v0.6.0 // indirect github.com/agext/levenshtein v1.2.1 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/felixge/httpsnoop v1.0.2 // indirect github.com/go-openapi/inflect v0.19.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/google/go-cmp v0.5.6 // indirect github.com/google/uuid v1.3.0 // indirect github.com/hashicorp/hcl/v2 v2.13.0 // indirect github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/zclconf/go-cty v1.8.0 // indirect go.opentelemetry.io/otel/internal/metric v0.24.0 // indirect go.opentelemetry.io/otel/metric v0.24.0 // indirect go.opentelemetry.io/otel/trace v1.0.1 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/text v0.3.7 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) golang-ariga-sqlcomment-0.1.0/go.sum000066400000000000000000001237501514435236700173750ustar00rootroot00000000000000ariga.io/atlas v0.6.0 h1:LjDa3zfm4J44uhTPboUmkGLhjuALMwHHTvrHZf2V+/s= ariga.io/atlas v0.6.0/go.mod h1:ft47uSh5hWGDCmQC9DsztZg6Xk+KagM5Ts/mZYKb9JE= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= entgo.io/ent v0.9.1 h1:IG8andyeD79GG24U8Q+1Y45hQXj6gY5evSBcva5gtBk= entgo.io/ent v0.9.1/go.mod h1:6NUeTfUN5mp5YN+5tgoH1SlakSvYPTBOYotSOvaI4ak= entgo.io/ent v0.11.3-0.20220816070906-2b54aadcce3a h1:sUFGYR+UCS5y5To31k41KVqSX2YV8mTTgzNXw32ug+o= entgo.io/ent v0.11.3-0.20220816070906-2b54aadcce3a/go.mod h1:5Kf2suCCfELTR+qd6KtEM4S46dT0OSLm+gq627nAuok= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/agext/levenshtein v1.2.1 h1:QmvMAjj2aEICytGiWzmxoE0x2KZvE0fvmqMOfy2tjT8= github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-bindata/go-bindata v1.0.1-0.20190711162640-ee3c2418e368/go.mod h1:7xCgX1lzlrXPHkfvn3EhumqHkmSlzt8at9q7v0ax19c= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-sql-driver/mysql v1.5.1-0.20200311113236-681ffa848bae/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.13.0 h1:0Apadu1w6M11dyGFxWnmhhcMjkbAiKCv7G1r/2QgCNc= github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.8 h1:gDp86IdQsN/xWjIEmr9MF6o9mpksUgh0fu+9ByFxzIU= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.14 h1:qZgc/Rwetq+MtyE18WhzjokPD93dNqLGNT3QJuLvBGw= github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM= github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zclconf/go-cty v1.8.0 h1:s4AvqaeQzJIu3ndv4gVIhplVD0krU+bgrcLSVUnaWuA= github.com/zclconf/go-cty v1.8.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.25.0 h1:FIbb8m2PtTWjvXLHOEnXAoSmkaiXbg3fuvoZAjsAT3Q= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.25.0/go.mod h1:NyB05cd+yPX6W5SiRNuJ90w7PV2+g2cgRbsPL7MvpME= go.opentelemetry.io/otel v1.0.1 h1:4XKyXmfqJLOQ7feyV5DB6gsBFZ0ltB8vLtp6pj4JIcc= go.opentelemetry.io/otel v1.0.1/go.mod h1:OPEOD4jIT2SlZPMmwT6FqZz2C0ZNdQqiWcoK6M0SNFU= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.1 h1:QaXn87hD37gomnr0W9OVju7ouaijrT7+92uurmn2zvQ= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.0.1/go.mod h1:B1r9v/IqMtkB0lIGbbayqT6f2awSH0EDZya1Yu4p1pU= go.opentelemetry.io/otel/internal/metric v0.24.0 h1:O5lFy6kAl0LMWBjzy3k//M8VjEaTDWL9DPJuqZmWIAA= go.opentelemetry.io/otel/internal/metric v0.24.0/go.mod h1:PSkQG+KuApZjBpC6ea6082ZrWUUy/w132tJ/LOU3TXk= go.opentelemetry.io/otel/metric v0.24.0 h1:Rg4UYHS6JKR1Sw1TxnI13z7q/0p/XAbgIqUTagvLJuU= go.opentelemetry.io/otel/metric v0.24.0/go.mod h1:tpMFnCD9t+BEGiWY2bWF5+AwjuAdM0lSowQ4SBA3/K4= go.opentelemetry.io/otel/sdk v1.0.1 h1:wXxFEWGo7XfXupPwVJvTBOaPBC9FEg0wB8hMNrKk+cA= go.opentelemetry.io/otel/sdk v1.0.1/go.mod h1:HrdXne+BiwsOHYYkBE5ysIcv2bvdZstxzmCQhxTcZkI= go.opentelemetry.io/otel/trace v1.0.1 h1:StTeIH6Q3G4r0Fiw34LTokUFESZgIDUr0qIJ7mKmAfw= go.opentelemetry.io/otel/trace v1.0.1/go.mod h1:5g4i4fKLaX2BQpSBsxw8YYcgKpMMSW3x7ZTuYBr3sUk= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007 h1:gG67DSER+11cZvqIMb8S8bt0vZtiN6xWYARwirrOSfE= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= golang-ariga-sqlcomment-0.1.0/oc.go000066400000000000000000000015141514435236700171630ustar00rootroot00000000000000package sqlcomment import ( "context" "go.opencensus.io/plugin/ochttp/propagation/tracecontext" "go.opencensus.io/trace" ) const ( traceparentHeader = "traceparent" tracestateHeader = "tracestate" ) // OCTagger is a Tagger that adds `traceparent` and `tracestate` tags to the SQL comment. type OCTagger struct { format *tracecontext.HTTPFormat } // NewOCTagger adds OC trace information as SQL tags. func NewOCTagger() OCTagger { return OCTagger{&tracecontext.HTTPFormat{}} } // Tag finds trace information on the given context and returns SQL tags with trace information. func (ot OCTagger) Tag(ctx context.Context) Tags { spanCtx := trace.FromContext(ctx).SpanContext() tp, ts := ot.format.SpanContextToHeaders(spanCtx) tags := Tags{ traceparentHeader: tp, } if ts != "" { tags[tracestateHeader] = ts } return tags } golang-ariga-sqlcomment-0.1.0/otel.go000066400000000000000000000022451514435236700175270ustar00rootroot00000000000000package sqlcomment import ( "context" "go.opentelemetry.io/otel" ) type ( // OTELTagger is a Tagger that adds `traceparent` and `tracestate` tags to the SQL comment. OTELTagger struct{} // CommentCarrier implements propagation.TextMapCarrier in order to retrieve trace information from OTEL. CommentCarrier Tags ) // NewOTELTagger adds OTEL trace information as SQL tags. func NewOTELTagger() OTELTagger { return OTELTagger{} } // Tag finds trace information on the given context and returns SQL tags with trace information. func (ot OTELTagger) Tag(ctx context.Context) Tags { c := NewCommentCarrier() otel.GetTextMapPropagator().Inject(ctx, c) return Tags(c) } func NewCommentCarrier() CommentCarrier { return make(CommentCarrier) } // Get returns the value associated with the passed key. func (c CommentCarrier) Get(key string) string { return string(c[key]) } // Set stores the key-value pair. func (c CommentCarrier) Set(key string, value string) { c[key] = value } // Keys lists the keys stored in this carrier. func (c CommentCarrier) Keys() []string { keys := make([]string, 0, len(c)) for k := range c { keys = append(keys, string(k)) } return keys } golang-ariga-sqlcomment-0.1.0/taggers.go000066400000000000000000000017251514435236700202220ustar00rootroot00000000000000package sqlcomment import ( "context" "fmt" "runtime/debug" ) // driverVersionTagger adds `db_driver` tag with "ent:" type driverVersionTagger struct { version string } func NewDriverVersionTagger() driverVersionTagger { info, ok := debug.ReadBuildInfo() if !ok { return driverVersionTagger{"ent"} } for _, d := range info.Deps { if d.Path == "entgo.io/ent" { return driverVersionTagger{fmt.Sprintf("ent:%s", d.Version)} } } return driverVersionTagger{"ent"} } func (dv driverVersionTagger) Tag(ctx context.Context) Tags { return Tags{ KeyDBDriver: dv.version, } } type contextTagger struct{} func (ct contextTagger) Tag(ctx context.Context) Tags { return FromContext(ctx) } type staticTagger struct { tags Tags } // NewStaticTagger returns an Tagger which adds tags to every SQL comment. func NewStaticTagger(tags Tags) staticTagger { return staticTagger{tags} } func (st staticTagger) Tag(ctx context.Context) Tags { return st.tags } golang-ariga-sqlcomment-0.1.0/tags.go000066400000000000000000000024231514435236700175200ustar00rootroot00000000000000package sqlcomment import ( "fmt" "net/url" "sort" "strings" ) const ( KeyDBDriver = "db_driver" KeyFramework = "framework" KeyApplication = "application" KeyRoute = "route" KeyController = "controller" KeyAction = "action" ) // Tags represents key value pairs which can be serialized into SQL comment. // see https://google.github.io/sqlcommenter/spec/ type Tags map[string]string func encodeValue(v string) string { urlEscape := strings.ReplaceAll(url.PathEscape(string(v)), "+", "%20") return fmt.Sprintf("'%s'", urlEscape) } func encodeKey(k string) string { return url.QueryEscape(string(k)) } // Marshal returns the sqlcomment encoding of t following the spec (see https://google.github.io/sqlcommenter/). func (t Tags) Marshal() string { kv := make([]struct{ k, v string }, 0, len(t)) for k := range t { kv = append(kv, struct{ k, v string }{encodeKey(k), encodeValue(t[k])}) } sort.Slice(kv, func(i, j int) bool { return kv[i].k < kv[j].k }) var b strings.Builder for i, p := range kv { if i > 0 { b.WriteByte(',') } fmt.Fprintf(&b, "%s=%s", p.k, p.v) } return b.String() } // Merge copies given tags into sc. func (t Tags) Merge(tags ...Tags) Tags { for _, c := range tags { for k, v := range c { t[k] = v } } return t } golang-ariga-sqlcomment-0.1.0/tags_test.go000066400000000000000000000006571514435236700205660ustar00rootroot00000000000000package sqlcomment import ( "testing" "github.com/stretchr/testify/assert" ) func TestCommentEscapse(t *testing.T) { tags := Tags{ "route": `/param first`, "num": `1234`, "query": `DROP TABLE FOO'`, "injection": `/route/*/;DROP TABLE USERS`, } assert.Equal(t, `injection='%2Froute%2F%2A%2F%3BDROP%20TABLE%20USERS',num='1234',query='DROP%20TABLE%20FOO%27',route='%2Fparam%20first'`, tags.Marshal()) }