From 4df9241384be65b482fab5a8823cd8c50acfb95f Mon Sep 17 00:00:00 2001 From: Aaron L Date: Mon, 27 Apr 2020 00:20:05 -0700 Subject: [PATCH] Move to go modules - Add documentation about modules - Add documentation about v4 - Bump version - Update changelog --- CHANGELOG.md | 9 +- LICENSE | 2 +- README.md | 33 +- boil/columns.go | 2 +- boilingcore/aliases.go | 6 +- boilingcore/aliases_test.go | 2 +- boilingcore/boilingcore.go | 8 +- boilingcore/boilingcore_test.go | 6 +- boilingcore/config.go | 4 +- boilingcore/config_test.go | 2 +- boilingcore/output.go | 2 +- boilingcore/templates.go | 6 +- boilingcore/text_helpers.go | 4 +- boilingcore/text_helpers_test.go | 2 +- drivers/binary_driver.go | 2 +- drivers/column.go | 2 +- drivers/interface.go | 4 +- drivers/interface_test.go | 2 +- drivers/mocks/mock.go | 14 +- drivers/registration_test.go | 2 +- drivers/sqlboiler-mssql/driver/mssql.go | 50 +- drivers/sqlboiler-mssql/driver/mssql_test.go | 2 +- drivers/sqlboiler-mssql/main.go | 4 +- drivers/sqlboiler-mysql/driver/mysql.go | 52 +- drivers/sqlboiler-mysql/driver/mysql_test.go | 2 +- drivers/sqlboiler-mysql/main.go | 4 +- drivers/sqlboiler-psql/driver/psql.go | 96 +-- drivers/sqlboiler-psql/driver/psql_test.go | 2 +- drivers/sqlboiler-psql/main.go | 4 +- go.mod | 19 + go.sum | 189 +++++ importers/imports.go | 34 +- importers/imports_test.go | 20 +- main.go | 10 +- queries/eager_load.go | 4 +- queries/eager_load_test.go | 2 +- queries/helpers_test.go | 2 +- queries/qm/query_mods.go | 4 +- queries/qmhelper/qmhelper.go | 2 +- queries/query.go | 4 +- queries/query_builders.go | 2 +- queries/query_builders_test.go | 2 +- queries/reflect.go | 4 +- queries/reflect_test.go | 2 +- randomize/random.go | 203 ----- randomize/random_test.go | 19 - randomize/randomize.go | 292 -------- randomize/randomize_test.go | 161 ---- strmangle/buf_pool.go | 27 - strmangle/inflect.go | 205 ----- strmangle/sets.go | 90 --- strmangle/sets_test.go | 132 ---- strmangle/strmangle.go | 744 ------------------- strmangle/strmangle_test.go | 683 ----------------- types/array.go | 2 +- types/decimal_test.go | 2 +- types/hstore.go | 4 +- types/json.go | 2 +- 58 files changed, 443 insertions(+), 2753 deletions(-) create mode 100644 go.mod create mode 100644 go.sum delete mode 100644 randomize/random.go delete mode 100644 randomize/random_test.go delete mode 100644 randomize/randomize.go delete mode 100644 randomize/randomize_test.go delete mode 100644 strmangle/buf_pool.go delete mode 100644 strmangle/inflect.go delete mode 100644 strmangle/sets.go delete mode 100644 strmangle/sets_test.go delete mode 100644 strmangle/strmangle.go delete mode 100644 strmangle/strmangle_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 151dce7b4..4939166c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,16 +3,23 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). -## Unreleased +## [v4.0.0] - 2020-04-26 + +**NOTE:** Your database drivers must be rebuilt upon moving to this release ### Added +- Add a `--add-soft-deletes` that changes the templates to use soft deletion + (thanks @namco1992) - Add a `--no-back-referencing` flag to disable setting backreferences in relationship helpers and eager loading. (thanks @namco1992) - Add not in helpers (thanks @RichardLindhout) ### Changed +- Changed dependency scheme to go modules +- Changed randomize/strmangle to be external dependencies to avoid module + cycles with the null package. - Changed the way comparisons work for keying caches which dramatically speeds up cache lookups (thanks @zikaeroh) diff --git a/LICENSE b/LICENSE index 0496e8036..99344d84f 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017 Volatile Technologies Inc. All rights reserved. +Copyright (c) 2020 Volatile Technologies Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/README.md b/README.md index effc4dbcc..751eb89db 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,11 @@ or some other migration tool to manage this part of the database's life-cycle. v3 has been released, please upgrade when possible, v2 is on life support only now. +# Note on v3 vs v4 + +v4 is identical virtually identical to v3 (it has 1 or 2 more features) but +was turned into modules. + ## Why another ORM While attempting to migrate a legacy Rails database, we realized how much ActiveRecord benefited us in terms of development velocity. @@ -111,6 +116,7 @@ Table of Contents - Strongly typed querying (usually no converting or binding to pointers) - Hooks (Before/After Create/Select/Update/Delete/Upsert) - Automatic CreatedAt/UpdatedAt +- Automatic DeletedAt - Table and column whitelist/blacklist - Relationships/Associations - Eager loading (recursive) @@ -399,18 +405,22 @@ sqlboiler psql Flags: --add-global-variants Enable generation for global variants --add-panic-variants Enable generation for panic variants + --add-soft-deletes Enable soft deletion by updating deleted_at timestamp -c, --config string Filename of config file to override default lookup -d, --debug Debug mode prints stack traces on error -h, --help help for sqlboiler --no-auto-timestamps Disable automatic timestamps for created_at/updated_at + --no-back-referencing Disable back referencing in the loaded relationship structs --no-context Disable context.Context usage in the generated code + --no-driver-templates Disable parsing of templates defined by the database driver --no-hooks Disable hooks feature for your models --no-rows-affected Disable rows affected in the generated API --no-tests Disable generated go test files -o, --output string The name of the folder to output to (default "models") -p, --pkgname string The name you wish to assign to your generated package (default "models") - --struct-tag-casing string Decides the casing for go structure tag names. camel or snake (default "snake") + --struct-tag-casing string Decides the casing for go structure tag names. camel, title or snake (default snake) (default "snake") -t, --tag strings Struct tags to be included on your models in addition to json, yaml, toml + --tag-ignore strings List of column names that should have tags values set to '-' (ignored during parsing) --templates strings A templates directory, overrides the bindata'd template folders in sqlboiler --version Print the version --wipe Delete the output folder (rm -rf) before generation to ensure sanity @@ -840,6 +850,10 @@ The most common causes of problems and panics are: field in Go so sqlboiler assumes you do not want to insert that field and you want the default value from the database. Use a whitelist/greylist to add that field to the list of fields to insert. +- decimal library showing errors like: `pq: encode: unknown type types.NullDecimal` + is a result of a too-new and broken version of the github.com/ericlargergren/decimal + package, use the following version in your go.mod: + github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5 For errors with other causes, it may be simple to debug yourself by looking at the generated code. Setting `boil.DebugMode` to `true` can help with this. You can change the output using `boil.DebugWriter` (defaults to `os.Stdout`). @@ -976,6 +990,23 @@ before being sent to the database (if they were going to be sent). will be used. To set `created_at` to `null`, set `Valid` to false and `Time` to a non-zero value. * The `updated_at` column will always be set to `time.Now()`. +### Automatic DeletedAt (Soft Delete) + +Soft deletes are a way of deleting records in a database for the average query +without actually removing the data. This type of thing is important in certain +scenarios where data retention is important. It is typically done by adding a +`deleted` bool or a `deleted_at` timestamp to each table in the database +that can be soft deleted and subsequent queries on that table should always +make sure that `deleted != true` or `deleted_at is null` to prevent showing +"deleted" data. + +SQLBoiler uses the `deleted_at` variant to provide this functionality. If your +table has a nullable timestamp field named `deleted_at` it will be a candidate +for soft-deletion. + +*NOTE*: As of writing soft-delete is opt-in via `--add-soft-deletes` and is +liable to change in future versions. + ### Query Building We generate "Starter" methods for you. These methods are named as the plural versions of your model, diff --git a/boil/columns.go b/boil/columns.go index 44b52aca2..da59aae84 100644 --- a/boil/columns.go +++ b/boil/columns.go @@ -1,7 +1,7 @@ package boil import ( - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/strmangle" ) // Columns kinds diff --git a/boilingcore/aliases.go b/boilingcore/aliases.go index 5ada9c51a..6da9e23b0 100644 --- a/boilingcore/aliases.go +++ b/boilingcore/aliases.go @@ -3,8 +3,8 @@ package boilingcore import ( "fmt" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/strmangle" ) // Aliases defines aliases for the generation run @@ -42,7 +42,7 @@ func FillAliases(a *Aliases, tables []drivers.Table) { for _, t := range tables { if t.IsJoinTable { - jt, ok := a.Tables[t.Name]; + jt, ok := a.Tables[t.Name] if !ok { a.Tables[t.Name] = TableAlias{Relationships: make(map[string]RelationshipAlias)} } else if jt.Relationships == nil { diff --git a/boilingcore/aliases_test.go b/boilingcore/aliases_test.go index 940c90a0d..d77937fd3 100644 --- a/boilingcore/aliases_test.go +++ b/boilingcore/aliases_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) func TestAliasesTables(t *testing.T) { diff --git a/boilingcore/boilingcore.go b/boilingcore/boilingcore.go index 071aec142..80c4810ca 100644 --- a/boilingcore/boilingcore.go +++ b/boilingcore/boilingcore.go @@ -12,10 +12,10 @@ import ( "strings" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/importers" - "github.com/volatiletech/sqlboiler/strmangle" - "github.com/volatiletech/sqlboiler/templatebin" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/importers" + "github.com/volatiletech/sqlboiler/v4/templatebin" + "github.com/volatiletech/strmangle" ) const ( diff --git a/boilingcore/boilingcore_test.go b/boilingcore/boilingcore_test.go index 696f21120..a225c07b1 100644 --- a/boilingcore/boilingcore_test.go +++ b/boilingcore/boilingcore_test.go @@ -12,10 +12,10 @@ import ( "strconv" "testing" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/importers" - "github.com/volatiletech/sqlboiler/drivers" - _ "github.com/volatiletech/sqlboiler/drivers/mocks" + "github.com/volatiletech/sqlboiler/v4/drivers" + _ "github.com/volatiletech/sqlboiler/v4/drivers/mocks" ) var state *State diff --git a/boilingcore/config.go b/boilingcore/config.go index a3a9d08f0..ed33d98cc 100644 --- a/boilingcore/config.go +++ b/boilingcore/config.go @@ -5,8 +5,8 @@ import ( "strings" "github.com/spf13/cast" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/importers" ) // Config for the running of the commands diff --git a/boilingcore/config_test.go b/boilingcore/config_test.go index 77496357c..0ea10ea5a 100644 --- a/boilingcore/config_test.go +++ b/boilingcore/config_test.go @@ -3,7 +3,7 @@ package boilingcore import ( "testing" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) func TestConfig_OutputDirDepth(t *testing.T) { diff --git a/boilingcore/output.go b/boilingcore/output.go index 1db34138a..6492f455c 100644 --- a/boilingcore/output.go +++ b/boilingcore/output.go @@ -14,7 +14,7 @@ import ( "text/template" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/importers" ) var ( diff --git a/boilingcore/templates.go b/boilingcore/templates.go index 21a031da7..06dd951a7 100644 --- a/boilingcore/templates.go +++ b/boilingcore/templates.go @@ -12,9 +12,9 @@ import ( "text/template" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/strmangle" - "github.com/volatiletech/sqlboiler/templatebin" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/templatebin" + "github.com/volatiletech/strmangle" ) // templateData for sqlboiler templates diff --git a/boilingcore/text_helpers.go b/boilingcore/text_helpers.go index b62f3d821..3a2cc7f1e 100644 --- a/boilingcore/text_helpers.go +++ b/boilingcore/text_helpers.go @@ -3,8 +3,8 @@ package boilingcore import ( "strings" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/strmangle" ) // txtNameToOne creates the local and foreign function names for diff --git a/boilingcore/text_helpers_test.go b/boilingcore/text_helpers_test.go index 326a8df02..c668e8809 100644 --- a/boilingcore/text_helpers_test.go +++ b/boilingcore/text_helpers_test.go @@ -3,7 +3,7 @@ package boilingcore import ( "testing" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) func TestTxtNameToOne(t *testing.T) { diff --git a/drivers/binary_driver.go b/drivers/binary_driver.go index 41604c93e..242475a5a 100644 --- a/drivers/binary_driver.go +++ b/drivers/binary_driver.go @@ -8,7 +8,7 @@ import ( "os/exec" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/importers" ) type binaryDriver string diff --git a/drivers/column.go b/drivers/column.go index d92eb9323..a1040d1eb 100644 --- a/drivers/column.go +++ b/drivers/column.go @@ -3,7 +3,7 @@ package drivers import ( "strings" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/strmangle" ) // Column holds information about a database column. diff --git a/drivers/interface.go b/drivers/interface.go index 7f1a1f606..46477b8c6 100644 --- a/drivers/interface.go +++ b/drivers/interface.go @@ -6,8 +6,8 @@ import ( "sort" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/importers" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/importers" + "github.com/volatiletech/strmangle" ) // These constants are used in the config map passed into the driver diff --git a/drivers/interface_test.go b/drivers/interface_test.go index e03c0146f..c526dfc35 100644 --- a/drivers/interface_test.go +++ b/drivers/interface_test.go @@ -3,7 +3,7 @@ package drivers import ( "testing" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/strmangle" ) type testMockDriver struct{} diff --git a/drivers/mocks/mock.go b/drivers/mocks/mock.go index 554516a35..d49809313 100644 --- a/drivers/mocks/mock.go +++ b/drivers/mocks/mock.go @@ -1,9 +1,9 @@ package mocks import ( - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/importers" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/importers" + "github.com/volatiletech/strmangle" ) func init() { @@ -23,16 +23,16 @@ func (m *MockDriver) Imports() (importers.Collection, error) { return importers.Collection{ BasedOnType: importers.Map{ "null.Int": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.String": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Time": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bytes": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "time.Time": { diff --git a/drivers/registration_test.go b/drivers/registration_test.go index e0d91454a..a84778840 100644 --- a/drivers/registration_test.go +++ b/drivers/registration_test.go @@ -3,7 +3,7 @@ package drivers import ( "testing" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/importers" ) type testRegistrationDriver struct{} diff --git a/drivers/sqlboiler-mssql/driver/mssql.go b/drivers/sqlboiler-mssql/driver/mssql.go index 9977e1b89..6e553cf82 100644 --- a/drivers/sqlboiler-mssql/driver/mssql.go +++ b/drivers/sqlboiler-mssql/driver/mssql.go @@ -10,9 +10,9 @@ import ( // Side effect import go-mssqldb _ "github.com/denisenkom/go-mssqldb" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/importers" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/importers" + "github.com/volatiletech/strmangle" ) func init() { @@ -464,8 +464,8 @@ func (MSSQLDriver) Imports() (col importers.Collection, err error) { `"strings"`, }, ThirdParty: importers.List{ - `"github.com/volatiletech/sqlboiler/strmangle"`, - `"github.com/volatiletech/sqlboiler/drivers"`, + `"github.com/volatiletech/strmangle"`, + `"github.com/volatiletech/sqlboiler/v4/drivers"`, }, }, } @@ -489,8 +489,8 @@ func (MSSQLDriver) Imports() (col importers.Collection, err error) { `"github.com/kat-co/vala"`, `"github.com/friendsofgo/errors"`, `"github.com/spf13/viper"`, - `"github.com/volatiletech/sqlboiler/drivers/sqlboiler-mssql/driver"`, - `"github.com/volatiletech/sqlboiler/randomize"`, + `"github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mssql/driver"`, + `"github.com/volatiletech/randomize"`, `_ "github.com/denisenkom/go-mssqldb"`, }, }, @@ -498,61 +498,61 @@ func (MSSQLDriver) Imports() (col importers.Collection, err error) { col.BasedOnType = importers.Map{ "null.Float32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Float64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int8": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int16": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint8": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint16": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.String": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bool": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Time": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bytes": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "time.Time": { Standard: importers.List{`"time"`}, }, "types.Decimal": { - Standard: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + Standard: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.NullDecimal": { - Standard: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + Standard: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, } return col, err diff --git a/drivers/sqlboiler-mssql/driver/mssql_test.go b/drivers/sqlboiler-mssql/driver/mssql_test.go index 68e88ccb9..511acf87b 100644 --- a/drivers/sqlboiler-mssql/driver/mssql_test.go +++ b/drivers/sqlboiler-mssql/driver/mssql_test.go @@ -31,7 +31,7 @@ import ( "regexp" "testing" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) var ( diff --git a/drivers/sqlboiler-mssql/main.go b/drivers/sqlboiler-mssql/main.go index b85e368a7..e46b1e400 100644 --- a/drivers/sqlboiler-mssql/main.go +++ b/drivers/sqlboiler-mssql/main.go @@ -1,8 +1,8 @@ package main import ( - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/drivers/sqlboiler-mssql/driver" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mssql/driver" ) func main() { diff --git a/drivers/sqlboiler-mysql/driver/mysql.go b/drivers/sqlboiler-mysql/driver/mysql.go index 9b90a33e6..2055f3e0e 100644 --- a/drivers/sqlboiler-mysql/driver/mysql.go +++ b/drivers/sqlboiler-mysql/driver/mysql.go @@ -9,8 +9,8 @@ import ( "github.com/friendsofgo/errors" "github.com/go-sql-driver/mysql" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/importers" ) func init() { @@ -475,8 +475,8 @@ func (MySQLDriver) Imports() (col importers.Collection, err error) { `"strings"`, }, ThirdParty: importers.List{ - `"github.com/volatiletech/sqlboiler/strmangle"`, - `"github.com/volatiletech/sqlboiler/drivers"`, + `"github.com/volatiletech/strmangle"`, + `"github.com/volatiletech/sqlboiler/v4/drivers"`, }, }, } @@ -503,8 +503,8 @@ func (MySQLDriver) Imports() (col importers.Collection, err error) { `"github.com/kat-co/vala"`, `"github.com/friendsofgo/errors"`, `"github.com/spf13/viper"`, - `"github.com/volatiletech/sqlboiler/drivers/sqlboiler-mysql/driver"`, - `"github.com/volatiletech/sqlboiler/randomize"`, + `"github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql/driver"`, + `"github.com/volatiletech/randomize"`, `_ "github.com/go-sql-driver/mysql"`, }, }, @@ -512,68 +512,68 @@ func (MySQLDriver) Imports() (col importers.Collection, err error) { col.BasedOnType = importers.Map{ "null.Float32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Float64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int8": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int16": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint8": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint16": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.String": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bool": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Time": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bytes": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.JSON": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "time.Time": { Standard: importers.List{`"time"`}, }, "types.JSON": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.Decimal": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.NullDecimal": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, } return col, err diff --git a/drivers/sqlboiler-mysql/driver/mysql_test.go b/drivers/sqlboiler-mysql/driver/mysql_test.go index 86c19ccfe..f894cf716 100644 --- a/drivers/sqlboiler-mysql/driver/mysql_test.go +++ b/drivers/sqlboiler-mysql/driver/mysql_test.go @@ -18,7 +18,7 @@ import ( "os/exec" "testing" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) var ( diff --git a/drivers/sqlboiler-mysql/main.go b/drivers/sqlboiler-mysql/main.go index 20bb83de0..409cee2fa 100644 --- a/drivers/sqlboiler-mysql/main.go +++ b/drivers/sqlboiler-mysql/main.go @@ -1,8 +1,8 @@ package main import ( - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/drivers/sqlboiler-mysql/driver" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-mysql/driver" ) func main() { diff --git a/drivers/sqlboiler-psql/driver/psql.go b/drivers/sqlboiler-psql/driver/psql.go index db52b0251..ccde8c045 100644 --- a/drivers/sqlboiler-psql/driver/psql.go +++ b/drivers/sqlboiler-psql/driver/psql.go @@ -10,11 +10,11 @@ import ( "os" "strings" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/importers" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/strmangle" // Side-effect import sql driver _ "github.com/lib/pq" @@ -609,8 +609,8 @@ func (p PostgresDriver) Imports() (importers.Collection, error) { `"strings"`, }, ThirdParty: importers.List{ - `"github.com/volatiletech/sqlboiler/strmangle"`, - `"github.com/volatiletech/sqlboiler/drivers"`, + `"github.com/volatiletech/strmangle"`, + `"github.com/volatiletech/sqlboiler/v4/drivers"`, }, }, } @@ -636,138 +636,138 @@ func (p PostgresDriver) Imports() (importers.Collection, error) { `"github.com/kat-co/vala"`, `"github.com/friendsofgo/errors"`, `"github.com/spf13/viper"`, - `"github.com/volatiletech/sqlboiler/drivers/sqlboiler-psql/driver"`, - `"github.com/volatiletech/sqlboiler/randomize"`, + `"github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql/driver"`, + `"github.com/volatiletech/randomize"`, `_ "github.com/lib/pq"`, }, }, } col.BasedOnType = importers.Map{ "null.Float32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Float64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int8": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int16": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Int64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint8": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint16": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint32": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Uint64": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.String": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bool": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Time": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.JSON": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "null.Bytes": { - ThirdParty: importers.List{`"github.com/volatiletech/null"`}, + ThirdParty: importers.List{`"github.com/volatiletech/null/v8"`}, }, "time.Time": { Standard: importers.List{`"time"`}, }, "types.JSON": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.Decimal": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.BytesArray": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.Int64Array": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.Float64Array": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.BoolArray": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.StringArray": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.DecimalArray": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "types.HStore": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "pgeo.Point": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.Line": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.Lseg": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.Box": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.Path": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.Polygon": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "types.NullDecimal": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types"`}, }, "pgeo.Circle": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullPoint": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullLine": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullLseg": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullBox": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullPath": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullPolygon": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, "pgeo.NullCircle": { - ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/types/pgeo"`}, + ThirdParty: importers.List{`"github.com/volatiletech/sqlboiler/v4/types/pgeo"`}, }, } diff --git a/drivers/sqlboiler-psql/driver/psql_test.go b/drivers/sqlboiler-psql/driver/psql_test.go index 6a6508a9c..774f6aeb7 100644 --- a/drivers/sqlboiler-psql/driver/psql_test.go +++ b/drivers/sqlboiler-psql/driver/psql_test.go @@ -18,7 +18,7 @@ import ( "os/exec" "testing" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) var ( diff --git a/drivers/sqlboiler-psql/main.go b/drivers/sqlboiler-psql/main.go index dd13aa70c..fd10f37c0 100644 --- a/drivers/sqlboiler-psql/main.go +++ b/drivers/sqlboiler-psql/main.go @@ -1,8 +1,8 @@ package main import ( - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/drivers/sqlboiler-psql/driver" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql/driver" ) func main() { diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..652f5fb04 --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module github.com/volatiletech/sqlboiler/v4 + +go 1.14 + +require ( + github.com/DATA-DOG/go-sqlmock v1.4.1 + github.com/davecgh/go-spew v1.1.1 + github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e + github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5 + github.com/friendsofgo/errors v0.9.2 + github.com/go-sql-driver/mysql v1.5.0 + github.com/lib/pq v1.2.1-0.20191011153232-f91d3411e481 + github.com/spf13/cast v1.3.1 + github.com/spf13/cobra v1.0.0 + github.com/spf13/viper v1.6.3 + github.com/volatiletech/null/v8 v8.1.0 + github.com/volatiletech/randomize v0.0.1 + github.com/volatiletech/strmangle v0.0.1 +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..af38a160c --- /dev/null +++ b/go.sum @@ -0,0 +1,189 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DATA-DOG/go-sqlmock v1.4.1 h1:ThlnYciV1iM/V0OSF/dtkqWb6xo5qITT1TJBG1MRDJM= +github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +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/apmckinlay/gsuneido v0.0.0-20180907175622-1f10244968e3/go.mod h1:hJnaqxrCRgMCTWtpNz9XUFkBCREiQdlcyK6YNmOfroM= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +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/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-semver v0.2.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/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e h1:LzwWXEScfcTu7vUZNlDDWDARoSGEtvlDKK2BYHowNeE= +github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +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/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5 h1:HQGCJNlqt1dUs/BhtEKmqWd6LWS+DWYVxi9+Jo4r0jE= +github.com/ericlagergren/decimal v0.0.0-20181231230500-73749d4874d5/go.mod h1:1yj25TwtUlJ+pfOu9apAVaM1RWfZGg+aFpd4hPQZekQ= +github.com/friendsofgo/errors v0.9.2/go.mod h1:yCvFW5AkDIL9qn7suHVLiI/gH228n7PC4Pn44IGoTOI= +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-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-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +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-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +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/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +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/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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +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/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +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/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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.1-0.20191011153232-f91d3411e481 h1:r9fnMM01mkhtfe6QfLrr/90mBVLnJHge2jGeBvApOjk= +github.com/lib/pq v1.2.1-0.20191011153232-f91d3411e481/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/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/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= +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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +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/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/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +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 h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +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 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= +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/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs= +github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= +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/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +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/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/volatiletech/inflect v0.0.1 h1:2a6FcMQyhmPZcLa+uet3VJ8gLn/9svWhJxJYwvE8KsU= +github.com/volatiletech/inflect v0.0.1/go.mod h1:IBti31tG6phkHitLlr5j7shC5SOo//x0AjDzaJU1PLA= +github.com/volatiletech/null/v8 v8.1.0 h1:eAO3I31A5R04usY5SKMMfDcOCnEGyT/T4wRI0JVGp4U= +github.com/volatiletech/null/v8 v8.1.0/go.mod h1:98DbwNoKEpRrYtGjWFctievIfm4n4MxG0A6EBUcoS5g= +github.com/volatiletech/randomize v0.0.1 h1:eE5yajattWqTB2/eN8df4dw+8jwAzBtbdo5sbWC4nMk= +github.com/volatiletech/randomize v0.0.1/go.mod h1:GN3U0QYqfZ9FOJ67bzax1cqZ5q2xuj2mXrXBjWaRTlY= +github.com/volatiletech/strmangle v0.0.1 h1:UKQoHmY6be/R3tSvD2nQYrH41k43OJkidwEiC74KIzk= +github.com/volatiletech/strmangle v0.0.1/go.mod h1:F6RA6IkB5vq0yTG4GQ0UsbbRcl3ni9P76i+JrTBKFFg= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +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-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c h1:Vj5n4GlwjmQteupaxJ9+0FNOmBrHfq7vN4btdGoDZgI= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/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-20181220203305-927f97764cc3/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-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +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/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-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 h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +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-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +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.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/importers/imports.go b/importers/imports.go index d3dc0f426..8bc6eafa3 100644 --- a/importers/imports.go +++ b/importers/imports.go @@ -10,7 +10,7 @@ import ( "github.com/spf13/cast" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/strmangle" ) // Collection of imports for various templating purposes @@ -202,20 +202,20 @@ func NewDefaultImports() Collection { }, ThirdParty: List{ `"github.com/friendsofgo/errors"`, - `"github.com/volatiletech/sqlboiler/boil"`, - `"github.com/volatiletech/sqlboiler/queries"`, - `"github.com/volatiletech/sqlboiler/queries/qm"`, - `"github.com/volatiletech/sqlboiler/queries/qmhelper"`, - `"github.com/volatiletech/sqlboiler/strmangle"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, + `"github.com/volatiletech/sqlboiler/v4/queries"`, + `"github.com/volatiletech/sqlboiler/v4/queries/qm"`, + `"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"`, + `"github.com/volatiletech/strmangle"`, }, } col.Singleton = Map{ "boil_queries": { ThirdParty: List{ - `"github.com/volatiletech/sqlboiler/drivers"`, - `"github.com/volatiletech/sqlboiler/queries"`, - `"github.com/volatiletech/sqlboiler/queries/qm"`, + `"github.com/volatiletech/sqlboiler/v4/drivers"`, + `"github.com/volatiletech/sqlboiler/v4/queries"`, + `"github.com/volatiletech/sqlboiler/v4/queries/qm"`, }, }, "boil_types": { @@ -224,8 +224,8 @@ func NewDefaultImports() Collection { }, ThirdParty: List{ `"github.com/friendsofgo/errors"`, - `"github.com/volatiletech/sqlboiler/boil"`, - `"github.com/volatiletech/sqlboiler/strmangle"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, + `"github.com/volatiletech/strmangle"`, }, }, } @@ -237,10 +237,10 @@ func NewDefaultImports() Collection { `"testing"`, }, ThirdParty: List{ - `"github.com/volatiletech/sqlboiler/boil"`, - `"github.com/volatiletech/sqlboiler/queries"`, - `"github.com/volatiletech/sqlboiler/randomize"`, - `"github.com/volatiletech/sqlboiler/strmangle"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, + `"github.com/volatiletech/sqlboiler/v4/queries"`, + `"github.com/volatiletech/randomize"`, + `"github.com/volatiletech/strmangle"`, }, } @@ -259,7 +259,7 @@ func NewDefaultImports() Collection { }, ThirdParty: List{ `"github.com/spf13/viper"`, - `"github.com/volatiletech/sqlboiler/boil"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, }, }, "boil_queries_test": { @@ -272,7 +272,7 @@ func NewDefaultImports() Collection { `"regexp"`, }, ThirdParty: List{ - `"github.com/volatiletech/sqlboiler/boil"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, }, }, "boil_suites_test": { diff --git a/importers/imports_test.go b/importers/imports_test.go index a2aa634fd..f055df22b 100644 --- a/importers/imports_test.go +++ b/importers/imports_test.go @@ -175,7 +175,7 @@ func TestAddTypeImports(t *testing.T) { `"fmt"`, }, ThirdParty: List{ - `"github.com/volatiletech/sqlboiler/boil"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, }, } @@ -186,8 +186,8 @@ func TestAddTypeImports(t *testing.T) { `"time"`, }, ThirdParty: List{ - `"github.com/volatiletech/null"`, - `"github.com/volatiletech/sqlboiler/boil"`, + `"github.com/volatiletech/null/v8"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, }, } @@ -200,7 +200,7 @@ func TestAddTypeImports(t *testing.T) { imps := NewDefaultImports() imps.BasedOnType = Map{ - "null.Time": Set{ThirdParty: List{`"github.com/volatiletech/null"`}}, + "null.Time": Set{ThirdParty: List{`"github.com/volatiletech/null/v8"`}}, "time.Time": Set{Standard: List{`"time"`}}, } @@ -217,8 +217,8 @@ func TestAddTypeImports(t *testing.T) { `"time"`, }, ThirdParty: List{ - `"github.com/volatiletech/null"`, - `"github.com/volatiletech/sqlboiler/boil"`, + `"github.com/volatiletech/null/v8"`, + `"github.com/volatiletech/sqlboiler/v4/boil"`, }, } @@ -234,11 +234,11 @@ func TestMergeSet(t *testing.T) { a := Set{ Standard: List{"fmt"}, - ThirdParty: List{"github.com/volatiletech/sqlboiler", "github.com/volatiletech/null"}, + ThirdParty: List{"github.com/volatiletech/sqlboiler/v4", "github.com/volatiletech/null/v8"}, } b := Set{ Standard: List{"os"}, - ThirdParty: List{"github.com/volatiletech/sqlboiler"}, + ThirdParty: List{"github.com/volatiletech/sqlboiler/v4"}, } c := mergeSet(a, b) @@ -246,8 +246,8 @@ func TestMergeSet(t *testing.T) { if c.Standard[0] != "fmt" && c.Standard[1] != "os" { t.Errorf("Wanted: fmt, os got: %#v", c.Standard) } - if c.ThirdParty[0] != "github.com/volatiletech/null" && c.ThirdParty[1] != "github.com/volatiletech/sqlboiler" { - t.Errorf("Wanted: github.com/volatiletech/sqlboiler, github.com/volatiletech/null got: %#v", c.ThirdParty) + if c.ThirdParty[0] != "github.com/volatiletech/null/v8" && c.ThirdParty[1] != "github.com/volatiletech/sqlboiler/v4" { + t.Errorf("Wanted: github.com/volatiletech/sqlboiler, github.com/volatiletech/null/v8 got: %#v", c.ThirdParty) } } diff --git a/main.go b/main.go index 62989a69f..e182ebeb2 100644 --- a/main.go +++ b/main.go @@ -11,14 +11,14 @@ import ( "github.com/friendsofgo/errors" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/volatiletech/sqlboiler/boilingcore" - "github.com/volatiletech/sqlboiler/drivers" - "github.com/volatiletech/sqlboiler/importers" + "github.com/volatiletech/sqlboiler/v4/boilingcore" + "github.com/volatiletech/sqlboiler/v4/drivers" + "github.com/volatiletech/sqlboiler/v4/importers" ) //go:generate go-bindata -nometadata -pkg templatebin -o templatebin/bindata.go templates templates/singleton templates_test templates_test/singleton -const sqlBoilerVersion = "3.6.1" +const sqlBoilerVersion = "4.0.0" var ( flagConfigFile string @@ -178,7 +178,7 @@ func preRun(cmd *cobra.Command, args []string) error { NoRowsAffected: viper.GetBool("no-rows-affected"), NoAutoTimestamps: viper.GetBool("no-auto-timestamps"), NoDriverTemplates: viper.GetBool("no-driver-templates"), - NoBackReferencing: viper.GetBool("no-back-referencing"), + NoBackReferencing: viper.GetBool("no-back-referencing"), Wipe: viper.GetBool("wipe"), StructTagCasing: strings.ToLower(viper.GetString("struct-tag-casing")), // camel | snake | title TagIgnore: viper.GetStringSlice("tag-ignore"), diff --git a/queries/eager_load.go b/queries/eager_load.go index 688b85565..a3f5da2fe 100644 --- a/queries/eager_load.go +++ b/queries/eager_load.go @@ -7,8 +7,8 @@ import ( "strings" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/boil" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/strmangle" ) type loadRelationshipState struct { diff --git a/queries/eager_load_test.go b/queries/eager_load_test.go index 542679f0c..c887e55a9 100644 --- a/queries/eager_load_test.go +++ b/queries/eager_load_test.go @@ -5,7 +5,7 @@ import ( "reflect" "testing" - "github.com/volatiletech/sqlboiler/boil" + "github.com/volatiletech/sqlboiler/v4/boil" ) var testEagerCounters struct { diff --git a/queries/helpers_test.go b/queries/helpers_test.go index 44ce8a0bd..fef25b312 100644 --- a/queries/helpers_test.go +++ b/queries/helpers_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "github.com/volatiletech/null" + "github.com/volatiletech/null/v8" ) type testObj struct { diff --git a/queries/qm/query_mods.go b/queries/qm/query_mods.go index 2d21211bf..b7c947f05 100644 --- a/queries/qm/query_mods.go +++ b/queries/qm/query_mods.go @@ -3,8 +3,8 @@ package qm import ( "strings" - "github.com/volatiletech/sqlboiler/queries" - "github.com/volatiletech/sqlboiler/queries/qmhelper" + "github.com/volatiletech/sqlboiler/v4/queries" + "github.com/volatiletech/sqlboiler/v4/queries/qmhelper" ) // QueryMod modifies a query object. diff --git a/queries/qmhelper/qmhelper.go b/queries/qmhelper/qmhelper.go index 3009d3741..ed9bdf019 100644 --- a/queries/qmhelper/qmhelper.go +++ b/queries/qmhelper/qmhelper.go @@ -4,7 +4,7 @@ import ( "fmt" "reflect" - "github.com/volatiletech/sqlboiler/queries" + "github.com/volatiletech/sqlboiler/v4/queries" ) // Nullable object diff --git a/queries/query.go b/queries/query.go index d9ccd3160..5efab3984 100644 --- a/queries/query.go +++ b/queries/query.go @@ -5,8 +5,8 @@ import ( "database/sql" "fmt" - "github.com/volatiletech/sqlboiler/boil" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/sqlboiler/v4/drivers" ) // joinKind is the type of join diff --git a/queries/query_builders.go b/queries/query_builders.go index af65392a3..590ae2b7e 100644 --- a/queries/query_builders.go +++ b/queries/query_builders.go @@ -7,7 +7,7 @@ import ( "sort" "strings" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/strmangle" ) var ( diff --git a/queries/query_builders_test.go b/queries/query_builders_test.go index 98a06a78a..88f46a860 100644 --- a/queries/query_builders_test.go +++ b/queries/query_builders_test.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/davecgh/go-spew/spew" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" ) var writeGoldenFiles = flag.Bool( diff --git a/queries/reflect.go b/queries/reflect.go index 9a848e883..19ee5bea5 100644 --- a/queries/reflect.go +++ b/queries/reflect.go @@ -13,8 +13,8 @@ import ( "unicode" "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/boil" - "github.com/volatiletech/sqlboiler/strmangle" + "github.com/volatiletech/sqlboiler/v4/boil" + "github.com/volatiletech/strmangle" ) type colBindingKey struct { diff --git a/queries/reflect_test.go b/queries/reflect_test.go index 177c12d99..0b0bb459a 100644 --- a/queries/reflect_test.go +++ b/queries/reflect_test.go @@ -12,7 +12,7 @@ import ( "testing" "time" - "github.com/volatiletech/sqlboiler/drivers" + "github.com/volatiletech/sqlboiler/v4/drivers" "github.com/DATA-DOG/go-sqlmock" ) diff --git a/randomize/random.go b/randomize/random.go deleted file mode 100644 index 8b0d51d91..000000000 --- a/randomize/random.go +++ /dev/null @@ -1,203 +0,0 @@ -package randomize - -import ( - "crypto/md5" - "fmt" - "math/rand" - "strconv" - "strings" - "time" - - "github.com/gofrs/uuid" - "github.com/volatiletech/sqlboiler/strmangle" -) - -const alphabetAll = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -const alphabetLowerAlpha = "abcdefghijklmnopqrstuvwxyz" - -// Str creates a randomized string from printable characters in the alphabet -func Str(nextInt func() int64, ln int) string { - str := make([]byte, ln) - for i := 0; i < ln; i++ { - str[i] = byte(alphabetAll[nextInt()%int64(len(alphabetAll))]) - } - - return string(str) -} - -// FormattedString checks a field type to see if it's in a range of special -// values and if so returns a randomized string for it. -func FormattedString(nextInt func() int64, fieldType string) (string, bool) { - if strings.HasPrefix(fieldType, "enum") { - enum, err := EnumValue(nextInt, fieldType) - if err != nil { - panic(err) - } - - return enum, true - } - - switch fieldType { - case "json", "jsonb": - return `"` + Str(nextInt, 1) + `"`, true - case "interval": - return strconv.Itoa((int(nextInt())%26)+2) + " days", true - case "uuid": - randomUUID, err := uuid.NewV4() - if err != nil { - panic(err) - } - return randomUUID.String(), true - case "cidr", "inet": - return randNetAddr(nextInt), true - case "macaddr": - return randMacAddr(nextInt), true - case "pg_lsn": - return randLsn(nextInt), true - case "txid_snapshot": - return randTxID(nextInt), true - case "money": - return randMoney(nextInt), true - case "time": - return randTime(nextInt), true - } - - return "", false -} - -// MediumInt is a special case in mysql (thanks for that -_-) -// this function checks if the fieldtype matches and if so returns -// a random value in the proper range. -func MediumInt(nextInt func() int64, fieldType string) (int32, bool) { - if fieldType == "mediumint" { - return int32(nextInt()) % 8388607, true - } - - return 0, false -} - -// MediumUint is the unsigned version of MediumInt -func MediumUint(nextInt func() int64, fieldType string) (uint32, bool) { - fmt.Println(fieldType) - if fieldType == "mediumint" { - return uint32(nextInt()) % 16777215, true - } - - return 0, false -} - -// Date generates a random time.Time between 1850 and 2050. -// Only the Day/Month/Year columns are set so that Dates and DateTimes do -// not cause mismatches in the test data comparisons. -func Date(nextInt func() int64) time.Time { - t := time.Date( - int(1972+nextInt()%60), - time.Month(1+(nextInt()%12)), - int(1+(nextInt()%25)), - 0, - 0, - 0, - 0, - time.UTC, - ) - - return t -} - -// EnumValue takes an enum field type, parses it's definition -// to figure out valid values, and selects a random one from within them. -func EnumValue(nextInt func() int64, enum string) (string, error) { - vals := strmangle.ParseEnumVals(enum) - if vals == nil || len(vals) == 0 { - return "", fmt.Errorf("unable to parse enum string: %s", enum) - } - - return vals[int(nextInt())%len(vals)], nil -} - -// ByteSlice creates a random set of bytes (non-printables included) -func ByteSlice(nextInt func() int64, ln int) []byte { - str := make([]byte, ln) - for i := 0; i < ln; i++ { - str[i] = byte(nextInt() % 256) - } - - return str -} - -func randNetAddr(nextInt func() int64) string { - return fmt.Sprintf( - "%d.%d.%d.%d", - nextInt()%254+1, - nextInt()%254+1, - nextInt()%254+1, - nextInt()%254+1, - ) -} - -func randMacAddr(nextInt func() int64) string { - buf := make([]byte, 6) - for i := range buf { - buf[i] = byte(nextInt()) - } - - // Set the local bit - buf[0] |= 2 - return fmt.Sprintf( - "%02x:%02x:%02x:%02x:%02x:%02x", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], - ) -} - -func randLsn(nextInt func() int64) string { - a := nextInt() % 9000000 - b := nextInt() % 9000000 - return fmt.Sprintf("%d/%d", a, b) -} - -func randTxID(nextInt func() int64) string { - // Order of integers is relevant - a := nextInt()%200 + 100 - b := a + 100 - c := a - d := a + 50 - return fmt.Sprintf("%d:%d:%d,%d", a, b, c, d) -} - -func randMoney(nextInt func() int64) string { - return fmt.Sprintf("%d.00", nextInt()%100000) -} - -func randTime(nextInt func() int64) string { - return fmt.Sprintf("%d:%d:%d", nextInt()%24, nextInt()%60, nextInt()%60) -} - -// StableDBName takes a database name in, and generates -// a random string using the database name as the rand Seed. -// getDBNameHash is used to generate unique test database names. -func StableDBName(input string) string { - return randStrFromSource(stableSource(input), 40) -} - -// stableSource takes an input value, and produces a random -// seed from it that will produce very few collisions in -// a 40 character random string made from a different alphabet. -func stableSource(input string) *rand.Rand { - sum := md5.Sum([]byte(input)) - var seed int64 - for i, byt := range sum { - seed ^= int64(byt) << uint((i*4)%64) - } - return rand.New(rand.NewSource(seed)) -} - -func randStrFromSource(r *rand.Rand, length int) string { - ln := len(alphabetLowerAlpha) - - output := make([]rune, length) - for i := 0; i < length; i++ { - output[i] = rune(alphabetLowerAlpha[r.Intn(ln)]) - } - - return string(output) -} diff --git a/randomize/random_test.go b/randomize/random_test.go deleted file mode 100644 index ee910ce61..000000000 --- a/randomize/random_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package randomize - -import "testing" - -func TestStableDBName(t *testing.T) { - t.Parallel() - - db := "awesomedb" - - one, two := StableDBName(db), StableDBName(db) - - if len(one) != 40 { - t.Error("want 40 characters:", len(one), one) - } - - if one != two { - t.Error("it should always produce the same value") - } -} diff --git a/randomize/randomize.go b/randomize/randomize.go deleted file mode 100644 index bac6c7aed..000000000 --- a/randomize/randomize.go +++ /dev/null @@ -1,292 +0,0 @@ -// Package randomize has helpers for randomization of structs and fields -package randomize - -import ( - "math" - "reflect" - "regexp" - "sort" - "sync/atomic" - "time" - - "github.com/friendsofgo/errors" - "github.com/volatiletech/sqlboiler/strmangle" -) - -// Randomizer allows a field to be randomized -type Randomizer interface { - // Randomize should panic if there's no ability to randomize with the current parameters. - // - // nextInt can be called to create "random" sequential integers. This is done to avoid collisions in unique columns - // for the tests. - // - // fieldType is used in the cases where the actual type (string, null string etc.) can actually be multiple - // types of things that have specific randomization requirements, like a uuid for example is a normal null.String - // but when randomizing that null string it must create a valid uuid or the database will reject it. - // - // shouldBeNull is a suggestion that a field should be null in this instance. The randomize implementation - // can ignore this if the field cannot be null either because the type doesn't support it or there - // is no ability for a field of this type to be null. - Randomize(nextInt func() int64, fieldType string, shouldBeNull bool) -} - -var ( - typeTime = reflect.TypeOf(time.Time{}) - rgxValidTime = regexp.MustCompile(`[2-9]+`) -) - -// Seed is an atomic counter for pseudo-randomization structs. Using full -// randomization leads to collisions in a domain where uniqueness is an -// important factor. -type Seed int64 - -// NewSeed creates a new seed for pseudo-randomization. -func NewSeed() *Seed { - s := new(int64) - *s = time.Now().Unix() - return (*Seed)(s) -} - -// NextInt retrives an integer in order -func (s *Seed) NextInt() int64 { - return atomic.AddInt64((*int64)(s), 1) -} - -// Struct gets its fields filled with random data based on the seed. -// It will ignore the fields in the blacklist. -// It will ignore fields that have the struct tag boil:"-" -func Struct(s *Seed, str interface{}, colTypes map[string]string, canBeNull bool, blacklist ...string) error { - // Don't modify blacklist - copyBlacklist := make([]string, len(blacklist)) - copy(copyBlacklist, blacklist) - blacklist = copyBlacklist - blacklist = append(blacklist, "deleted_at") - - sort.Strings(blacklist) - - // Check if it's pointer - value := reflect.ValueOf(str) - kind := value.Kind() - if kind != reflect.Ptr { - return errors.Errorf("Outer element should be a pointer, given a non-pointer: %T", str) - } - - // Check if it's a struct - value = value.Elem() - kind = value.Kind() - if kind != reflect.Struct { - return errors.Errorf("Inner element should be a struct, given a non-struct: %T", str) - } - - typ := value.Type() - nFields := value.NumField() - - // Iterate through fields, randomizing - for i := 0; i < nFields; i++ { - fieldVal := value.Field(i) - fieldTyp := typ.Field(i) - - var found bool - for _, v := range blacklist { - if strmangle.TitleCase(v) == fieldTyp.Name || v == fieldTyp.Tag.Get("boil") { - found = true - break - } - } - - if found { - continue - } - - if fieldTyp.Tag.Get("boil") == "-" { - continue - } - - fieldDBType := colTypes[fieldTyp.Name] - if err := randomizeField(s, fieldVal, fieldDBType, canBeNull); err != nil { - return err - } - } - - return nil -} - -// randomizeField changes the value at field to a "randomized" value. -// -// If canBeNull is false: -// The value will always be a non-null and non-zero value. -// -// If canBeNull is true: -// The value has the possibility of being null or a non-zero value at random. -func randomizeField(s *Seed, field reflect.Value, fieldType string, canBeNull bool) error { - kind := field.Kind() - typ := field.Type() - - var shouldBeNull bool - // Check the regular columns, these can be set or not set - // depending on the canBeNull flag. - // if canBeNull is false, then never return null values. - if canBeNull { - // 1 in 3 chance of being null or zero value - shouldBeNull = s.NextInt()%3 == 0 - } - - // The struct and it's fields should always be addressable - ptrToField := field.Addr() - if r, ok := ptrToField.Interface().(Randomizer); ok { - r.Randomize(s.NextInt, fieldType, shouldBeNull) - return nil - } - - var value interface{} - - if kind == reflect.Struct { - if shouldBeNull { - value = getStructNullValue(s, fieldType, typ) - } else { - value = getStructRandValue(s, fieldType, typ) - } - } else { - // only get zero values for non byte slices - // to stop mysql from being a jerk - if shouldBeNull && kind != reflect.Slice { - value = getVariableZeroValue(s, fieldType, kind, typ) - } else { - value = getVariableRandValue(s, fieldType, kind, typ) - } - } - - if value == nil { - return errors.Errorf("unsupported type: %s", typ.String()) - } - - newValue := reflect.ValueOf(value) - if reflect.TypeOf(value) != typ { - newValue = newValue.Convert(typ) - } - - field.Set(newValue) - - return nil -} - -// getStructNullValue for the matching type. -func getStructNullValue(s *Seed, fieldType string, typ reflect.Type) interface{} { - if typ == typeTime { - // MySQL does not support 0 value time.Time, so use rand - return Date(s.NextInt) - } - - return nil -} - -// getStructRandValue returns a "random" value for the matching type. -// The randomness is really an incrementation of the global seed, -// this is done to avoid duplicate key violations. -func getStructRandValue(s *Seed, fieldType string, typ reflect.Type) interface{} { - if typ == typeTime { - return Date(s.NextInt) - } - - return nil -} - -// getVariableZeroValue for the matching type. -func getVariableZeroValue(s *Seed, fieldType string, kind reflect.Kind, typ reflect.Type) interface{} { - switch kind { - case reflect.Float32: - return float32(0) - case reflect.Float64: - return float64(0) - case reflect.Int: - return int(0) - case reflect.Int8: - return int8(0) - case reflect.Int16: - return int16(0) - case reflect.Int32: - return int32(0) - case reflect.Int64: - return int64(0) - case reflect.Uint: - return uint(0) - case reflect.Uint8: - return uint8(0) - case reflect.Uint16: - return uint16(0) - case reflect.Uint32: - return uint32(0) - case reflect.Uint64: - return uint64(0) - case reflect.Bool: - return false - case reflect.String: - // Some of these formatted strings cannot tolerate 0 values, so - // we ignore the request for a null value. - str, ok := FormattedString(s.NextInt, fieldType) - if ok { - return str - } - return "" - case reflect.Slice: - return []byte{} - } - - return nil -} - -// getVariableRandValue returns a "random" value for the matching kind. -// The randomness is really an incrementation of the global seed, -// this is done to avoid duplicate key violations. -func getVariableRandValue(s *Seed, fieldType string, kind reflect.Kind, typ reflect.Type) interface{} { - switch kind { - case reflect.Float32: - return float32(float32(s.NextInt()%10)/10.0 + float32(s.NextInt()%10)) - case reflect.Float64: - return float64(float64(s.NextInt()%10)/10.0 + float64(s.NextInt()%10)) - case reflect.Int: - return int(s.NextInt()) - case reflect.Int8: - return int8(s.NextInt() % math.MaxInt8) - case reflect.Int16: - return int16(s.NextInt() % math.MaxInt16) - case reflect.Int32: - val, ok := MediumInt(s.NextInt, fieldType) - if ok { - return val - } - return int32(s.NextInt() % math.MaxInt32) - case reflect.Int64: - return int64(s.NextInt()) - case reflect.Uint: - return uint(s.NextInt()) - case reflect.Uint8: - return uint8(s.NextInt() % math.MaxUint8) - case reflect.Uint16: - return uint16(s.NextInt() % math.MaxUint16) - case reflect.Uint32: - val, ok := MediumUint(s.NextInt, fieldType) - if ok { - return val - } - return uint32(s.NextInt() % math.MaxUint32) - case reflect.Uint64: - return uint64(s.NextInt()) - case reflect.Bool: - return true - case reflect.String: - str, ok := FormattedString(s.NextInt, fieldType) - if ok { - return str - } - return Str(s.NextInt, 1) - case reflect.Slice: - sliceVal := typ.Elem() - if sliceVal.Kind() != reflect.Uint8 { - return errors.Errorf("unsupported slice type: %T, was expecting byte slice.", typ.String()) - } - return ByteSlice(s.NextInt, 1) - } - - return nil -} diff --git a/randomize/randomize_test.go b/randomize/randomize_test.go deleted file mode 100644 index ad9ac4c86..000000000 --- a/randomize/randomize_test.go +++ /dev/null @@ -1,161 +0,0 @@ -package randomize - -import ( - "reflect" - "testing" - "time" -) - -type MagicType struct { - Value int - Randomized bool -} - -func (m *MagicType) Randomize(nextInt func() int64, fieldType string, shouldBeNull bool) { - m.Value = int(nextInt()) - m.Randomized = true -} - -func TestRandomizeStruct(t *testing.T) { - t.Parallel() - - s := NewSeed() - - var testStruct = struct { - Int int - Int64 int64 - Float64 float64 - Bool bool - Time time.Time - String string - ByteSlice []byte - Interval string - - Magic MagicType - - Ignore int - }{} - - fieldTypes := map[string]string{ - "Int": "integer", - "Int64": "bigint", - "Float64": "decimal", - "Bool": "boolean", - "Time": "date", - "String": "character varying", - "ByteSlice": "bytea", - "Interval": "interval", - "Magic": "magic_type", - "Ignore": "integer", - } - - err := Struct(s, &testStruct, fieldTypes, true, "Ignore") - if err != nil { - t.Fatal(err) - } - - if testStruct.Ignore != 0 { - t.Error("blacklisted value was filled in:", testStruct.Ignore) - } - - if testStruct.Int == 0 && - testStruct.Int64 == 0 && - testStruct.Float64 == 0 && - testStruct.Bool == false && - testStruct.Time.IsZero() && - testStruct.String == "" && - testStruct.Interval == "" && - testStruct.Magic.Value == 0 && - testStruct.ByteSlice == nil { - t.Errorf("the regular values are not being randomized: %#v", testStruct) - } - - if !testStruct.Magic.Randomized { - t.Error("The randomize interface should have been used") - } -} - -func TestRandomizeField(t *testing.T) { - t.Parallel() - - type RandomizeTest struct { - In interface{} - Typs []string - Out interface{} - } - - s := NewSeed() - inputs := []RandomizeTest{ - {In: new(float32), Out: float32(0), Typs: []string{"real"}}, - {In: new(float64), Out: float64(0), Typs: []string{"numeric"}}, - {In: new(int), Out: int(0), Typs: []string{"integer"}}, - {In: new(int8), Out: int8(0), Typs: []string{"integer"}}, - {In: new(int16), Out: int16(0), Typs: []string{"smallserial"}}, - {In: new(int32), Out: int32(0), Typs: []string{"integer"}}, - {In: new(int64), Out: int64(0), Typs: []string{"bigserial"}}, - {In: new(uint), Out: uint(0), Typs: []string{"integer"}}, - {In: new(uint8), Out: uint8(0), Typs: []string{"integer"}}, - {In: new(uint16), Out: uint16(0), Typs: []string{"integer"}}, - {In: new(uint32), Out: uint32(0), Typs: []string{"integer"}}, - {In: new(uint64), Out: uint64(0), Typs: []string{"integer"}}, - - {In: new(bool), Out: false}, - {In: new(string), Out: ""}, - {In: new([]byte), Out: new([]byte)}, - {In: &time.Time{}, Out: &time.Time{}}, - } - - for i := 0; i < len(inputs); i++ { - for _, typ := range inputs[i].Typs { - val := reflect.Indirect(reflect.ValueOf(&inputs[i])) - field := val.FieldByName("In").Elem().Elem() - - // Make sure we never get back values that would be considered null - // by the boil whitelist generator, or by the database driver - if err := randomizeField(s, field, typ, false); err != nil { - t.Errorf("%d) %s", i, err) - } - - if inputs[i].In == inputs[i].Out { - t.Errorf("%d) Field should not be null, got: %v -- type: %s\n", i, inputs[i].In, typ) - } - } - } -} - -func TestEnumValue(t *testing.T) { - t.Parallel() - - s := NewSeed() - - enum1 := "enum.workday('monday','tuesday')" - enum2 := "enum('monday','tuesday')" - enum3 := "enum('monday')" - - r1, err := EnumValue(s.NextInt, enum1) - if err != nil { - t.Error(err) - } - - if r1 != "monday" && r1 != "tuesday" { - t.Errorf("Expected monday or tuesday, got: %q", r1) - } - - r2, err := EnumValue(s.NextInt, enum2) - if err != nil { - t.Error(err) - } - - if r2 != "monday" && r2 != "tuesday" { - t.Errorf("Expected monday or tuesday, got: %q", r2) - } - - r3, err := EnumValue(s.NextInt, enum3) - if err != nil { - t.Error(err) - } - - if r3 != "monday" { - t.Errorf("Expected monday got: %q", r3) - } -} diff --git a/strmangle/buf_pool.go b/strmangle/buf_pool.go deleted file mode 100644 index 750568c29..000000000 --- a/strmangle/buf_pool.go +++ /dev/null @@ -1,27 +0,0 @@ -package strmangle - -import ( - "bytes" - "sync" -) - -var bufPool = sync.Pool{ - New: newBuffer, -} - -func newBuffer() interface{} { - return &bytes.Buffer{} -} - -// GetBuffer retrieves a buffer from the buffer pool -func GetBuffer() *bytes.Buffer { - buf := bufPool.Get().(*bytes.Buffer) - buf.Reset() - - return buf -} - -// PutBuffer back into the buffer pool -func PutBuffer(buf *bytes.Buffer) { - bufPool.Put(buf) -} diff --git a/strmangle/inflect.go b/strmangle/inflect.go deleted file mode 100644 index 556135cc4..000000000 --- a/strmangle/inflect.go +++ /dev/null @@ -1,205 +0,0 @@ -package strmangle - -import "github.com/volatiletech/inflect" - -var boilRuleset *inflect.Ruleset - -// create a new ruleset and load it with the default -// set of common English pluralization rules -func newBoilRuleset() *inflect.Ruleset { - rs := inflect.NewRuleset() - rs.AddPlural("s", "s") - rs.AddPlural("testis", "testes") - rs.AddPlural("axis", "axes") - rs.AddPlural("octopus", "octopi") - rs.AddPlural("virus", "viri") - rs.AddPlural("octopi", "octopi") - rs.AddPlural("viri", "viri") - rs.AddPlural("alias", "aliases") - rs.AddPlural("status", "statuses") - rs.AddPlural("bus", "buses") - rs.AddPlural("buffalo", "buffaloes") - rs.AddPlural("tomato", "tomatoes") - rs.AddPlural("tum", "ta") - rs.AddPlural("ium", "ia") - rs.AddPlural("ta", "ta") - rs.AddPlural("ia", "ia") - rs.AddPlural("sis", "ses") - rs.AddPlural("lf", "lves") - rs.AddPlural("rf", "rves") - rs.AddPlural("afe", "aves") - rs.AddPlural("bfe", "bves") - rs.AddPlural("cfe", "cves") - rs.AddPlural("dfe", "dves") - rs.AddPlural("efe", "eves") - rs.AddPlural("gfe", "gves") - rs.AddPlural("hfe", "hves") - rs.AddPlural("ife", "ives") - rs.AddPlural("jfe", "jves") - rs.AddPlural("kfe", "kves") - rs.AddPlural("lfe", "lves") - rs.AddPlural("mfe", "mves") - rs.AddPlural("nfe", "nves") - rs.AddPlural("ofe", "oves") - rs.AddPlural("pfe", "pves") - rs.AddPlural("qfe", "qves") - rs.AddPlural("rfe", "rves") - rs.AddPlural("sfe", "sves") - rs.AddPlural("tfe", "tves") - rs.AddPlural("ufe", "uves") - rs.AddPlural("vfe", "vves") - rs.AddPlural("wfe", "wves") - rs.AddPlural("xfe", "xves") - rs.AddPlural("yfe", "yves") - rs.AddPlural("zfe", "zves") - rs.AddPlural("hive", "hives") - rs.AddPlural("quy", "quies") - rs.AddPlural("by", "bies") - rs.AddPlural("cy", "cies") - rs.AddPlural("dy", "dies") - rs.AddPlural("fy", "fies") - rs.AddPlural("gy", "gies") - rs.AddPlural("hy", "hies") - rs.AddPlural("jy", "jies") - rs.AddPlural("ky", "kies") - rs.AddPlural("ly", "lies") - rs.AddPlural("my", "mies") - rs.AddPlural("ny", "nies") - rs.AddPlural("py", "pies") - rs.AddPlural("qy", "qies") - rs.AddPlural("ry", "ries") - rs.AddPlural("sy", "sies") - rs.AddPlural("ty", "ties") - rs.AddPlural("vy", "vies") - rs.AddPlural("wy", "wies") - rs.AddPlural("xy", "xies") - rs.AddPlural("zy", "zies") - rs.AddPlural("x", "xes") - rs.AddPlural("ch", "ches") - rs.AddPlural("ss", "sses") - rs.AddPlural("sh", "shes") - rs.AddPlural("matrix", "matrices") - rs.AddPlural("vertix", "vertices") - rs.AddPlural("indix", "indices") - rs.AddPlural("matrex", "matrices") - rs.AddPlural("vertex", "vertices") - rs.AddPlural("index", "indices") - rs.AddPlural("mouse", "mice") - rs.AddPlural("louse", "lice") - rs.AddPlural("mice", "mice") - rs.AddPlural("lice", "lice") - rs.AddPluralExact("ox", "oxen", true) - rs.AddPluralExact("oxen", "oxen", true) - rs.AddPluralExact("quiz", "quizzes", true) - rs.AddSingular("s", "") - rs.AddSingular("ss", "ss") - rs.AddSingular("as", "as") - rs.AddSingular("us", "us") - rs.AddSingular("is", "is") - rs.AddSingular("schemas", "schema") - rs.AddSingular("news", "news") - rs.AddSingular("ta", "tum") - rs.AddSingular("ia", "ium") - rs.AddSingular("analyses", "analysis") - rs.AddSingular("bases", "basis") - rs.AddSingular("diagnoses", "diagnosis") - rs.AddSingular("parentheses", "parenthesis") - rs.AddSingular("prognoses", "prognosis") - rs.AddSingular("synopses", "synopsis") - rs.AddSingular("theses", "thesis") - rs.AddSingular("analyses", "analysis") - rs.AddSingular("aves", "afe") - rs.AddSingular("bves", "bfe") - rs.AddSingular("cves", "cfe") - rs.AddSingular("dves", "dfe") - rs.AddSingular("eves", "efe") - rs.AddSingular("gves", "gfe") - rs.AddSingular("hves", "hfe") - rs.AddSingular("ives", "ife") - rs.AddSingular("jves", "jfe") - rs.AddSingular("kves", "kfe") - rs.AddSingular("lves", "lfe") - rs.AddSingular("mves", "mfe") - rs.AddSingular("nves", "nfe") - rs.AddSingular("oves", "ofe") - rs.AddSingular("pves", "pfe") - rs.AddSingular("qves", "qfe") - rs.AddSingular("rves", "rfe") - rs.AddSingular("sves", "sfe") - rs.AddSingular("tves", "tfe") - rs.AddSingular("uves", "ufe") - rs.AddSingular("vves", "vfe") - rs.AddSingular("wves", "wfe") - rs.AddSingular("xves", "xfe") - rs.AddSingular("yves", "yfe") - rs.AddSingular("zves", "zfe") - rs.AddSingular("hives", "hive") - rs.AddSingular("tives", "tive") - rs.AddSingular("lves", "lf") - rs.AddSingular("rves", "rf") - rs.AddSingular("quies", "quy") - rs.AddSingular("bies", "by") - rs.AddSingular("cies", "cy") - rs.AddSingular("dies", "dy") - rs.AddSingular("fies", "fy") - rs.AddSingular("gies", "gy") - rs.AddSingular("hies", "hy") - rs.AddSingular("jies", "jy") - rs.AddSingular("kies", "ky") - rs.AddSingular("lies", "ly") - rs.AddSingular("mies", "my") - rs.AddSingular("nies", "ny") - rs.AddSingular("pies", "py") - rs.AddSingular("qies", "qy") - rs.AddSingular("ries", "ry") - rs.AddSingular("sies", "sy") - rs.AddSingular("ties", "ty") - rs.AddSingular("vies", "vy") - rs.AddSingular("wies", "wy") - rs.AddSingular("xies", "xy") - rs.AddSingular("zies", "zy") - rs.AddSingular("series", "series") - rs.AddSingular("movies", "movie") - rs.AddSingular("xes", "x") - rs.AddSingular("ches", "ch") - rs.AddSingular("sses", "ss") - rs.AddSingular("shes", "sh") - rs.AddSingular("mice", "mouse") - rs.AddSingular("lice", "louse") - rs.AddSingular("buses", "bus") - rs.AddSingular("oes", "o") - rs.AddSingular("shoes", "shoe") - rs.AddSingular("crises", "crisis") - rs.AddSingular("axes", "axis") - rs.AddSingular("testes", "testis") - rs.AddSingular("octopi", "octopus") - rs.AddSingular("viri", "virus") - rs.AddSingular("statuses", "status") - rs.AddSingular("aliases", "alias") - rs.AddSingularExact("oxen", "ox", true) - rs.AddSingular("vertices", "vertex") - rs.AddSingular("indices", "index") - rs.AddSingular("matrices", "matrix") - rs.AddSingularExact("quizzes", "quiz", true) - rs.AddSingular("databases", "database") - rs.AddSingular("menus", "menu") - rs.AddIrregular("person", "people") - rs.AddIrregular("man", "men") - rs.AddIrregular("child", "children") - rs.AddIrregular("sex", "sexes") - rs.AddIrregular("move", "moves") - rs.AddIrregular("zombie", "zombies") - rs.AddIrregular("cookie", "cookies") - rs.AddSingularExact("a", "a", true) - rs.AddSingularExact("i", "i", true) - rs.AddSingularExact("is", "is", true) - rs.AddSingularExact("us", "us", true) - rs.AddSingularExact("as", "as", true) - rs.AddSingularExact("areas", "area", true) - rs.AddPluralExact("a", "a", true) - rs.AddPluralExact("i", "i", true) - rs.AddPluralExact("is", "is", true) - rs.AddPluralExact("us", "us", true) - rs.AddPluralExact("as", "as", true) - return rs -} diff --git a/strmangle/sets.go b/strmangle/sets.go deleted file mode 100644 index db8bee1a5..000000000 --- a/strmangle/sets.go +++ /dev/null @@ -1,90 +0,0 @@ -package strmangle - -// SetInclude checks to see if the string is found in the string slice -func SetInclude(str string, slice []string) bool { - for _, s := range slice { - if str == s { - return true - } - } - - return false -} - -// SetComplement subtracts the elements in b from a -func SetComplement(a []string, b []string) []string { - c := make([]string, 0, len(a)) - - for _, aVal := range a { - found := false - for _, bVal := range b { - if aVal == bVal { - found = true - break - } - } - if !found { - c = append(c, aVal) - } - } - - return c -} - -// SetMerge will return a merged slice without duplicates -func SetMerge(a []string, b []string) []string { - merged := make([]string, 0, len(a)+len(b)) - - for _, aVal := range a { - found := false - for _, mVal := range merged { - if aVal == mVal { - found = true - break - } - } - - if !found { - merged = append(merged, aVal) - } - } - - for _, bVal := range b { - found := false - for _, mVal := range merged { - if bVal == mVal { - found = true - break - } - } - - if !found { - merged = append(merged, bVal) - } - } - - return merged -} - -// SortByKeys returns a new ordered slice based on the keys ordering -func SortByKeys(keys []string, strs []string) []string { - c := make([]string, len(strs)) - - index := 0 -Outer: - for _, v := range keys { - for _, k := range strs { - if v == k { - c[index] = v - index++ - - if index > len(strs)-1 { - break Outer - } - break - } - } - } - - return c -} diff --git a/strmangle/sets_test.go b/strmangle/sets_test.go deleted file mode 100644 index 23cd3f3dd..000000000 --- a/strmangle/sets_test.go +++ /dev/null @@ -1,132 +0,0 @@ -package strmangle - -import ( - "reflect" - "testing" -) - -func TestSetInclude(t *testing.T) { - t.Parallel() - - elements := []string{"one", "two"} - if got := SetInclude("one", elements); !got { - t.Error("should have found element key") - } - if got := SetInclude("three", elements); got { - t.Error("should not have found element key") - } -} - -func TestSetComplement(t *testing.T) { - t.Parallel() - - tests := []struct { - A []string - B []string - C []string - }{ - { - []string{"thing1", "thing2", "thing3"}, - []string{"thing2", "otherthing", "stuff"}, - []string{"thing1", "thing3"}, - }, - { - []string{}, - []string{"thing1", "thing2"}, - []string{}, - }, - { - []string{"thing1", "thing2"}, - []string{}, - []string{"thing1", "thing2"}, - }, - { - []string{"thing1", "thing2"}, - []string{"thing1", "thing2"}, - []string{}, - }, - } - - for i, test := range tests { - c := SetComplement(test.A, test.B) - if !reflect.DeepEqual(test.C, c) { - t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, c) - } - } -} - -func TestSetMerge(t *testing.T) { - t.Parallel() - - tests := []struct { - A []string - B []string - C []string - }{ - { - []string{"thing1", "thing2", "thing3"}, - []string{"thing1", "thing3", "thing4"}, - []string{"thing1", "thing2", "thing3", "thing4"}, - }, - { - []string{}, - []string{"thing1", "thing2"}, - []string{"thing1", "thing2"}, - }, - { - []string{"thing1", "thing2"}, - []string{}, - []string{"thing1", "thing2"}, - }, - { - []string{"thing1", "thing2", "thing3"}, - []string{"thing1", "thing2", "thing3"}, - []string{"thing1", "thing2", "thing3"}, - }, - { - []string{"thing1", "thing2"}, - []string{"thing3", "thing4"}, - []string{"thing1", "thing2", "thing3", "thing4"}, - }, - } - - for i, test := range tests { - m := SetMerge(test.A, test.B) - if !reflect.DeepEqual(test.C, m) { - t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.C, m) - } - } -} - -func TestSortByKeys(t *testing.T) { - t.Parallel() - - tests := []struct { - Keys []string - Strs []string - Ret []string - }{ - { - []string{"id", "name", "thing", "stuff"}, - []string{"thing", "stuff", "name", "id"}, - []string{"id", "name", "thing", "stuff"}, - }, - { - []string{"id", "name", "thing", "stuff"}, - []string{"id", "name", "thing", "stuff"}, - []string{"id", "name", "thing", "stuff"}, - }, - { - []string{"id", "name", "thing", "stuff"}, - []string{"stuff", "thing"}, - []string{"thing", "stuff"}, - }, - } - - for i, test := range tests { - z := SortByKeys(test.Keys, test.Strs) - if !reflect.DeepEqual(test.Ret, z) { - t.Errorf("[%d] mismatch:\nWant: %#v\nGot: %#v", i, test.Ret, z) - } - } -} diff --git a/strmangle/strmangle.go b/strmangle/strmangle.go deleted file mode 100644 index 164ddce27..000000000 --- a/strmangle/strmangle.go +++ /dev/null @@ -1,744 +0,0 @@ -// Package strmangle is a collection of string manipulation functions. -// Primarily used by boil and templates for code generation. -// Because it is focused on pipelining inside templates -// you will see some odd parameter ordering. -package strmangle - -import ( - "fmt" - "math" - "regexp" - "sort" - "strings" - "sync" -) - -var ( - idAlphabet = []byte("abcdefghijklmnopqrstuvwxyz") - smartQuoteRgx = regexp.MustCompile(`^(?i)"?[a-z_][_a-z0-9\-]*"?(\."?[_a-z][_a-z0-9]*"?)*(\.\*)?$`) - - rgxEnum = regexp.MustCompile(`^enum(\.[a-z0-9_]+)?\((,?'[^']+')+\)$`) - rgxEnumIsOK = regexp.MustCompile(`^(?i)[a-z][a-z0-9_\s]*$`) - rgxEnumShouldTitle = regexp.MustCompile(`^[a-z][a-z0-9_]*$`) - rgxWhitespace = regexp.MustCompile(`\s`) -) - -var uppercaseWords = map[string]struct{}{ - "acl": {}, - "api": {}, - "ascii": {}, - "cpu": {}, - "eof": {}, - "guid": {}, - "id": {}, - "ip": {}, - "json": {}, - "ram": {}, - "sla": {}, - "udp": {}, - "ui": {}, - "uid": {}, - "uuid": {}, - "uri": {}, - "url": {}, - "utf8": {}, -} - -var reservedWords = map[string]struct{}{ - "break": {}, - "case": {}, - "chan": {}, - "const": {}, - "continue": {}, - "default": {}, - "defer": {}, - "else": {}, - "fallthrough": {}, - "for": {}, - "func": {}, - "go": {}, - "goto": {}, - "if": {}, - "import": {}, - "interface": {}, - "map": {}, - "package": {}, - "range": {}, - "return": {}, - "select": {}, - "struct": {}, - "switch": {}, - "type": {}, - "var": {}, -} - -func init() { - // Our Boil inflection Ruleset does not include uncountable inflections. - // This way, people using words like Sheep will not have - // collisions with their model name (Sheep) and their - // function name (Sheep()). Instead, it will - // use the regular inflection rules: Sheep, Sheeps(). - boilRuleset = newBoilRuleset() -} - -// SchemaTable returns a table name with a schema prefixed if -// using a database that supports real schemas, for example, -// for Postgres: "schema_name"."table_name", -// for MS SQL: [schema_name].[table_name], versus -// simply "table_name" for MySQL (because it does not support real schemas) -func SchemaTable(lq, rq string, useSchema bool, schema string, table string) string { - if useSchema { - return fmt.Sprintf(`%s%s%s.%s%s%s`, lq, schema, rq, lq, table, rq) - } - - return fmt.Sprintf(`%s%s%s`, lq, table, rq) -} - -// IdentQuote attempts to quote simple identifiers in SQL statements -func IdentQuote(lq rune, rq rune, s string) string { - if strings.EqualFold(s, "null") || s == "?" { - return s - } - - if m := smartQuoteRgx.MatchString(s); m != true { - return s - } - - buf := GetBuffer() - defer PutBuffer(buf) - - splits := strings.Split(s, ".") - for i, split := range splits { - if i != 0 { - buf.WriteByte('.') - } - - if rune(split[0]) == lq || rune(split[len(split)-1]) == rq || split == "*" { - buf.WriteString(split) - continue - } - - buf.WriteRune(lq) - buf.WriteString(split) - buf.WriteRune(rq) - } - - return buf.String() -} - -// IdentQuoteSlice applies IdentQuote to a slice. -func IdentQuoteSlice(lq rune, rq rune, s []string) []string { - if len(s) == 0 { - return s - } - - strs := make([]string, len(s)) - for i, str := range s { - strs[i] = IdentQuote(lq, rq, str) - } - - return strs -} - -// Identifier is a base conversion from Base 10 integers to Base 26 -// integers that are represented by an alphabet from a-z -// See tests for example outputs. -func Identifier(in int) string { - ln := len(idAlphabet) - var n int - if in == 0 { - n = 1 - } else { - n = 1 + int(math.Log(float64(in))/math.Log(float64(ln))) - } - - cols := GetBuffer() - defer PutBuffer(cols) - - for i := 0; i < n; i++ { - divisor := int(math.Pow(float64(ln), float64(n-i-1))) - rem := in / divisor - cols.WriteByte(idAlphabet[rem]) - - in -= rem * divisor - } - - return cols.String() -} - -// QuoteCharacter returns a string that allows the quote character -// to be embedded into a Go string that uses double quotes: -func QuoteCharacter(q rune) string { - if q == '"' { - return `\"` - } - - return string(q) -} - -// Plural converts singular words to plural words (eg: person to people) -func Plural(name string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - splits := strings.Split(name, "_") - - for i := 0; i < len(splits); i++ { - if i != 0 { - buf.WriteByte('_') - } - - if i == len(splits)-1 { - buf.WriteString(boilRuleset.Pluralize(splits[len(splits)-1])) - break - } - - buf.WriteString(splits[i]) - } - - return buf.String() -} - -// Singular converts plural words to singular words (eg: people to person) -func Singular(name string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - splits := strings.Split(name, "_") - - for i := 0; i < len(splits); i++ { - if i != 0 { - buf.WriteByte('_') - } - - if i == len(splits)-1 { - buf.WriteString(boilRuleset.Singularize(splits[len(splits)-1])) - break - } - - buf.WriteString(splits[i]) - } - - return buf.String() -} - -// titleCaseCache holds the mapping of title cases. -// Example: map["MyWord"] == "my_word" -var ( - mut sync.RWMutex - titleCaseCache = map[string]string{} -) - -// TitleCase changes a snake-case variable name -// into a go styled object variable name of "ColumnName". -// titleCase also fully uppercases "ID" components of names, for example -// "column_name_id" to "ColumnNameID". -// -// Note: This method is ugly because it has been highly optimized, -// we found that it was a fairly large bottleneck when we were using regexp. -func TitleCase(n string) string { - // Attempt to fetch from cache - mut.RLock() - val, ok := titleCaseCache[n] - mut.RUnlock() - if ok { - return val - } - - ln := len(n) - name := []byte(n) - buf := GetBuffer() - - start := 0 - end := 0 - for start < ln { - // Find the start and end of the underscores to account - // for the possibility of being multiple underscores in a row. - if end < ln { - if name[start] == '_' { - start++ - end++ - continue - // Once we have found the end of the underscores, we can - // find the end of the first full word. - } else if name[end] != '_' { - end++ - continue - } - } - - word := name[start:end] - wordLen := len(word) - var vowels bool - - numStart := wordLen - for i, c := range word { - vowels = vowels || (c == 97 || c == 101 || c == 105 || c == 111 || c == 117 || c == 121) - - if c > 47 && c < 58 && numStart == wordLen { - numStart = i - } - } - - _, match := uppercaseWords[string(word[:numStart])] - - if match || !vowels { - // Uppercase all a-z characters - for _, c := range word { - if c > 96 && c < 123 { - buf.WriteByte(c - 32) - } else { - buf.WriteByte(c) - } - } - } else { - if c := word[0]; c > 96 && c < 123 { - buf.WriteByte(word[0] - 32) - buf.Write(word[1:]) - } else { - buf.Write(word) - } - } - - start = end + 1 - end = start - } - - ret := buf.String() - PutBuffer(buf) - - // Cache the title case result - mut.Lock() - titleCaseCache[n] = ret - mut.Unlock() - - return ret -} - -// Ignore sets "-" for the tags values, so the fields will be ignored during parsing -func Ignore(table, column string, ignoreList map[string]struct{}) bool { - _, ok := ignoreList[column] - if ok { - return true - } - _, ok = ignoreList[fmt.Sprintf("%s.%s", table, column)] - if ok { - return true - } - return false -} - -// CamelCase takes a variable name in the format of "var_name" and converts -// it into a go styled variable name of "varName". -// camelCase also fully uppercases "ID" components of names, for example -// "var_name_id" to "varNameID". It will also lowercase the first letter -// of the name in the case where it's fed something that starts with uppercase. -func CamelCase(name string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - // Discard all leading '_' - index := -1 - for i := 0; i < len(name); i++ { - if name[i] != '_' { - index = i - break - } - } - - if index != -1 { - name = name[index:] - } else { - return "" - } - - index = -1 - for i := 0; i < len(name); i++ { - if name[i] == '_' { - index = i - break - } - } - - if index == -1 { - buf.WriteString(strings.ToLower(string(name[0]))) - if len(name) > 1 { - buf.WriteString(name[1:]) - } - } else { - buf.WriteString(strings.ToLower(string(name[0]))) - if len(name) > 1 { - buf.WriteString(name[1:index]) - buf.WriteString(TitleCase(name[index+1:])) - } - } - - return buf.String() -} - -// TitleCaseIdentifier splits on dots and then titlecases each fragment. -// map titleCase (split c ".") -func TitleCaseIdentifier(id string) string { - nextDot := strings.IndexByte(id, '.') - if nextDot < 0 { - return TitleCase(id) - } - - buf := GetBuffer() - defer PutBuffer(buf) - lastDot := 0 - ln := len(id) - addDots := false - - for i := 0; nextDot >= 0; i++ { - fragment := id[lastDot:nextDot] - - titled := TitleCase(fragment) - - if addDots { - buf.WriteByte('.') - } - buf.WriteString(titled) - addDots = true - - if nextDot == ln { - break - } - - lastDot = nextDot + 1 - if nextDot = strings.IndexByte(id[lastDot:], '.'); nextDot >= 0 { - nextDot += lastDot - } else { - nextDot = ln - } - } - - return buf.String() -} - -// MakeStringMap converts a map[string]string into the format: -// "key": "value", "key": "value" -func MakeStringMap(types map[string]string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - keys := make([]string, 0, len(types)) - for k := range types { - keys = append(keys, k) - } - sort.Strings(keys) - - c := 0 - for _, k := range keys { - v := types[k] - buf.WriteString(fmt.Sprintf("`%s`: `%s`", k, v)) - if c < len(types)-1 { - buf.WriteString(", ") - } - - c++ - } - - return buf.String() -} - -// StringMap maps a function over a slice of strings. -func StringMap(modifier func(string) string, strs []string) []string { - ret := make([]string, len(strs)) - - for i, str := range strs { - ret[i] = modifier(str) - } - - return ret -} - -// PrefixStringSlice with the given str. -func PrefixStringSlice(str string, strs []string) []string { - ret := make([]string, len(strs)) - - for i, s := range strs { - ret[i] = fmt.Sprintf("%s%s", str, s) - } - - return ret -} - -// Placeholders generates the SQL statement placeholders for in queries. -// For example, ($1,$2,$3),($4,$5,$6) etc. -// It will start counting placeholders at "start". -// If useIndexPlaceholders is false, it will convert to ? instead of $1 etc. -func Placeholders(useIndexPlaceholders bool, count int, start int, group int) string { - buf := GetBuffer() - defer PutBuffer(buf) - - if start == 0 || group == 0 { - panic("Invalid start or group numbers supplied.") - } - - if group > 1 { - buf.WriteByte('(') - } - for i := 0; i < count; i++ { - if i != 0 { - if group > 1 && i%group == 0 { - buf.WriteString("),(") - } else { - buf.WriteByte(',') - } - } - if useIndexPlaceholders { - buf.WriteString(fmt.Sprintf("$%d", start+i)) - } else { - buf.WriteByte('?') - } - } - if group > 1 { - buf.WriteByte(')') - } - - return buf.String() -} - -// SetParamNames takes a slice of columns and returns a comma separated -// list of parameter names for a template statement SET clause. -// eg: "col1"=$1, "col2"=$2, "col3"=$3 -func SetParamNames(lq, rq string, start int, columns []string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - for i, c := range columns { - if start != 0 { - buf.WriteString(fmt.Sprintf(`%s%s%s=$%d`, lq, c, rq, i+start)) - } else { - buf.WriteString(fmt.Sprintf(`%s%s%s=?`, lq, c, rq)) - } - - if i < len(columns)-1 { - buf.WriteByte(',') - } - } - - return buf.String() -} - -// WhereClause returns the where clause using start as the $ flag index -// For example, if start was 2 output would be: "colthing=$2 AND colstuff=$3" -func WhereClause(lq, rq string, start int, cols []string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - for i, c := range cols { - if start != 0 { - buf.WriteString(fmt.Sprintf(`%s%s%s=$%d`, lq, c, rq, start+i)) - } else { - buf.WriteString(fmt.Sprintf(`%s%s%s=?`, lq, c, rq)) - } - - if i < len(cols)-1 { - buf.WriteString(" AND ") - } - } - - return buf.String() -} - -// WhereClauseRepeated returns the where clause repeated with OR clause using start as the $ flag index -// For example, if start was 2 output would be: "(colthing=$2 AND colstuff=$3) OR (colthing=$4 AND colstuff=$5)" -func WhereClauseRepeated(lq, rq string, start int, cols []string, count int) string { - var startIndex int - buf := GetBuffer() - defer PutBuffer(buf) - buf.WriteByte('(') - for i := 0; i < count; i++ { - if i != 0 { - buf.WriteString(") OR (") - } - - startIndex = 0 - if start > 0 { - startIndex = start + i*len(cols) - } - - buf.WriteString(WhereClause(lq, rq, startIndex, cols)) - } - buf.WriteByte(')') - - return buf.String() -} - -// JoinSlices merges two string slices of equal length -func JoinSlices(sep string, a, b []string) []string { - lna, lnb := len(a), len(b) - if lna != lnb { - panic("joinSlices: can only merge slices of same length") - } else if lna == 0 { - return nil - } - - ret := make([]string, len(a)) - for i, elem := range a { - ret[i] = fmt.Sprintf("%s%s%s", elem, sep, b[i]) - } - - return ret -} - -// StringSliceMatch returns true if the length of both -// slices is the same, and the elements of both slices are the same. -// The elements can be in any order. -func StringSliceMatch(a []string, b []string) bool { - if len(a) != len(b) { - return false - } - - for _, aval := range a { - found := false - for _, bval := range b { - if bval == aval { - found = true - break - } - } - if !found { - return false - } - } - - return true -} - -// ContainsAny returns true if any of the passed in strings are -// found in the passed in string slice -func ContainsAny(a []string, finds ...string) bool { - for _, s := range a { - for _, find := range finds { - if s == find { - return true - } - } - } - - return false -} - -// GenerateTags converts a slice of tag strings into tags that -// can be passed onto the end of a struct, for example: -// tags: ["xml", "db"] convert to: xml:"column_name" db:"column_name" -func GenerateTags(tags []string, columnName string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - for _, tag := range tags { - buf.WriteString(tag) - buf.WriteString(`:"`) - buf.WriteString(columnName) - buf.WriteString(`" `) - } - - return buf.String() -} - -// GenerateIgnoreTags converts a slice of tag strings into -// ignore tags that can be passed onto the end of a struct, for example: -// tags: ["xml", "db"] convert to: xml:"-" db:"-" -func GenerateIgnoreTags(tags []string) string { - buf := GetBuffer() - defer PutBuffer(buf) - - for _, tag := range tags { - buf.WriteString(tag) - buf.WriteString(`:"-" `) - } - - return buf.String() -} - -// ParseEnumVals returns the values from an enum string -// -// Postgres and MySQL drivers return different values -// psql: enum.enum_name('values'...) -// mysql: enum('values'...) -func ParseEnumVals(s string) []string { - if !rgxEnum.MatchString(s) { - return nil - } - - startIndex := strings.IndexByte(s, '(') - s = s[startIndex+2 : len(s)-2] - return strings.Split(s, "','") -} - -// ParseEnumName returns the name portion of an enum if it exists -// -// Postgres and MySQL drivers return different values -// psql: enum.enum_name('values'...) -// mysql: enum('values'...) -// In the case of mysql, the name will never return anything -func ParseEnumName(s string) string { - if !rgxEnum.MatchString(s) { - return "" - } - - endIndex := strings.IndexByte(s, '(') - s = s[:endIndex] - startIndex := strings.IndexByte(s, '.') - if startIndex < 0 { - return "" - } - - return s[startIndex+1:] -} - -// IsEnumNormal checks a set of eval values to see if they're "normal" -func IsEnumNormal(values []string) bool { - for _, v := range values { - if !rgxEnumIsOK.MatchString(v) { - return false - } - } - - return true -} - -//StripWhitespace removes all whitespace from a string -func StripWhitespace(value string) string { - return rgxWhitespace.ReplaceAllString(value, "") -} - -// ShouldTitleCaseEnum checks a value to see if it's title-case-able -func ShouldTitleCaseEnum(value string) bool { - return rgxEnumShouldTitle.MatchString(value) -} - -// ReplaceReservedWords takes a word and replaces it with word_ if it's found -// in the list of reserved words. -func ReplaceReservedWords(word string) string { - if _, ok := reservedWords[word]; ok { - return word + "_" - } - return word -} - -// RemoveDuplicates from a string slice -func RemoveDuplicates(dedup []string) []string { - if len(dedup) <= 1 { - return dedup - } - - for i := 0; i < len(dedup)-1; i++ { - for j := i + 1; j < len(dedup); j++ { - if dedup[i] != dedup[j] { - continue - } - - if j != len(dedup)-1 { - dedup[j] = dedup[len(dedup)-1] - j-- - } - dedup = dedup[:len(dedup)-1] - } - } - - return dedup -} diff --git a/strmangle/strmangle_test.go b/strmangle/strmangle_test.go deleted file mode 100644 index b575b2341..000000000 --- a/strmangle/strmangle_test.go +++ /dev/null @@ -1,683 +0,0 @@ -package strmangle - -import ( - "strings" - "testing" - - "github.com/friendsofgo/errors" -) - -func TestIdentQuote(t *testing.T) { - t.Parallel() - - tests := []struct { - In string - Out string - }{ - {In: `thing`, Out: `"thing"`}, - {In: `null`, Out: `null`}, - {In: `"thing"`, Out: `"thing"`}, - {In: `*`, Out: `*`}, - {In: ``, Out: ``}, - {In: `thing.thing`, Out: `"thing"."thing"`}, - {In: `"thing"."thing"`, Out: `"thing"."thing"`}, - {In: `thing.thing.thing.thing`, Out: `"thing"."thing"."thing"."thing"`}, - {In: `thing."thing".thing."thing"`, Out: `"thing"."thing"."thing"."thing"`}, - {In: `count(*) as ab, thing as bd`, Out: `count(*) as ab, thing as bd`}, - {In: `hello.*`, Out: `"hello".*`}, - {In: `hello.there.*`, Out: `"hello"."there".*`}, - {In: `"hello".there.*`, Out: `"hello"."there".*`}, - {In: `hello."there".*`, Out: `"hello"."there".*`}, - {In: `go-backend.tokens`, Out: `"go-backend"."tokens"`}, - } - - for _, test := range tests { - if got := IdentQuote('"', '"', test.In); got != test.Out { - t.Errorf("want: %s, got: %s", test.Out, got) - } - } -} - -func TestIdentQuoteSlice(t *testing.T) { - t.Parallel() - - ret := IdentQuoteSlice('"', '"', []string{`thing`, `null`}) - if ret[0] != `"thing"` { - t.Error(ret[0]) - } - if ret[1] != `null` { - t.Error(ret[1]) - } -} - -func TestIdentifier(t *testing.T) { - t.Parallel() - - tests := []struct { - In int - Out string - }{ - {In: 0, Out: "a"}, - {In: 25, Out: "z"}, - {In: 26, Out: "ba"}, - {In: 52, Out: "ca"}, - {In: 675, Out: "zz"}, - {In: 676, Out: "baa"}, - } - - for _, test := range tests { - if got := Identifier(test.In); got != test.Out { - t.Errorf("[%d] want: %q, got: %q", test.In, test.Out, got) - } - } -} - -func TestQuoteCharacter(t *testing.T) { - t.Parallel() - - if QuoteCharacter('[') != "[" { - t.Error("want just the normal quote character") - } - if QuoteCharacter('`') != "`" { - t.Error("want just the normal quote character") - } - if QuoteCharacter('"') != `\"` { - t.Error("want an escaped character") - } -} - -func TestPlaceholders(t *testing.T) { - t.Parallel() - - x := Placeholders(true, 1, 2, 1) - want := "$2" - if want != x { - t.Errorf("want %s, got %s", want, x) - } - - x = Placeholders(true, 5, 1, 1) - want = "$1,$2,$3,$4,$5" - if want != x { - t.Errorf("want %s, got %s", want, x) - } - - x = Placeholders(false, 5, 1, 1) - want = "?,?,?,?,?" - if want != x { - t.Errorf("want %s, got %s", want, x) - } - - x = Placeholders(true, 6, 1, 2) - want = "($1,$2),($3,$4),($5,$6)" - if want != x { - t.Errorf("want %s, got %s", want, x) - } - - x = Placeholders(true, 6, 1, 2) - want = "($1,$2),($3,$4),($5,$6)" - if want != x { - t.Errorf("want %s, got %s", want, x) - } - - x = Placeholders(false, 9, 1, 3) - want = "(?,?,?),(?,?,?),(?,?,?)" - if want != x { - t.Errorf("want %s, got %s", want, x) - } - - x = Placeholders(true, 7, 1, 3) - want = "($1,$2,$3),($4,$5,$6),($7)" - if want != x { - t.Errorf("want %s, got %s", want, x) - } -} - -func TestSingular(t *testing.T) { - t.Parallel() - - tests := []struct { - In string - Out string - }{ - {"hello_people", "hello_person"}, - {"hello_person", "hello_person"}, - {"friends", "friend"}, - {"areas", "area"}, - {"hello_there_people", "hello_there_person"}, - {"schemas", "schema"}, - } - - for i, test := range tests { - if out := Singular(test.In); out != test.Out { - t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out) - } - } -} - -func TestPlural(t *testing.T) { - t.Parallel() - - tests := []struct { - In string - Out string - }{ - {"hello_person", "hello_people"}, - {"friend", "friends"}, - {"friends", "friends"}, - {"area", "areas"}, - {"hello_there_person", "hello_there_people"}, - {"schema", "schemas"}, - } - - for i, test := range tests { - if out := Plural(test.In); out != test.Out { - t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out) - } - } -} - -func TestTitleCase(t *testing.T) { - t.Parallel() - - tests := []struct { - In string - Out string - }{ - {"hello_there", "HelloThere"}, - {"", ""}, - {"____a____a___", "AA"}, - {"_a_a_", "AA"}, - {"fun_id", "FunID"}, - {"_fun_id", "FunID"}, - {"__fun____id_", "FunID"}, - {"uid", "UID"}, - {"guid", "GUID"}, - {"uid", "UID"}, - {"uuid", "UUID"}, - {"ssn", "SSN"}, - {"tz", "TZ"}, - {"thing_guid", "ThingGUID"}, - {"guid_thing", "GUIDThing"}, - {"thing_guid_thing", "ThingGUIDThing"}, - {"id", "ID"}, - {"gvzxc", "GVZXC"}, - {"id_trgb_id", "IDTRGBID"}, - {"vzxx_vxccb_nmx", "VZXXVXCCBNMX"}, - {"thing_zxc_stuff_vxz", "ThingZXCStuffVXZ"}, - {"zxc_thing_vxz_stuff", "ZXCThingVXZStuff"}, - {"zxc_vdf9c9_hello9", "ZXCVDF9C9Hello9"}, - {"id9_uid911_guid9e9", "ID9UID911GUID9E9"}, - {"zxc_vdf0c0_hello0", "ZXCVDF0C0Hello0"}, - {"id0_uid000_guid0e0", "ID0UID000GUID0E0"}, - {"ab_5zxc5d5", "Ab5ZXC5D5"}, - {"Identifier", "Identifier"}, - } - - for i, test := range tests { - if out := TitleCase(test.In); out != test.Out { - t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out) - } - } -} - -func TestCamelCase(t *testing.T) { - t.Parallel() - - tests := []struct { - In string - Out string - }{ - {"hello_there_sunny", "helloThereSunny"}, - {"", ""}, - {"a_", "a"}, - {"aaa_", "aaa"}, - {"a___", "a"}, - {"aaa___", "aaa"}, - {"_a_", "a"}, - {"_aaa_", "aaa"}, - {"____a___", "a"}, - {"___aaa____", "aaa"}, - {"___a", "a"}, - {"___aa", "aa"}, - {"____a____a___", "aA"}, - {"_a_a_", "aA"}, - {"_fun_id", "funID"}, - {"__fun____id_", "funID"}, - {"fun_id_times", "funIDTimes"}, - {"uid", "uid"}, - {"guid", "guid"}, - {"uid", "uid"}, - {"uuid", "uuid"}, - {"ssn", "ssn"}, - {"tz", "tz"}, - {"thing_guid", "thingGUID"}, - {"guid_thing", "guidThing"}, - {"thing_guid_thing", "thingGUIDThing"}, - {"Some_upperCase___thing", "someUpperCaseThing"}, - {"A", "a"}, - {"A_a", "aA"}, - } - - for i, test := range tests { - if out := CamelCase(test.In); out != test.Out { - t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out) - } - } -} - -func TestTitleCaseIdentifier(t *testing.T) { - t.Parallel() - - tests := []struct { - In string - Out string - }{ - {"hello", "Hello"}, - {"hello.world", "Hello.World"}, - {"hey.id.world", "Hey.ID.World"}, - } - - for i, test := range tests { - if out := TitleCaseIdentifier(test.In); out != test.Out { - t.Errorf("[%d] (%s) Out was wrong: %q, want: %q", i, test.In, out, test.Out) - } - } -} - -func TestMakeStringMap(t *testing.T) { - t.Parallel() - - var m map[string]string - r := MakeStringMap(m) - - if r != "" { - t.Errorf("Expected empty result, got: %s", r) - } - - m = map[string]string{ - "TestOne": "interval", - "TestTwo": "integer", - } - - r = MakeStringMap(m) - - e1 := "`TestOne`: `interval`, `TestTwo`: `integer`" - e2 := "`TestTwo`: `integer`, `TestOne`: `interval`" - - if r != e1 && r != e2 { - t.Errorf("Got %s", r) - } -} - -func TestStringMap(t *testing.T) { - t.Parallel() - - mapped := StringMap(strings.ToLower, []string{"HELLO", "WORLD"}) - if got := strings.Join(mapped, " "); got != "hello world" { - t.Errorf("mapped was wrong: %q", got) - } -} - -func TestPrefixStringSlice(t *testing.T) { - t.Parallel() - - slice := PrefixStringSlice("o.", []string{"one", "two"}) - if got := strings.Join(slice, " "); got != "o.one o.two" { - t.Error("wrong output:", got) - } -} - -func TestSetParamNames(t *testing.T) { - t.Parallel() - - tests := []struct { - Cols []string - Start int - Should string - }{ - {Cols: []string{"col1", "col2"}, Start: 0, Should: `"col1"=?,"col2"=?`}, - {Cols: []string{"col1"}, Start: 2, Should: `"col1"=$2`}, - {Cols: []string{"col1", "col2"}, Start: 4, Should: `"col1"=$4,"col2"=$5`}, - {Cols: []string{"col1", "col2", "col3"}, Start: 4, Should: `"col1"=$4,"col2"=$5,"col3"=$6`}, - } - - for i, test := range tests { - r := SetParamNames(`"`, `"`, test.Start, test.Cols) - if r != test.Should { - t.Errorf("(%d) want: %s, got: %s\nTest: %#v", i, test.Should, r, test) - } - } -} - -func TestWhereClause(t *testing.T) { - t.Parallel() - - tests := []struct { - Cols []string - Start int - Should string - }{ - {Cols: []string{"col1", "col2"}, Start: 0, Should: `"col1"=? AND "col2"=?`}, - {Cols: []string{"col1"}, Start: 2, Should: `"col1"=$2`}, - {Cols: []string{"col1", "col2"}, Start: 4, Should: `"col1"=$4 AND "col2"=$5`}, - {Cols: []string{"col1", "col2", "col3"}, Start: 4, Should: `"col1"=$4 AND "col2"=$5 AND "col3"=$6`}, - } - - for i, test := range tests { - r := WhereClause(`"`, `"`, test.Start, test.Cols) - if r != test.Should { - t.Errorf("(%d) want: %s, got: %s\nTest: %#v", i, test.Should, r, test) - } - } -} - -func TestJoinSlices(t *testing.T) { - t.Parallel() - - ret := JoinSlices("", nil, nil) - if ret != nil { - t.Error("want nil, got:", ret) - } - - ret = JoinSlices(" ", []string{"one", "two"}, []string{"three", "four"}) - if got := ret[0]; got != "one three" { - t.Error("ret element was wrong:", got) - } - if got := ret[1]; got != "two four" { - t.Error("ret element was wrong:", got) - } -} - -func TestJoinSlicesFail(t *testing.T) { - t.Parallel() - - defer func() { - if recover() == nil { - t.Error("did not panic") - } - }() - - JoinSlices("", nil, []string{"hello"}) -} - -func TestStringSliceMatch(t *testing.T) { - t.Parallel() - - tests := []struct { - a []string - b []string - expect bool - }{ - { - a: []string{}, - b: []string{}, - expect: true, - }, - { - a: []string{"a"}, - b: []string{}, - expect: false, - }, - { - a: []string{"a"}, - b: []string{"a"}, - expect: true, - }, - { - a: []string{}, - b: []string{"b"}, - expect: false, - }, - { - a: []string{"c", "d"}, - b: []string{"b", "d"}, - expect: false, - }, - { - a: []string{"b", "d"}, - b: []string{"c", "d"}, - expect: false, - }, - { - a: []string{"a", "b", "c"}, - b: []string{"c", "b", "a"}, - expect: true, - }, - { - a: []string{"a", "b", "c"}, - b: []string{"a", "b", "c"}, - expect: true, - }, - } - - for i, test := range tests { - if StringSliceMatch(test.a, test.b) != test.expect { - t.Errorf("%d) Expected match to return %v, but got %v", i, test.expect, !test.expect) - } - } -} - -func TestContainsAny(t *testing.T) { - t.Parallel() - - a := []string{"hello", "friend"} - if ContainsAny([]string{}, "x") { - t.Errorf("Should not contain x") - } - - if ContainsAny(a, "x") { - t.Errorf("Should not contain x") - } - - if !ContainsAny(a, "hello") { - t.Errorf("Should contain hello") - } - - if !ContainsAny(a, "friend") { - t.Errorf("Should contain friend") - } - - if !ContainsAny(a, "hello", "friend") { - t.Errorf("Should contain hello and friend") - } - - if ContainsAny(a) { - t.Errorf("Should not return true") - } -} - -func TestGenerateTags(t *testing.T) { - tags := GenerateTags([]string{}, "col_name") - if tags != "" { - t.Errorf("Expected empty string, got %s", tags) - } - - tags = GenerateTags([]string{"xml"}, "col_name") - exp := `xml:"col_name" ` - if tags != exp { - t.Errorf("expected %s, got %s", exp, tags) - } - - tags = GenerateTags([]string{"xml", "db"}, "col_name") - exp = `xml:"col_name" db:"col_name" ` - if tags != exp { - t.Errorf("expected %s, got %s", exp, tags) - } -} - -func TestGenerateIgnoreTags(t *testing.T) { - tags := GenerateIgnoreTags([]string{}) - if tags != "" { - t.Errorf("Expected empty string, got %s", tags) - } - - tags = GenerateIgnoreTags([]string{"xml"}) - exp := `xml:"-" ` - if tags != exp { - t.Errorf("expected %s, got %s", exp, tags) - } - - tags = GenerateIgnoreTags([]string{"xml", "db"}) - exp = `xml:"-" db:"-" ` - if tags != exp { - t.Errorf("expected %s, got %s", exp, tags) - } -} - -func TestParseEnum(t *testing.T) { - t.Parallel() - - tests := []struct { - Enum string - Name string - Vals []string - }{ - {"enum('one')", "", []string{"one"}}, - {"enum('one','two')", "", []string{"one", "two"}}, - {"enum.working('one')", "working", []string{"one"}}, - {"enum.wor_king('one','two')", "wor_king", []string{"one", "two"}}, - {"enum('with space','two')", "", []string{"with space", "two"}}, - } - - for i, test := range tests { - name := ParseEnumName(test.Enum) - vals := ParseEnumVals(test.Enum) - if name != test.Name { - t.Errorf("%d) name was wrong, want: %s got: %s (%s)", i, test.Name, name, test.Enum) - } - for j, v := range test.Vals { - if v != vals[j] { - t.Errorf("%d.%d) value was wrong, want: %s got: %s (%s)", i, j, v, vals[j], test.Enum) - } - } - } -} - -func TestIsEnumNormal(t *testing.T) { - t.Parallel() - - tests := []struct { - Vals []string - Ok bool - }{ - {[]string{"o1ne", "two2"}, true}, - {[]string{"one", "t#wo2"}, false}, - {[]string{"1one", "two2"}, false}, - {[]string{"with space", "two"}, true}, - } - - for i, test := range tests { - if got := IsEnumNormal(test.Vals); got != test.Ok { - t.Errorf("%d) want: %t got: %t, %#v", i, test.Ok, got, test.Vals) - } - } -} - -func TestShouldTitleCaseEnum(t *testing.T) { - t.Parallel() - - tests := []struct { - Val string - Ok bool - }{ - {"hello_there0", true}, - {"hEllo", false}, - {"_hello", false}, - {"0hello", false}, - } - - for i, test := range tests { - if got := ShouldTitleCaseEnum(test.Val); got != test.Ok { - t.Errorf("%d) want: %t got: %t, %v", i, test.Ok, got, test.Val) - } - } -} - -func TestReplaceReservedWords(t *testing.T) { - tests := []struct { - Word string - Replace bool - }{ - {"break", true}, - {"id", false}, - {"type", true}, - } - - for i, test := range tests { - got := ReplaceReservedWords(test.Word) - if test.Replace && !strings.HasSuffix(got, "_") { - t.Errorf("%d) want suffixed (%s), got: %s", i, test.Word, got) - } else if !test.Replace && strings.HasSuffix(got, "_") { - t.Errorf("%d) want normal (%s), got: %s", i, test.Word, got) - } - } -} - -func TestRemoveDuplicates(t *testing.T) { - t.Parallel() - - hasDups := func(possible []string) error { - for i := 0; i < len(possible)-1; i++ { - for j := i + 1; j < len(possible); j++ { - if possible[i] == possible[j] { - return errors.Errorf("found duplicate: %s [%d] [%d]", possible[i], i, j) - } - } - } - - return nil - } - - if len(RemoveDuplicates([]string{})) != 0 { - t.Error("It should have returned an empty slice") - } - - oneItem := []string{"patrick"} - slice := RemoveDuplicates(oneItem) - if ln := len(slice); ln != 1 { - t.Error("Length was wrong:", ln) - } else if oneItem[0] != slice[0] { - t.Errorf("Slices differ: %#v %#v", oneItem, slice) - } - - slice = RemoveDuplicates([]string{"hello", "patrick", "hello"}) - if ln := len(slice); ln != 2 { - t.Error("Length was wrong:", ln) - } - if err := hasDups(slice); err != nil { - t.Error(err) - } - - slice = RemoveDuplicates([]string{"five", "patrick", "hello", "hello", "patrick", "hello", "hello"}) - if ln := len(slice); ln != 3 { - t.Error("Length was wrong:", ln) - } - if err := hasDups(slice); err != nil { - t.Error(err) - } -} - -func TestIgnore(t *testing.T) { - t.Parallel() - type args struct { - table string - column string - ignoreList map[string]struct{} - } - tests := []struct { - name string - args args - want bool - }{ - {name: "ignore column", args: args{column: "b", ignoreList: map[string]struct{}{"b": {}}}, want: true}, - {name: "ignore table.column", args: args{column: "a.b", ignoreList: map[string]struct{}{"a.b": {}}}, want: true}, - {name: "don't ignore", args: args{column: "a.b", ignoreList: map[string]struct{}{"a.c": {}}}, want: false}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := Ignore(tt.args.table, tt.args.column, tt.args.ignoreList); got != tt.want { - t.Errorf("Ignore() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/types/array.go b/types/array.go index 0dedcdcb3..f7f3ecff1 100644 --- a/types/array.go +++ b/types/array.go @@ -35,7 +35,7 @@ import ( "github.com/ericlagergren/decimal" "github.com/lib/pq/oid" - "github.com/volatiletech/sqlboiler/randomize" + "github.com/volatiletech/randomize" ) type parameterStatus struct { diff --git a/types/decimal_test.go b/types/decimal_test.go index ede2ad546..9a01735f6 100644 --- a/types/decimal_test.go +++ b/types/decimal_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/ericlagergren/decimal" - "github.com/volatiletech/sqlboiler/queries/qmhelper" + "github.com/volatiletech/sqlboiler/v4/queries/qmhelper" ) func TestDecimal_Value(t *testing.T) { diff --git a/types/hstore.go b/types/hstore.go index 53eb6370a..708698222 100644 --- a/types/hstore.go +++ b/types/hstore.go @@ -24,8 +24,8 @@ import ( "database/sql/driver" "strings" - "github.com/volatiletech/null" - "github.com/volatiletech/sqlboiler/randomize" + "github.com/volatiletech/null/v8" + "github.com/volatiletech/randomize" ) // HStore is a wrapper for transferring HStore values back and forth easily. diff --git a/types/json.go b/types/json.go index aefd03c2c..611d17a0e 100644 --- a/types/json.go +++ b/types/json.go @@ -5,7 +5,7 @@ import ( "encoding/json" "errors" - "github.com/volatiletech/sqlboiler/randomize" + "github.com/volatiletech/randomize" ) // JSON is an alias for json.RawMessage, which is