diff --git a/app/app.cue b/app/app.cue
index 517cc4510..eb5b56ef4 100644
--- a/app/app.cue
+++ b/app/app.cue
@@ -10,7 +10,7 @@ import (
)
corteza: schema.#platform & {
- handle: "corteza"
+ "ident": "corteza"
"options": [
options.DB,
@@ -44,7 +44,10 @@ corteza: schema.#platform & {
options.discovery,
]
- components: [
+ // platform resources
+ "resources": resources
+
+ "components": [
system.component,
compose.component,
automation.component,
diff --git a/app/boot_levels.go b/app/boot_levels.go
index 2a52bc845..76766aa28 100644
--- a/app/boot_levels.go
+++ b/app/boot_levels.go
@@ -208,7 +208,7 @@ func (app *CortezaApp) InitStore(ctx context.Context) (err error) {
// @todo refactor this to make more sense and put it where it belongs
{
var set types.SettingValueSet
- set, _, err = store.SearchSettings(ctx, app.Store, types.SettingsFilter{Prefix: "auth.external"})
+ set, _, err = store.SearchSettingValues(ctx, app.Store, types.SettingsFilter{Prefix: "auth.external"})
if err != nil {
return err
}
@@ -216,7 +216,7 @@ func (app *CortezaApp) InitStore(ctx context.Context) (err error) {
err = set.Walk(func(old *types.SettingValue) error {
if strings.HasSuffix(old.Name, ".redirect-url") {
// remove obsolete redirect-url
- if err = store.DeleteSetting(ctx, app.Store, old); err != nil {
+ if err = store.DeleteSettingValue(ctx, app.Store, old); err != nil {
return err
}
@@ -229,13 +229,13 @@ func (app *CortezaApp) InitStore(ctx context.Context) (err error) {
log.Info("renaming settings", zap.String("old", old.Name), zap.String("new", new.Name))
- if err = store.CreateSetting(ctx, app.Store, &new); err != nil {
+ if err = store.CreateSettingValue(ctx, app.Store, &new); err != nil {
if store.ErrNotUnique != err {
return err
}
}
- if err = store.DeleteSetting(ctx, app.Store, old); err != nil {
+ if err = store.DeleteSettingValue(ctx, app.Store, old); err != nil {
return err
}
}
diff --git a/app/options/DB.cue b/app/options/DB.cue
index cc2d43af1..3e33a0954 100644
--- a/app/options/DB.cue
+++ b/app/options/DB.cue
@@ -5,7 +5,8 @@ import (
)
DB: schema.#optionsGroup & {
- handle: "DB"
+ handle: "db"
+ expIdent: "DB"
options: {
DSN: {
defaultValue: "sqlite3://file::memory:?cache=shared&mode=memory"
diff --git a/app/options/actionLog.cue b/app/options/actionLog.cue
index c3e8bedef..8784387e7 100644
--- a/app/options/actionLog.cue
+++ b/app/options/actionLog.cue
@@ -5,7 +5,8 @@ import (
)
actionLog: schema.#optionsGroup & {
- handle: "actionLog"
+ handle: "action-log"
+ env: "ACTIONLOG"
options: {
enabled: {
type: "bool"
diff --git a/app/options/discovery.cue b/app/options/discovery.cue
index 77a4c3c79..8c34bd802 100644
--- a/app/options/discovery.cue
+++ b/app/options/discovery.cue
@@ -11,20 +11,20 @@ discovery: schema.#optionsGroup & {
type: "bool"
defaultGoExpr: "false"
description: "Enable discovery endpoints"
- },
+ }
debug: {
type: "bool"
defaultGoExpr: "false"
description: "Enable discovery related activity info"
- },
+ }
corteza_domain: {
- type: "string"
- description: "Indicates host of corteza compose webapp"
- },
- base_url: {
- type: "string"
- description: "Indicates host of corteza discovery server"
- },
+ type: "string"
+ description: "Indicates host of corteza compose webapp"
+ }
+ base_url: {
+ type: "string"
+ description: "Indicates host of corteza discovery server"
+ }
}
title: "Discovery"
diff --git a/app/options/waitFor.cue b/app/options/waitFor.cue
index 0737c8520..c63b8e245 100644
--- a/app/options/waitFor.cue
+++ b/app/options/waitFor.cue
@@ -5,7 +5,7 @@ import (
)
waitFor: schema.#optionsGroup & {
- handle: "waitFor"
+ handle: "wait-for"
imports: [
"\"time\"",
diff --git a/app/resources.cue b/app/resources.cue
new file mode 100644
index 000000000..449aba012
--- /dev/null
+++ b/app/resources.cue
@@ -0,0 +1,251 @@
+package app
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+_allFeaturesDisabled: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+}
+
+resources: {
+ "rbac-rule": schema.#PkgResource & {
+ package: {
+ ident: "rbac"
+ import: "github.com/cortezaproject/corteza-server/pkg/rbac"
+ }
+
+ ident: "rule"
+ identPlural: "rules"
+ expIdent: "Rule"
+
+ features: _allFeaturesDisabled
+
+ struct: {
+ role_id: { primaryKey: true, goType: "uint64", ident: "roleID", storeIdent: "rel_role" }
+ resource: { primaryKey: true }
+ operation: { primaryKey: true }
+ access: { goType: "types.Access" }
+ }
+
+ store: {
+ ident: "rbacRule"
+
+ settings: {
+ rdbms: {
+ table: "rbac_rules"
+ }
+ }
+
+ api: {
+ functions: [
+ {
+ expIdent: "TransferRbacRules"
+ args: [
+ {ident: "src", goType: "uint64"},
+ {ident: "dst", goType: "uint64"},
+ ]
+ return: []
+ },
+ ]
+ }
+ }
+ }
+
+ "label": schema.#PkgResource & {
+ package: {
+ ident: "labels"
+ import: "github.com/cortezaproject/corteza-server/pkg/label/types"
+ }
+
+ ident: "label"
+ identPlural: "labels"
+ expIdent: "Label"
+
+ features: _allFeaturesDisabled
+
+ struct: {
+ kind: { primaryKey: true }
+ resource_id: { primaryKey: true, goType: "uint64", ident: "resourceID", storeIdent: "rel_resource" }
+ name: { primaryKey: true, ignoreCase: true }
+ value: {}
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["kind", "resource_id", "name"]
+ description: """
+ searches for label by kind, resource ID and name
+ """
+ },
+ ]
+
+ functions: [
+ {
+ expIdent: "DeleteExtraLabels"
+ args: [
+ {ident: "kind", goType: "string"},
+ {ident: "resourceId", goType: "uint64"},
+ {ident: "name", goType: "string", spread: true},
+ ]
+ return: []
+ },
+ ]
+ }
+ }
+ }
+
+ "flag": schema.#PkgResource & {
+ package: {
+ ident: "flag"
+ import: "github.com/cortezaproject/corteza-server/pkg/flag/types"
+ }
+
+ ident: "flag"
+ identPlural: "flags"
+ expIdent: "Flag"
+
+ features: _allFeaturesDisabled
+
+ struct: {
+ kind: { primaryKey: true }
+ resource_id: { primaryKey: true, goType: "uint64", ident: "resourceID", storeIdent: "rel_resource" }
+ owned_by: { primaryKey: true, goType: "uint64" }
+ name: { primaryKey: true, ignoreCase: true }
+ active: { goType: "bool"}
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["kind", "resource_id", "owned_by", "name"]
+ description: """
+ searches for flag by kind, resource ID, owner and name
+ """
+ },
+ ]
+ }
+ }
+ }
+
+ "actionlog": schema.#PkgResource & {
+ package: {
+ ident: "actionlog"
+ import: "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ }
+
+ ident: "action"
+ identPlural: "action"
+ expIdent: "Action"
+
+ features: {
+ labels: false
+ paging: false
+ checkFn: false
+ }
+
+ struct: {
+ id: schema.IdField
+ timestamp: schema.SortableTimestampField & { storeIdent: "ts" }
+ request_origin: {}
+ request_id: { ident: "requestID" }
+ actor_ip_addr: { ident: "actorIPAddr"}
+ actor_id: { goType: "uint64", ident: "actorID" }
+ resource: {}
+ action: {}
+ error: {}
+ severity: { goType: "types.Severity" }
+ description: {}
+ meta: { goType: "types.Meta" }
+ }
+
+ filter: {
+ expIdent: "Filter"
+ struct: {
+ from_timestamp: { goType: "*time.Time" }
+ to_timestamp: { goType: "*time.Time" }
+ before_action_id: { goType: "uint64", ident: "beforeActionID" }
+ actor_id: { goType: "[]uint64", ident: "actorID" }
+ origin: {}
+ resource: {}
+ action: {}
+ limit: { goType: "uint" }
+ }
+
+ byValue: ["action", "resource", "origin", "actor_id" ]
+ }
+
+ store: {
+ ident: "actionlog"
+
+ settings: {
+ rdbms: {
+ table: "actionlog"
+
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for action log by ID
+ """
+ },
+ ]
+ }
+ }
+ }
+
+ "resource-activity": schema.#PkgResource & {
+ package: {
+ ident: "discovery"
+ import: "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ }
+
+ ident: "resourceActivity"
+ identPlural: "resourceActivities"
+ expIdent: "ResourceActivity"
+ expIdentPlural: "ResourceActivities"
+
+ features: _allFeaturesDisabled
+
+ struct: {
+ id: schema.IdField
+ timestamp: schema.SortableTimestampField & { storeIdent: "ts" }
+ resource_type: {}
+ resource_action: {}
+ resource_id: { goType: "uint64", ident: "resourceID", storeIdent: "rel_resource" }
+ meta: { goType: "rawJson" }
+ }
+
+ filter: {
+ expIdent: "ResourceActivityFilter"
+ struct: {
+ from_timestamp: { goType: "*time.Time" }
+ to_timestamp: { goType: "*time.Time" }
+ }
+ }
+
+ store: {
+ ident: "resourceActivity"
+
+ settings: {
+ rdbms: {
+ table: "resource_activity_log"
+ }
+ }
+
+ api: {
+ lookups: []
+ }
+ }
+ }
+}
diff --git a/app/store.go b/app/store.go
index 333db199f..ef8488643 100644
--- a/app/store.go
+++ b/app/store.go
@@ -2,7 +2,7 @@ package app
// Registers all supported store backends
import (
- _ "github.com/cortezaproject/corteza-server/store/mysql"
- _ "github.com/cortezaproject/corteza-server/store/postgres"
- _ "github.com/cortezaproject/corteza-server/store/sqlite3"
+ _ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/mysql"
+ _ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/postgres"
+ _ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
)
diff --git a/auth/external/register.go b/auth/external/register.go
index 5be9c1ff5..0ba92ad70 100644
--- a/auth/external/register.go
+++ b/auth/external/register.go
@@ -16,7 +16,7 @@ import (
"go.uber.org/zap"
)
-func AddProvider(ctx context.Context, log *zap.Logger, s store.Settings, eap *types.ExternalAuthProvider, force bool) error {
+func AddProvider(ctx context.Context, log *zap.Logger, s store.SettingValues, eap *types.ExternalAuthProvider, force bool) error {
var (
prefix = "auth.external.providers." + eap.Key + "."
)
@@ -33,7 +33,7 @@ func AddProvider(ctx context.Context, log *zap.Logger, s store.Settings, eap *ty
log.Info("adding external authentication provider")
- ss, _, err := store.SearchSettings(ctx, s, types.SettingsFilter{
+ ss, _, err := store.SearchSettingValues(ctx, s, types.SettingsFilter{
Prefix: prefix,
})
@@ -52,7 +52,7 @@ func AddProvider(ctx context.Context, log *zap.Logger, s store.Settings, eap *ty
if vv, err := eap.EncodeKV(); err != nil {
return fmt.Errorf("could not encode auth provider values: %w", err)
return err
- } else if err = store.UpsertSetting(ctx, s, vv...); err != nil {
+ } else if err = store.UpsertSettingValue(ctx, s, vv...); err != nil {
return fmt.Errorf("could not store auth provider values: %w", err)
}
@@ -102,11 +102,11 @@ func DiscoverOidcProvider(ctx context.Context, log *zap.Logger, opt options.Auth
return
}
-func RegisterOidcProvider(ctx context.Context, log *zap.Logger, s store.Settings, opt options.AuthOpt, name, providerUrl string, force, validate, enable bool) (eap *types.ExternalAuthProvider, err error) {
+func RegisterOidcProvider(ctx context.Context, log *zap.Logger, s store.SettingValues, opt options.AuthOpt, name, providerUrl string, force, validate, enable bool) (eap *types.ExternalAuthProvider, err error) {
if !force {
prefix := "auth.external.providers." + eap.Key + "."
- vv, _, err := store.SearchSettings(ctx, s, types.SettingsFilter{
+ vv, _, err := store.SearchSettingValues(ctx, s, types.SettingsFilter{
Prefix: prefix,
})
@@ -168,7 +168,7 @@ func RegisterOidcProvider(ctx context.Context, log *zap.Logger, s store.Settings
vv = append(vv, v)
}
- err = store.UpsertSetting(ctx, s, vv...)
+ err = store.UpsertSettingValue(ctx, s, vv...)
if err != nil {
return
}
diff --git a/automation/component.cue b/automation/component.cue
index 828bd07e3..9e71839f5 100644
--- a/automation/component.cue
+++ b/automation/component.cue
@@ -9,6 +9,8 @@ component: schema.#component & {
resources: {
"workflow": workflow
+ "session": session
+ "trigger": trigger
}
rbac: operations: {
diff --git a/automation/session.cue b/automation/session.cue
new file mode 100644
index 000000000..348842358
--- /dev/null
+++ b/automation/session.cue
@@ -0,0 +1,67 @@
+package automation
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+session: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ workflow_id: { ident: "workflowID", goType: "uint64", storeIdent: "rel_workflow" }
+ event_type: { goType: "string" }
+ resource_type: { goType: "string" }
+ status: { goType: "types.SessionStatus" }
+ input: { goType: "*expr.Vars" }
+ output: { goType: "*expr.Vars" }
+ stacktrace: { goType: "types.Stacktrace" }
+
+ created_by: { goType: "uint64" }
+ created_at: schema.SortableTimestampField
+ purge_at: schema.SortableTimestampNilField
+ completed_at: schema.SortableTimestampNilField
+ suspended_at: schema.SortableTimestampNilField
+ error: {}
+ }
+
+ filter: {
+ struct: {
+ session_id: { goType: "[]uint64", storeIdent: "id", ident: "sessionID" }
+ completed: { schema.SortableTimestampNilField, storeIdent: "completed_at" }
+ created_by: { goType: "[]uint64" }
+ status: { goType: "[]uint" }
+ workflow_id: { goType: "[]uint64", storeIdent: "rel_workflow", ident: "workflowID" }
+ event_type: { goType: "string" }
+ resource_type: { goType: "string" }
+ }
+
+ byValue: ["status", "workflow_id", "event_type", "resource_type", "created_by"]
+ byNilState: ["completed"]
+ }
+
+ store: {
+ ident: "automationSession"
+
+ settings: {
+ rdbms: {
+ table: "automation_sessions"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for session by ID
+
+ It returns session even if deleted
+ """
+ }
+ ]
+ }
+ }
+}
diff --git a/automation/trigger.cue b/automation/trigger.cue
new file mode 100644
index 000000000..5814be293
--- /dev/null
+++ b/automation/trigger.cue
@@ -0,0 +1,64 @@
+package automation
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+trigger: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ workflow_id: { ident: "workflowID", goType: "uint64", storeIdent: "rel_workflow" }
+ step_id: { ident: "stepID", goType: "uint64", storeIdent: "rel_step" }
+ enabled: { goType: "bool" }
+ resource_type: { goType: "string" }
+ event_type: { goType: "string" }
+ meta: { goType: "*types.TriggerMeta" }
+ constraints: { goType: "types.TriggerConstraintSet" }
+ input: { goType: "*expr.Vars" }
+
+ owned_by: { goType: "uint64" }
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ disabled: { goType: "filter.State", storeIdent: "enabled" }
+ trigger_id: { goType: "[]uint64", ident: "triggerID", storeIdent: "id" }
+ workflow_id: { goType: "[]uint64", ident: "workflowID", storeIdent: "rel_workflow" }
+ event_type: { goType: "string" }
+ resource_type: { goType: "string" }
+ }
+
+ byValue: ["trigger_id", "workflow_id", "event_type", "resource_type"]
+ byNilState: ["deleted"]
+ byFalseState: ["disabled"]
+ }
+
+ store: {
+ ident: "automationTrigger"
+
+ settings: {
+ rdbms: {
+ table: "automation_triggers"
+ }
+ }
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for trigger by ID
+
+ It returns trigger even if deleted
+ """
+ }
+ ]
+ }
+ }
+}
diff --git a/automation/workflow.cue b/automation/workflow.cue
index 00f941086..9a935e7af 100644
--- a/automation/workflow.cue
+++ b/automation/workflow.cue
@@ -4,7 +4,40 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-workflow: schema.#resource & {
+workflow: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ meta: { goType: "*types.WorkflowMeta" }
+ enabled: { goType: "bool" }
+ trace: { goType: "bool" }
+ keep_sessions: { goType: "int" }
+ scope: { goType: "*expr.Vars" }
+ steps: { goType: "types.WorkflowStepSet" }
+ paths: { goType: "types.WorkflowPathSet" }
+ issues: { goType: "types.WorkflowIssueSet" }
+ run_as: { goType: "uint64" }
+
+ owned_by: { goType: "uint64" }
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ disabled: { goType: "filter.State", storeIdent: "enabled" }
+ }
+
+ query: ["handle"]
+ byNilState: ["deleted"]
+ byFalseState: ["disabled"]
+ }
+
rbac: {
operations: {
"read": description: "Read workflow"
@@ -16,4 +49,36 @@ workflow: schema.#resource & {
"sessions.manage": description: "Manage workflow sessions"
}
}
+
+ store: {
+ ident: "automationWorkflow"
+
+ settings: {
+ rdbms: {
+ table: "automation_workflows"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for workflow by ID
+
+ It returns workflow even if deleted
+ """
+ }, {
+ fields: ["handle"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for workflow by their handle
+
+ It returns only valid workflows
+ """
+ }
+ ]
+ }
+ }
}
diff --git a/codegen/.gitignore b/codegen/.gitignore
index 796b96d1c..4c3f18b1a 100644
--- a/codegen/.gitignore
+++ b/codegen/.gitignore
@@ -1 +1,2 @@
/build
+tmp*.cue
diff --git a/codegen/Makefile b/codegen/Makefile
index ee31fd174..8b9578f2e 100644
--- a/codegen/Makefile
+++ b/codegen/Makefile
@@ -18,6 +18,3 @@ $(DEF_DOCS): $(CUE) $(JSONTPLEXEC)
@[ "${DOCS_DIR}" ] || ( echo "DOCS_DIR is not set, run make like this: make docs DOCS_DIR=/path/to/corteza-docs"; exit 1 )
@ echo "$(COLOUR_GREEN)Generating doc files from $@$(COLOUR_END) $(COLOUR_BLUE)(dst: $(DOCS_DIR))$(COLOUR_END)"
@ $(CUE) eval $@ --out json | $(JSONTPLEXEC) -v -p $(ROOT_DIR)/codegen/assets/templates -b $(DOCS_DIR)
-
-gen:
- @ rm $(JSONTPLEXEC)
diff --git a/codegen/assets/templates/gocode/locale/service.go.tpl b/codegen/assets/templates/gocode/locale/service.go.tpl
deleted file mode 100644
index f18b25cdd..000000000
--- a/codegen/assets/templates/gocode/locale/service.go.tpl
+++ /dev/null
@@ -1,206 +0,0 @@
-package {{ .package }}
-
-{{ template "gocode/header-gentext.tpl" }}
-
-import (
- "context"
-
-{{- range .imports }}
- {{ . }}
-{{- end }}
- "github.com/cortezaproject/corteza-server/pkg/actionlog"
- intAuth "github.com/cortezaproject/corteza-server/pkg/auth"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/locale"
- "github.com/cortezaproject/corteza-server/pkg/options"
- "github.com/cortezaproject/corteza-server/store"
- systemTypes "github.com/cortezaproject/corteza-server/system/types"
- "golang.org/x/text/language"
-)
-
-type (
- localeAccessControl interface {
- CanManageResourceTranslations(ctx context.Context) bool
- }
-
- resourceTranslationsManager struct {
- actionlog actionlog.Recorder
- locale locale.Resource
- store store.Storer
- ac localeAccessController
- }
-
- localeAccessController interface {
- CanManageResourceTranslations(context.Context) bool
- }
-
- ResourceTranslationsManagerService interface {
-{{- range .resources }}
- {{ .expIdent }}(ctx context.Context, {{ range .references }}{{ . }} uint64, {{ end }}) (locale.ResourceTranslationSet, error)
-{{- end }}
-
- Upsert(context.Context, locale.ResourceTranslationSet) error
- Locale() locale.Resource
- }
-)
-
-var ErrNotAllowedToManageResourceTranslations = errors.Unauthorized("not allowed to manage resource translations")
-
-func ResourceTranslationsManager(ls locale.Resource) *resourceTranslationsManager {
- return &resourceTranslationsManager{
- actionlog: DefaultActionlog,
- store: DefaultStore,
- ac: DefaultAccessControl,
- locale: ls,
- }
-}
-
-func (svc resourceTranslationsManager) Upsert(ctx context.Context, rr locale.ResourceTranslationSet) (err error) {
- // User is allowed to manage resource translations when:
- // - managed resource translation strings are all for default language
- // or
- // - user is allowed to manage resource translations
- if rr.ContainsForeign(svc.Locale().Default().Tag) {
- if !svc.ac.CanManageResourceTranslations(ctx) {
- return ErrNotAllowedToManageResourceTranslations
- }
- }
-
- for _, r := range rr {
- r.Msg = locale.SanitizeMessage(r.Msg)
- }
-
- // @todo validation
-
- me := intAuth.GetIdentityFromContext(ctx)
-
- // - group by resource
- localeByRes := make(map[string]locale.ResourceTranslationSet)
- for _, r := range rr {
- localeByRes[r.Resource] = append(localeByRes[r.Resource], r)
- }
-
- // - for each resource, fetch the current state
- sysLocale := make(systemTypes.ResourceTranslationSet, 0, len(rr))
- for res, rr := range localeByRes {
- current, _, err := store.SearchResourceTranslations(ctx, svc.store, systemTypes.ResourceTranslationFilter{
- Resource: res,
- })
- if err != nil {
- return err
- }
-
- // get deltas and prepare upsert accordingly
- aux := current.New(rr)
- aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
- cc.ID = nextID()
- cc.CreatedAt = *now()
- cc.CreatedBy = me.Identity()
-
- return nil
- })
- sysLocale = append(sysLocale, aux...)
-
- aux = current.Old(rr)
- _ = aux.Walk(func(cc *systemTypes.ResourceTranslation) error {
- cc.UpdatedAt = now()
- cc.UpdatedBy = me.Identity()
- return nil
- })
- sysLocale = append(sysLocale, aux...)
- }
-
- err = store.UpsertResourceTranslation(ctx, svc.store, sysLocale...)
- if err != nil {
- return err
- }
-
- // Reload ALL resource translations
- // @todo we could probably do this more selectively and refresh only updated resources?
- _ = locale.Global().ReloadResourceTranslations(ctx)
-
- return nil
-}
-
-func (svc resourceTranslationsManager) Locale() locale.Resource {
- return svc.locale
-}
-
-{{- range .resources }}
-
-func (svc resourceTranslationsManager) {{ .expIdent }}(ctx context.Context, {{ range .references }}{{ . }} uint64, {{ end }}) (locale.ResourceTranslationSet, error) {
- var (
- err error
- out locale.ResourceTranslationSet
- res *types.{{ .expIdent }}
- k types.LocaleKey
- )
-
- res, err = svc.load{{ .expIdent }}(ctx, svc.store, {{ range .references }}{{ . }}, {{ end }})
- if err != nil {
- return nil, err
- }
-
- for _, tag := range svc.locale.Tags() {
- {{- range .keys}}
- {{- if not .customHandler }}
- k = types.{{ .struct }}
- out = append(out, &locale.ResourceTranslation{
- Resource: res.ResourceTranslation(),
- Lang: tag.String(),
- Key: k.Path,
- Msg: svc.locale.TResourceFor(tag, res.ResourceTranslation(), k.Path),
- })
- {{ end }}
- {{- end}}
- }
-
- {{ if .extended }}
- tmp, err := svc.{{ .ident }}Extended(ctx, res)
- return append(out, tmp...), err
- {{- else }}
- return out, nil
- {{- end }}
-}
-
-{{- end }}
-
-func updateTranslations(ctx context.Context, ac localeAccessControl, lsvc ResourceTranslationsManagerService, tt ...*locale.ResourceTranslation) error {
- if lsvc == nil || lsvc.Locale() == nil || lsvc.Locale().Default() == nil {
- // gracefully handle partial initializations
- return nil
- }
-
- var (
- // assuming options will not change after start
- contentLang = lsvc.Locale().Default().Tag
- )
-
- if options.Locale().ResourceTranslationsEnabled {
- contentLang = locale.GetContentLanguageFromContext(ctx)
- // Resource translations enabled
- if contentLang == language.Und {
- // If no content-language meta (HTTP header) info was
- // used, do not run update translations - we do not know
- // what is the language that we're sending in
- return nil
- }
-
- if !lsvc.Locale().SupportedLang(contentLang) {
- // unsupported language
- return errors.InvalidData("unsupported language")
- }
-
- if !ac.CanManageResourceTranslations(ctx) {
- return errors.Unauthorized("not allowed to manage resource translations")
- }
- }
-
- locale.ResourceTranslationSet(tt).SetLanguage(contentLang)
- if err := lsvc.Upsert(ctx, tt); err != nil {
- return err
- }
-
- return nil
-}
-
diff --git a/codegen/assets/templates/gocode/locale/types.go.tpl b/codegen/assets/templates/gocode/locale/types.go.tpl
deleted file mode 100644
index 28a957631..000000000
--- a/codegen/assets/templates/gocode/locale/types.go.tpl
+++ /dev/null
@@ -1,120 +0,0 @@
-package {{ .package }}
-
-{{ template "gocode/header-gentext.tpl" }}
-
-import (
- "fmt"
- "strconv"
- "github.com/cortezaproject/corteza-server/pkg/locale"
-)
-
-type (
- LocaleKey struct {
- Name string
- Resource string
- Path string
- CustomHandler string
- }
-)
-
-// Types and stuff
-const (
-{{- range .resources }}
- {{ .const }} = "{{ .type }}"
-{{- end }}
-)
-
-var (
- // @todo can we remove LocaleKey struct for string constant?
-{{- range .resources }}
-{{- range .keys }}
- {{ .struct }} = LocaleKey{ Path: {{ printf "%q" .path }} }
-{{- end }}
-{{- end }}
-)
-
-{{- range .resources }}
-
-// ResourceTranslation returns string representation of Locale resource for {{ .expIdent }} by calling {{ .expIdent }}ResourceTranslation fn
-//
-// Locale resource is in "{{ .type }}/..." format
-//
-// This function is auto-generated
-func (r {{ .expIdent }}) ResourceTranslation() string {
- return {{ .expIdent }}ResourceTranslation({{ if .references }}{{ range .references }}r.{{ . }},{{ end }}{{ end }})
-}
-
-// {{ .expIdent }}ResourceTranslation returns string representation of Locale resource for {{ .expIdent }}
-//
-// Locale resource is in the {{ .type }}/{{- if .references }}...{{ end }} format
-//
-// This function is auto-generated
-func {{ .expIdent }}ResourceTranslation({{ if .references }}{{ range .references }}{{ . }} uint64,{{ end }}{{ end }}) string {
- {{- if .references }}
- cpts := []interface{{"{}"}}{
- {{ .expIdent }}ResourceTranslationType,
- {{- range .references }}
- strconv.FormatUint({{ . }}, 10),
- {{- end }}
- }
-
- return fmt.Sprintf({{ .expIdent }}ResourceTranslationTpl(), cpts...)
- {{- end }}
-}
-
-func {{ .expIdent }}ResourceTranslationTpl() string {
- {{- if .references }}
- return "%s
- {{- range .references }}/%s{{- end }}"
-
- {{- else }}
- return "%s"
- {{- end }}
-}
-
-func (r *{{ .expIdent }}) DecodeTranslations(tt locale.ResourceTranslationIndex) {
- var aux *locale.ResourceTranslation
-
- {{- range .keys }}
- {{ if .decodeFunc }}
- {{ if not .extended }}
- r.{{ .decodeFunc }}(tt)
- {{- end}}
- {{ else }}
- if aux = tt.FindByKey({{ .struct }}.Path); aux != nil {
- r.{{ .fieldPath }} = aux.Msg
- }
- {{- end}}
- {{- end}}
-
- {{- if .extended }}
- r.decodeTranslations(tt)
- {{- end }}
-}
-
-func (r *{{ .expIdent }}) EncodeTranslations() (out locale.ResourceTranslationSet) {
- out = locale.ResourceTranslationSet{}
- {{- range .keys }}
- {{ if .encodeFunc }}
- {{ if not .extended }}
- out = append(out, r.{{ .encodeFunc }}()...)
- {{- end}}
- {{ else }}
- if r.{{ .fieldPath }} != "" {
- out = append(out, &locale.ResourceTranslation{
- Resource: r.ResourceTranslation(),
- Key: {{ .struct }}.Path,
- Msg: locale.SanitizeMessage(r.{{ .fieldPath }}),
- })
- }
- {{- end}}
- {{- end}}
-
- {{- if .extended }}
- out = append(out, r.encodeTranslations()...)
- {{- end }}
-
- return out
-}
-
-{{- end }}
diff --git a/codegen/assets/templates/gocode/store/interfaces.go.tpl b/codegen/assets/templates/gocode/store/interfaces.go.tpl
new file mode 100644
index 000000000..0e767f1cf
--- /dev/null
+++ b/codegen/assets/templates/gocode/store/interfaces.go.tpl
@@ -0,0 +1,133 @@
+package store
+
+{{ template "gocode/header-gentext.tpl" }}
+
+import (
+ "context"
+ "go.uber.org/zap"
+{{- range $path, $alias := .imports }}
+ {{ $alias }} {{ printf "%q" $path }}
+{{- end }}
+ "github.com/cortezaproject/corteza-server/pkg/locale"
+ "golang.org/x/text/language"
+ "github.com/cortezaproject/corteza-server/pkg/report"
+)
+
+{{ define "extraArgs" -}}
+{{/*This is temporary solution until we properly implement Compose Record Store*/}}
+{{- if eq . "composeRecord" }}mod *composeType.Module, {{ end -}}
+{{- end }}
+{{ define "extraParams" -}}
+{{/*This is temporary solution until we properly implement Compose Record Store*/}}
+{{- if eq . "composeRecord" }}mod, {{ end -}}
+{{- end }}
+
+type (
+ // Storer interface combines interfaces of all supported store interfaces
+ Storer interface {
+ // SetLogger sets new logging facility
+ //
+ // Store facility should fallback to logger.Default when no logging facility is set
+ //
+ // Intentionally closely coupled with Zap logger since this is not some public lib
+ // and it's highly unlikely we'll support different/multiple logging "backend"
+ SetLogger(*zap.Logger)
+
+ // Tx is a transaction handler
+ Tx(context.Context, func(context.Context, Storer) error) error
+
+ // Upgrade store's schema to the latest version
+ Upgrade(context.Context, *zap.Logger) error
+
+ {{- range .types }}
+ {{ .expIdentPlural }}
+ {{- end }}
+ }
+
+{{ range .types }}
+ {{ .expIdentPlural }} interface {
+ Search{{ .expIdentPlural }}(ctx context.Context, {{ template "extraArgs" .ident }} f {{ .goFilterType }}) ({{ .goSetType }}, {{ .goFilterType }}, error)
+ Create{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error
+ Update{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error
+ Upsert{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error
+ Delete{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error
+ {{ .api.deleteByPK.expFnIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} {{ range .api.deleteByPK.primaryKeys }}{{ .ident }} {{ .goType }},{{ end }}) error
+ Truncate{{ .expIdentPlural }}(ctx context.Context, {{ template "extraArgs" .ident }}) error
+
+ {{- range .api.lookups }}
+ {{ .expFnIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} {{ range .args }}{{ .ident }} {{ .goType }}, {{ end }}) (*{{ .returnType }}, error)
+ {{- end }}
+ {{- range .api.functions }}
+ {{ .expFnIdent }}(ctx context.Context, {{ range .args }}{{ .ident }} {{ if .spread}}...{{ end }}{{ .goType }}, {{ end }}) ({{ range .return }}{{ . }}, {{ end }} error)
+ {{- end }}
+ }
+{{ end }}
+)
+
+{{- range .types }}
+ // Search{{ .expIdentPlural }} returns all matching {{ .expIdentPlural }} from store
+ //
+ // This function is auto-generated
+ func Search{{ .expIdentPlural }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }} f {{ .goFilterType }}) ({{ .goSetType }}, {{ .goFilterType }}, error) {
+ return s.Search{{ .expIdentPlural }}(ctx, {{ template "extraParams" .ident }} f)
+ }
+
+ // Create{{ .expIdent }} creates one or more {{ .expIdentPlural }} in store
+ //
+ // This function is auto-generated
+ func Create{{ .expIdent }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error {
+ return s.Create{{ .expIdent }}(ctx, {{ template "extraParams" .ident }}rr...)
+ }
+
+ // Update{{ .expIdent }} updates one or more (existing) {{ .expIdentPlural }} in store
+ //
+ // This function is auto-generated
+ func Update{{ .expIdent }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error {
+ return s.Update{{ .expIdent }}(ctx, {{ template "extraParams" .ident }}rr...)
+ }
+
+ // Upsert{{ .expIdent }} creates new or updates existing one or more {{ .expIdentPlural }} in store
+ //
+ // This function is auto-generated
+ func Upsert{{ .expIdent }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error {
+ return s.Upsert{{ .expIdent }}(ctx, {{ template "extraParams" .ident }}rr...)
+ }
+
+ // Delete{{ .expIdent }} deletes one or more {{ .expIdentPlural }} from store
+ //
+ // This function is auto-generated
+ func Delete{{ .expIdent }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) error {
+ return s.Delete{{ .expIdent }}(ctx, {{ template "extraParams" .ident }}rr...)
+ }
+
+ // Delete{{ .expIdent }}ByID deletes one or more {{ .expIdentPlural }} from store
+ //
+ // This function is auto-generated
+ func {{ .api.deleteByPK.expFnIdent }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }} {{ range .api.deleteByPK.primaryKeys }}{{ .ident }} {{ .goType }},{{ end }}) error {
+ return s.{{ .api.deleteByPK.expFnIdent }}(ctx, {{ template "extraParams" .ident }}{{ range .api.deleteByPK.primaryKeys }}{{ .ident }},{{ end }})
+ }
+
+ // Truncate{{ .expIdentPlural }} Deletes all {{ .expIdentPlural }} from store
+ //
+ // This function is auto-generated
+ func Truncate{{ .expIdentPlural }}(ctx context.Context, s {{ .expIdentPlural }}, {{ template "extraArgs" .ident }}) error {
+ return s.Truncate{{ .expIdentPlural }}(ctx, {{ template "extraParams" .ident }})
+ }
+
+ {{- range .api.lookups }}
+ {{ if .description }}{{ .description }}{{ end }}
+ //
+ // This function is auto-generated
+ func {{ .expFnIdent }}(ctx context.Context, s {{ .expStoreIdent }}, {{ template "extraArgs" .ident }} {{ range .args }}{{ .ident }} {{ .goType }}, {{ end }}) (*{{ .returnType }}, error) {
+ return s.{{ .expFnIdent }}(ctx, {{ template "extraParams" .ident }}{{ range .args }}{{ .ident }}, {{ end }})
+ }
+ {{- end }}
+ {{- range .api.functions }}
+ {{ if .description }}{{ .description }}{{ end }}
+ //
+ // This function is auto-generated
+ func {{ .expFnIdent }}(ctx context.Context, s {{ .expStoreIdent }}, {{ range .args }}{{ .ident }} {{ if .spread}}...{{ end }}{{ .goType }}, {{ end }}) ({{ range .return }}{{ . }}, {{ end }} error) {
+ return s.{{ .expFnIdent }}(ctx, {{ range .args }}{{ .ident }}{{ if .spread}}...{{ end }}, {{ end }})
+ }
+ {{- end }}
+{{- end }}
diff --git a/codegen/assets/templates/gocode/store/rdbms/aux_types.go.tpl b/codegen/assets/templates/gocode/store/rdbms/aux_types.go.tpl
new file mode 100644
index 000000000..74990bead
--- /dev/null
+++ b/codegen/assets/templates/gocode/store/rdbms/aux_types.go.tpl
@@ -0,0 +1,57 @@
+package rdbms
+
+{{ template "gocode/header-gentext.tpl" }}
+
+import (
+ "time"
+ "github.com/cortezaproject/corteza-server/pkg/expr"
+{{- range $path, $alias := .imports }}
+ {{ $alias }} {{ printf "%q" $path }}
+{{- end }}
+)
+
+type (
+{{ range .types }}
+ // {{ .auxIdent }} is an auxiliary structure used for transporting to/from RDBMS store
+ {{ .auxIdent }} struct {
+ {{ range .auxStruct }}
+ {{ .expIdent }} {{ .goType }} {{ printf "`db:%q`" .name }}
+ {{- end }}
+ }
+{{ end }}
+)
+
+{{- range .types }}
+// encodes {{ .expIdent }} to {{ .auxIdent }}
+//
+// This function is auto-generated
+func (aux *{{ .auxIdent }}) encode(res *{{ .goType }}) (_ error) {
+ {{- range .auxStruct }}
+ aux.{{ .expIdent }} = res.{{ .expIdent }}
+ {{- end }}
+ return
+}
+
+// decodes {{ .expIdent }} from {{ .auxIdent }}
+//
+// This function is auto-generated
+func (aux {{ .auxIdent }}) decode() (res *{{ .goType }}, _ error) {
+ res = new({{ .goType }})
+ {{- range .auxStruct }}
+ res.{{ .expIdent }} = aux.{{ .expIdent }}
+ {{- end }}
+ return
+}
+
+// scans row and fills {{ .auxIdent }} fields
+//
+// This function is auto-generated
+func (aux *{{ .auxIdent }})scan(row scalable) (error) {
+ return row.Scan(
+ {{- range .auxStruct }}
+ &aux.{{ .expIdent }},
+ {{- end }}
+ )
+}
+
+{{ end }}
diff --git a/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl b/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl
new file mode 100644
index 000000000..e2e37115e
--- /dev/null
+++ b/codegen/assets/templates/gocode/store/rdbms/filters.go.tpl
@@ -0,0 +1,91 @@
+package rdbms
+
+{{ template "gocode/header-gentext.tpl" }}
+
+import (
+ "strings"
+ {{- range $path, $alias := .imports }}
+ {{ $alias }} {{ printf "%q" $path }}
+ {{- end }}
+ "github.com/doug-martin/goqu/v9"
+)
+
+type (
+ // extendedFilters allows special per-resource
+ // filters to be attached to store
+ //
+ // when optional filter is set, generated filter function is NOT called automatically
+ // (but can be called from the optional filter)
+ extendedFilters struct {
+ // Filter extensions for search/query functions
+ {{ range .types }}
+
+ // optional {{ .ident }} filter function called after the generated function
+ {{ .expIdent }} func({{ .goFilterType }}) ([]goqu.Expression, {{ .goFilterType }}, error)
+ {{ end }}
+ }
+)
+
+{{- range .types }}
+// {{ .expIdent }}Filter returns logical expressions
+//
+// This function is called from Store.Query{{ .expIdentPlural }}() and can be extended
+// by setting Store.Filters.{{ .expIdent }}. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func {{ .expIdent }}Filter(f {{ .goFilterType }})(ee []goqu.Expression, _ {{ .goFilterType }}, err error) {
+ {{ range .filter.byNilState }}
+ if expr := stateNilComparison({{ printf "%q" .storeIdent }}, f.{{ .expIdent }}); expr != nil {
+ ee = append(ee, expr)
+ }
+ {{ end }}
+
+ {{ range .filter.byFalseState }}
+ if expr := stateFalseComparison({{ printf "%q" .storeIdent }}, f.{{ .expIdent }}); expr != nil {
+ ee = append(ee, expr)
+ }
+ {{ end }}
+
+ {{ range .filter.byValue }}
+ {{ if eq .goType "string" }}
+ if val := strings.TrimSpace(f.{{ .expIdent }}); len(val) > 0 {
+ ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).Eq(f.{{ .expIdent }}))
+ }
+ {{ else if eq .goType "bool" }}
+ if f.{{ .expIdent }} {
+ ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).IsTrue())
+ }
+ {{ else if eq .goType "uint64" }}
+ if f.{{ .expIdent }} > 0 {
+ ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).Eq(f.{{ .expIdent }}))
+ }
+ {{ else if eq .goType "[]uint64" }}
+ if len(f.{{ .expIdent }}) > 0 {
+ ee = append(ee, goqu.C({{ printf "%q" .storeIdent }}).In(f.{{ .expIdent }}))
+ }
+ {{ else }}
+ // @todo codegen warning: filtering by {{ .expIdent }} ({{ .goType }}) not supported,
+ // see rdbms.go.tpl and add an exception
+ {{ end }}
+ {{ end }}
+
+ {{ if .filter.byLabel }}
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+ {{ end }}
+
+ {{ if .filter.query }}
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ {{- range .filter.query }}
+ goqu.C({{ printf "%q" .storeIdent }}).ILike("%" + f.Query + "%"),
+ {{- end }}
+ ))
+ }
+ {{ end }}
+
+ return ee, f, err
+}
+{{ end }}
diff --git a/codegen/assets/templates/gocode/store/rdbms/queries.go.tpl b/codegen/assets/templates/gocode/store/rdbms/queries.go.tpl
new file mode 100644
index 000000000..7f8fc8430
--- /dev/null
+++ b/codegen/assets/templates/gocode/store/rdbms/queries.go.tpl
@@ -0,0 +1,114 @@
+package rdbms
+
+{{ template "gocode/header-gentext.tpl" }}
+
+import (
+ "github.com/doug-martin/goqu/v9"
+{{- range $path, $alias := .imports }}
+ {{ $alias }} {{ printf "%q" $path }}
+{{- end }}
+)
+
+var (
+{{- range .types }}
+// {{ .ident }}Table represents {{ .identPlural }} store table
+//
+// This value is auto-generated
+{{ .ident }}Table = goqu.T({{ printf "%q" .settings.rdbms.table }})
+
+// {{ .ident }}SelectQuery assembles select query for fetching {{ .identPlural }}
+//
+// This function is auto-generated
+{{ .ident }}SelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ {{- range .struct }}
+ {{ printf "%q" .storeIdent }},
+ {{- end }}
+ ).From({{ .ident }}Table)
+}
+
+// {{ .ident }}InsertQuery assembles query inserting {{ .identPlural }}
+//
+// This function is auto-generated
+{{ .ident }}InsertQuery = func(d goqu.DialectWrapper, res *{{ .goType }}) *goqu.InsertDataset {
+ return d.Insert({{ .ident }}Table).
+ Rows(goqu.Record{
+ {{- range .struct }}
+ {{ printf "%q" .storeIdent }}: res.{{ .expIdent }},
+ {{- end }}
+ })
+}
+
+// {{ .ident }}UpsertQuery assembles (insert+on-conflict) query for replacing {{ .identPlural }}
+//
+// This function is auto-generated
+{{ .ident }}UpsertQuery = func(d goqu.DialectWrapper, res *{{ .goType }}) *goqu.InsertDataset {
+ var target = `
+ {{- range .struct -}}
+ {{- if .primaryKey -}}
+ ,
+ {{- if .ignoreCase -}}
+ LOWER({{- .storeIdent -}})
+ {{- else -}}
+ {{- .storeIdent -}}
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}`
+
+ return {{ .ident }}InsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ {{- range .struct }}
+ {{- if not .primaryKey }}
+ {{ printf "%q" .storeIdent }}: res.{{ .expIdent }},
+ {{- end }}
+ {{- end }}
+ },
+ ),
+ )
+}
+
+// {{ .ident }}UpdateQuery assembles query for updating {{ .identPlural }}
+//
+// This function is auto-generated
+{{ .ident }}UpdateQuery = func(d goqu.DialectWrapper, res *{{ .goType }}) *goqu.UpdateDataset {
+ return d.Update({{ .ident }}Table).
+ Set(goqu.Record{
+ {{- range .struct }}
+ {{- if not .primaryKey }}
+ {{ printf "%q" .storeIdent }}: res.{{ .expIdent }},
+ {{- end }}
+ {{- end }}
+ }).
+ Where({{ .ident }}PrimaryKeys(res))
+}
+
+// {{ .ident }}DeleteQuery assembles delete query for removing {{ .identPlural }}
+//
+// This function is auto-generated
+{{ .ident }}DeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete({{ .ident }}Table).Where(ee...)
+}
+
+// {{ .ident }}DeleteQuery assembles delete query for removing {{ .identPlural }}
+//
+// This function is auto-generated
+{{ .ident }}TruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate({{ .ident }}Table)
+}
+
+// {{ .ident }}PrimaryKeys assembles set of conditions for all primary keys
+//
+// This function is auto-generated
+{{ .ident }}PrimaryKeys = func(res *{{ .goType }}) goqu.Ex {
+ return goqu.Ex{
+ {{- range .struct }}
+ {{- if .primaryKey }}
+ {{ printf "%q" .storeIdent }}: res.{{ .expIdent }},
+ {{- end }}
+ {{- end }}
+ }
+}
+{{ end }}
+)
diff --git a/codegen/assets/templates/gocode/store/rdbms/rdbms.go.tpl b/codegen/assets/templates/gocode/store/rdbms/rdbms.go.tpl
new file mode 100644
index 000000000..cc4f0b558
--- /dev/null
+++ b/codegen/assets/templates/gocode/store/rdbms/rdbms.go.tpl
@@ -0,0 +1,606 @@
+package rdbms
+
+{{ template "gocode/header-gentext.tpl" }}
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "strings"
+
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/cortezaproject/corteza-server/pkg/errors"
+ "github.com/cortezaproject/corteza-server/pkg/filter"
+ "github.com/cortezaproject/corteza-server/store"
+ "github.com/cortezaproject/corteza-server/store"
+{{- range $path, $alias := .imports }}
+ {{ $alias }} {{ printf "%q" $path }}
+{{- end }}
+)
+
+{{ define "extraArgs" -}}
+{{/*This is temporary solution until we properly implement Compose Record Store*/}}
+{{- if eq . "composeRecord" }}mod *composeType.Module, {{ end -}}
+{{- end }}
+{{ define "extraParams" -}}
+{{/*This is temporary solution until we properly implement Compose Record Store*/}}
+{{- if eq . "composeRecord" }}mod, {{ end -}}
+{{- end }}
+
+var (
+{{ range .types }}
+ _ store.{{ .expIdentPlural }} = &Store{}
+{{- end }}
+)
+
+{{- range .types }}
+// Create{{ .expIdent }} creates one or more rows in {{ .ident }} collection
+//
+// This function is auto-generated
+func (s Store) Create{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) (err error) {
+ for i := range rr {
+ if err = s.check{{ .expIdent }}Constraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, {{ .ident }}InsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+
+ return
+}
+
+// Update{{ .expIdent }} updates one or more existing entries in {{ .ident }} collection
+//
+// This function is auto-generated
+func (s Store) Update{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) (err error) {
+ for i := range rr {
+ if err = s.check{{ .expIdent }}Constraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, {{ .ident }}UpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// Upsert{{ .expIdent }} updates one or more existing entries in {{ .ident }} collection
+//
+// This function is auto-generated
+func (s Store) Upsert{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) (err error) {
+ for i := range rr {
+ if err = s.check{{ .expIdent }}Constraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, {{ .ident }}UpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// Delete{{ .expIdent }} Deletes one or more entries from {{ .ident }} collection
+//
+// This function is auto-generated
+func (s Store) Delete{{ .expIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} rr ...*{{ .goType }}) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, {{ .ident }}DeleteQuery(s.config.Dialect, {{ .ident }}PrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// Delete{{ .expIdent }}ByID deletes single entry from {{ .ident }} collection
+//
+// This function is auto-generated
+func (s Store) {{ .api.deleteByPK.expFnIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} {{ range .api.deleteByPK.primaryKeys }}{{ .ident }} {{ .goType }},{{ end }}) error {
+ return s.Exec(ctx, {{ .ident }}DeleteQuery(s.config.Dialect, goqu.Ex{
+ {{- range .api.deleteByPK.primaryKeys }}
+ {{ printf "%q" .storeIdent }}: {{ .ident }},
+ {{- end }}
+ }))
+}
+
+// Truncate{{ .expIdentPlural }} Deletes all rows from the {{ .ident }} collection
+func (s Store) Truncate{{ .expIdentPlural }}(ctx context.Context, {{ template "extraArgs" .ident }}) error {
+ return s.Exec(ctx, {{ .ident }}TruncateQuery(s.config.Dialect))
+}
+
+// Search{{ .expIdentPlural }} returns (filtered) set of {{ .expIdentPlural }}
+//
+// This function is auto-generated
+func (s Store) Search{{ .expIdentPlural }}(ctx context.Context, {{ template "extraArgs" .ident }} f {{ .goFilterType }}) (set {{ .goSetType }}, _ {{ .goFilterType }}, err error) {
+ {{ if .features.paging }}
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOf{{ .expIdentPlural }} fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOf{{ .expIdentPlural }}(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+ {{ else }}
+ set, _, err = s.Query{{ .expIdentPlural }}(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ {{ end }}
+ return set, f, nil
+}
+
+{{ if .features.paging }}
+// fetchFullPageOf{{ .expIdentPlural }} collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOf{{ .expIdentPlural }}(
+ ctx context.Context,
+ filter {{ .goFilterType }},
+) (set []*{{ .goType }}, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*{{ .goType }}
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter {{ .goFilterType }}
+ )
+
+ set = make([]*{{ .goType }}, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.Query{{ .expIdentPlural }}(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.{{ .api.collectCursorValues.fnIdent }}(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.{{ .api.collectCursorValues.fnIdent }}(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.{{ .api.collectCursorValues.fnIdent }}(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+{{ end }}
+
+// Query{{ .expIdentPlural }} queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) Query{{ .expIdentPlural }}(
+ ctx context.Context,
+ f {{ .goFilterType }},
+) (_ []*{{ .goType }}, more bool, err error) {
+ var (
+ {{ if .features.checkFn }}
+ ok bool
+ {{ end }}
+ set = make([]*{{ .goType }}, 0, DefaultSliceCapacity)
+ res *{{ .goType }}
+ aux {{ .auxIdent }}
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ {{ if .features.sorting }}
+ sortExpr []exp.OrderedExpression
+ {{ end }}
+ )
+
+ if s.config.Filters.{{ .expIdent }} != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.{{ .expIdent }}(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = {{ .expIdent }}Filter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for {{ .expIdent }}: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ {{ if .features.paging }}
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+ {{ end }}
+
+
+ query := {{ .ident }}SelectQuery(s.config.Dialect).Where(expr...)
+
+ {{ if .features.sorting }}
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.{{ .api.sortableFields.fnIdent }}()); err != nil {
+ err = fmt.Errorf("could generate order expression for {{ .expIdent }}: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+ {{ end }}
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query {{ .expIdent }}: %w", err)
+ return
+ }
+
+
+
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query {{ .expIdent }}: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query {{ .expIdent }}: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for {{ .expIdent }}: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode {{ .expIdent }}: %w", err)
+ return
+ }
+
+ {{ if .features.checkFn }}
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+ {{ end }}
+
+ set = append(set, res)
+ }
+
+ {{ if .features.paging }}
+ return set, f.Limit > 0 && count >= f.Limit, err
+ {{ else }}
+ return set, false, err
+ {{ end }}
+}
+
+{{- range .api.lookups }}
+ {{ if .description }}{{ .description }}{{ end }}
+ //
+ // This function is auto-generated
+ func (s Store) {{ .expFnIdent }}(ctx context.Context, {{ template "extraArgs" .ident }} {{ range .args }}{{ .ident }} {{ .goType }}, {{ end }}) (_ *{{ .returnType }}, err error) {
+ var (
+ rows *sql.Rows
+ aux = new({{ .auxIdent }})
+ lookup = {{ .ident }}SelectQuery(s.config.Dialect).Where(
+ {{- range .args }}
+ {{- if .ignoreCase }}
+ s.config.Functions.LOWER(goqu.I({{ printf "%q" .storeIdent }})).Eq(strings.ToLower({{ .ident }})),
+ {{- else }}
+ goqu.I({{ printf "%q" .storeIdent }}).Eq({{ .ident }}),
+ {{- end }}
+ {{- end }}
+ {{- range .nullConstraint }}
+ goqu.I({{ printf "%q" . }}).IsNull(),
+ {{- end }}
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+ }
+{{- end }}
+
+{{ with .api.sortableFields }}
+// {{ .fnIdent }} returns all {{ .expIdent }} columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) {{ .fnIdent }}() map[string]string {
+ return map[string]string{
+ {{- range $k, $v := .fields }}
+ {{ printf "%q: %q" $k $v }},
+ {{- end }}
+ }
+}
+{{ end }}
+
+{{ with .api.collectCursorValues }}
+// {{ .fnIdent }} collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) {{ .fnIdent }}(res *{{ .goType }}, cc ...*filter.SortExpr) *filter.PagingCursor {
+ {{- if .fields }}
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ {{ range .primaryKeys }}
+ pk{{ .expIdent }} bool
+ {{- end }}
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ {{- range .fields }}
+ case {{ printf "%q" .ident }}:
+ cur.Set(c.Column, res.{{ .expIdent }}, c.Descending)
+
+ {{- if .primaryKey }}
+ pk{{ .expIdent }} = true
+ {{- else if .unique }}
+ hasUnique = true
+ {{- end }}
+ {{- end }}
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ {{- range .primaryKeys }}
+ if !hasUnique || !pk{{ .expIdent }} {
+ collect(&filter.SortExpr{Column: {{ printf "%q" .ident }}, Descending: {{ if .descending }}true{{ else }}false{{ end }}})
+ }
+ {{- end }}
+
+ return cur
+ {{ else }}
+ return nil
+ {{- end }}
+}
+{{ end }}
+
+
+{{ with .api.checkConstraints }}
+// {{ .fnIdent }} performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) {{ .fnIdent }}(ctx context.Context, res *{{ .goType }}) (err error) {
+ {{- range .checks }}
+ err = func() (err error) {
+ {{- range .fields }}
+ {{ if eq .goType "uint64" }}
+ if res.{{ .expIdent }} == 0 {
+ // skip check on empty values
+ return nil
+ }
+ {{ else }}
+ // handling string type as default
+ if len(res.{{ .expIdent }}) == 0 {
+ // skip check on empty values
+ return nil
+ }
+ {{ end }}
+ {{ end }}
+
+ {{- range .nullConstraint }}
+ if res.{{ .expIdent }} != nil {
+ // skip check if value is not nil
+ return nil
+ }
+ {{ end }}
+
+ ex, err := s.{{ .lookupFnIdent }}(ctx, {{ range .fields }}res.{{ .expIdent }},{{ end }})
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+ {{ end }}
+ return nil
+}
+{{ end }}
+{{ end }}
diff --git a/codegen/assets/templates/gocode/store/tests/all.go.tpl b/codegen/assets/templates/gocode/store/tests/all.go.tpl
new file mode 100644
index 000000000..35d20db9a
--- /dev/null
+++ b/codegen/assets/templates/gocode/store/tests/all.go.tpl
@@ -0,0 +1,17 @@
+package tests
+
+{{ template "gocode/header-gentext.tpl" }}
+
+import (
+ "testing"
+
+ "github.com/cortezaproject/corteza-server/store"
+)
+
+func testAllGenerated(t *testing.T, s store.Storer) {
+{{ range .types }}
+ t.Run({{ printf "%q" .ident }}, func(t *testing.T) {
+ test{{ .expIdentPlural }}(t, s)
+ })
+{{- end }}
+}
diff --git a/codegen/schema/codegen.cue b/codegen/schema/codegen.cue
index 68d971374..4243ad4cf 100644
--- a/codegen/schema/codegen.cue
+++ b/codegen/schema/codegen.cue
@@ -1,6 +1,6 @@
package schema
-#codegen: {
+#_ioSpec: {
template: string
output: string
@@ -8,6 +8,13 @@ package schema
if output =~ "\\.adoc$" {
syntax: "adoc"
}
+}
+
+#codegen: {
+ bulk?: [...#_ioSpec]
+ if bulk == _|_ {
+ #_ioSpec
+ }
payload: _
}
diff --git a/codegen/schema/component.cue b/codegen/schema/component.cue
index 6e85fe61f..c16562698 100644
--- a/codegen/schema/component.cue
+++ b/codegen/schema/component.cue
@@ -12,7 +12,7 @@ import (
platform: #baseHandle
resources: {
- [key=_]: {"handle": key, "component": handle, "platform": platform} & #resource
+ [key=_]: {"handle": key, "component": handle, "platform": platform} & #Resource
}
fqrn: platform + "::" + handle
diff --git a/codegen/schema/platform.cue b/codegen/schema/platform.cue
index 9328b03b6..83dd24cfb 100644
--- a/codegen/schema/platform.cue
+++ b/codegen/schema/platform.cue
@@ -4,11 +4,15 @@ package schema
ident: #baseHandle | *"corteza"
options: [...#optionsGroup]
- components: [...{platform: ident} & #component]
- // env-var definitions
- // options: {}
- //
+ components: [...{platform: ident} & #component]
+
+ resources: {
+ [key=#handle]: #Resource & {
+ "handle": key,
+ "platform": ident
+ }
+ }
// automation: {
// types: ....
diff --git a/codegen/schema/resource.cue b/codegen/schema/resource.cue
index fb4dccd6f..d41a7894e 100644
--- a/codegen/schema/resource.cue
+++ b/codegen/schema/resource.cue
@@ -1,6 +1,14 @@
package schema
-#resource: #_base & {
+import (
+ "strings"
+)
+
+#Resource: {
+ #_base
+
+ imports: [...{ import: string }]
+
// copy field values from #_base
handle: handle, ident: ident, expIdent: expIdent
@@ -10,9 +18,40 @@ package schema
// Fully qualified resource name
fqrn: string | *(platform + "::" + component + ":" + handle)
- // fields: #Fields
+ struct: #Struct
+ filter: {
+ "expIdent": #expIdent | *"\(expIdent)Filter"
+
+ struct: #Struct
+
+ // generate filtering by-nil-state for the specified fields
+ "byNilState": [...string]
+
+ // generate filtering by-false-state for the specified fields
+ "byFalseState": [...string]
+
+ // generate query filter for the specified fields
+ "query": [...string]
+
+ // filter resources by fields (eq)
+ "byValue": [...string]
+ }
// operations: #Operations
+ features: {
+ // filtering by label
+ labels: bool | *true
+
+ // support pagination
+ paging: bool | *true
+
+ // support sorting
+ sorting: bool | *true
+
+ // support resource check function
+ checkFn: bool | *true
+ }
+
// All parent resources
parents: [... #_base & {
// copy field values from #_base
@@ -35,64 +74,58 @@ package schema
}
}
- // List of known keys for resource translation
- // locale?: {
- // [Name=_]: {
- // name: Name & #Handle
- // path: string
- // custom: bool | *false
- // }
- // }
+ store?: {
+ // how is this resource represented (prefixed/suffixed functions) in the store
+ "ident": #ident | *ident
+ "identPlural": #ident | *"\(store.ident)s"
+ "expIdent": #expIdent | *strings.ToTitle(store.ident)
+ "expIdentPlural": #expIdent | *"\(store.expIdent)s"
+
+ api?: {
+ lookups: [...{
+ _expFields: [ for f in fields {strings.ToTitle(struct[f].expIdent)}]
+
+ "expIdent": "Lookup\(store.expIdent)By" + strings.Join(_expFields, "")
+ description: string | *""
+
+ // fields used for the lookup (must exist in the struct)
+ fields: [...string]
+
+ // Skip null constraints
+ nullConstraint: [...string]
+ constraintCheck: bool | *false
+ }]
+
+ functions: [...{
+ expIdent: string
+
+ description: string | *""
+
+ args: [...{ident: #ident, goType: string, spread: bool | *false}]
+ return: [...string]
+ }]
+ }
+
+ settings: {
+ defaultOrder: [...{ field: string, descending: bool | *false }]
+
+ rdbms: {
+ // use resource handle (plural) as RDBMS table name as default
+ table: string | *"\(strings.Replace(handle, "-", "_", -1))s"
+ }
+ }
+ }
}
-//#fields: {
-// // Each field can be
-// [key=_]: #fields | *({name: key} & #field)
-//}
-//
-//#field: {
-// name: #expIdent
-// unique: bool | *false
-//
-// // Golang type (built-in or other)
-// type: string | *"string"
-//
-// // System fields,
-// system: bool | *false
-//
-// if name =~ "At$" {
-// type: string | *"*time.Time"
-// }
-//}
+#storeFunction: {
+ expIdent: #expIdent
+ args: [...string]
+ return: [...string]
+}
-//#Operations: {
-// [Operation=_]: {operation: Operation} & #Operation
-//}
-
-//#Operation: {
-// name: #ExpIdent
-// description: string
-// can: string | false | *"\(name)"
-//}
-
-//idField: {
-// // Expecting ID field to allways have name ID
-// name: "ID"
-// unique: true
-//
-// // Service fields,
-// // @todo We might want to have a better name for this
-// // service: true
-//
-// // @todo someday we'll replace this with the "ID" type
-// type: "uint64"
-//}
-//
-//handleField: {
-// // Expecting ID field to allways have name ID
-// name: "handle"
-// unique: true
-//
-// // @todo someday we'll replace this with the "ID" type
-// type: "string" & #handle
-//}
+#PkgResource: #Resource & {
+ package: {
+ ident: #ident
+ import: string
+ }
+}
diff --git a/codegen/schema/shared.cue b/codegen/schema/shared.cue
index 72b8a7a79..a366b54da 100644
--- a/codegen/schema/shared.cue
+++ b/codegen/schema/shared.cue
@@ -13,7 +13,7 @@ import (
// More liberal then identifier, allows underscores and dots
#handle: =~"^[A-Za-z][a-zA-Z0-9_\\-\\.]*[a-zA-Z0-9]+$"
-// More liberal then identifier, allows underscores and dots
+// More liberal then identifier
#baseHandle: =~"^[a-z][a-z0-9-]*[a-z0-9]+$"
#_base: {
@@ -22,11 +22,17 @@ import (
handle: #baseHandle | *"base"
_words: strings.Replace(strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1), ".", " ", -1)
- // lowercased (unexported, golang) identifier
+ // lowercase (unexported, golang) identifier
ident: #ident | *strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
- // upercased (exported, golang) identifier
+ // plural
+ identPlural: #ident | *"\(ident)s"
+
+ // uppercase (exported, golang) identifier
expIdent: #expIdent | *strings.Replace(strings.ToTitle(_words), " ", "", -1)
+ // plural exported
+ expIdentPlural: #expIdent | *"\(expIdent)s"
+
...
}
diff --git a/codegen/schema/struct.cue b/codegen/schema/struct.cue
new file mode 100644
index 000000000..3f4be5ccb
--- /dev/null
+++ b/codegen/schema/struct.cue
@@ -0,0 +1,103 @@
+package schema
+
+import (
+ "strings"
+)
+
+#Struct: {
+ // Each field can be
+ [name=_]: {"name": name} & #StructField
+}
+
+// logic in struct fields is a bit different
+#StructField: {
+ name: #ident
+ _words: strings.Replace(strings.Replace(name, "_", " ", -1), ".", " ", -1)
+
+ _ident: strings.ToCamel(strings.Replace(strings.ToTitle(_words), " ", "", -1))
+
+ // Golang type (built-in or other)
+ goType: string | *"string"
+
+ // lowercase (unexported, golang) identifier
+ ident: #ident | *_ident
+
+ // uppercase (exported, golang) identifier
+ expIdent: #expIdent | *strings.ToTitle(ident)
+
+ // store identifier
+ storeIdent: #ident | *name
+ store: bool | *true
+
+ unique: bool | *false
+ sortable: bool | *false
+ descending: bool | *false
+ primaryKey: bool | *false
+ ignoreCase: bool | *false
+
+ #StructJsonTag
+}
+
+IdField: #StructField & {
+ // Expecting ID field to always have name ID
+ name: "id"
+ expIdent: "ID"
+ primaryKey: true
+ unique: true
+
+ // @todo someday we'll replace this with the "ID" type
+ goType: "uint64"
+}
+
+HandleField: #StructField & {
+ // Expecting ID field to always have name handle
+ name: "handle"
+ unique: true
+ ignoreCase: true
+
+ goType: "string"
+}
+
+SortableTimestampField: #StructField & {
+ sortable: true
+ goType: "time.Time"
+}
+
+SortableTimestampNilField: #StructField & {
+ sortable: true
+ goType: "*time.Time"
+}
+
+#StructJsonTag: {
+ name: string
+
+ _specs: {field: string | *name, omitEmpty: bool | *false, "string": bool | *false}
+
+ json: string | _specs | bool | *false
+ jsonTag?: string
+
+ // just wrap whatever we got in json
+ if (json & string) != _|_ {
+ jsonTag: "json:\"\(json)\""
+ }
+
+ // json enable,d wrap with ident as a JSON prop name
+ if (json & bool) != _|_ && json {
+ // generic json tag
+ jsonTag: "json:\"\(name)\""
+ }
+
+ // full-specs
+ if (json & bool) == _|_ && (json & _specs) != _|_ {
+ _omitEmpty: string | *""
+ if json.omitEmpty {
+ _omitEmpty: ",omitempty"
+ }
+ _string: string | *""
+ if json.string {
+ _string: ",string"
+ }
+
+ jsonTag: "json:\"\(json.field)\(_omitEmpty)\(_string)\""
+ }
+}
diff --git a/codegen/server.store.cue b/codegen/server.store.cue
new file mode 100644
index 000000000..8ae2c89ee
--- /dev/null
+++ b/codegen/server.store.cue
@@ -0,0 +1,230 @@
+package codegen
+
+import (
+ "strings"
+ "list"
+ "github.com/cortezaproject/corteza-server/app"
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+_StoreResource: {
+ res = "res": schema.#Resource
+ typePkg = "typePkg": string
+
+ result: {
+ ident: res.store.ident
+ identPlural: res.store.identPlural
+ expIdent: res.store.expIdent
+ expIdentPlural: res.store.expIdentPlural
+ goType: "\(typePkg).\(res.expIdent)"
+ goSetType: "\(typePkg).\(res.expIdent)Set"
+ goFilterType: "\(typePkg).\(res.filter.expIdent)"
+
+ struct: [ for f in res.struct if f.store {
+ "ident": f.ident
+ "expIdent": f.expIdent
+ "storeIdent": f.storeIdent
+ "name": f.name
+ "primaryKey": f.primaryKey
+ "ignoreCase": f.ignoreCase
+ "goType": strings.Replace(f.goType, "types.", "\(typePkg).", 1)
+ }]
+
+ filter: {
+ // query fields as defined in struct
+ "query": [ for name in res.filter.query {res.struct[name]}],
+
+ // filter by nil state as defined in filter
+ "byNilState": [ for name in res.filter.byNilState {res.filter.struct[name]}]
+
+ // filter by false as defined in filter
+ "byFalseState": [ for name in res.filter.byFalseState {res.filter.struct[name]}]
+
+ // filter by value as defined in filter
+ // @todo this should be pulled from the struct
+ "byValue": [ for name in res.filter.byValue {res.filter.struct[name]}]
+ "byLabel": res.features.labels
+ }
+
+ auxIdent: "aux\(expIdent)"
+ auxStruct: struct
+
+ features: {
+ paging: res.features.paging
+ sorting: res.features.sorting
+ checkFn: res.features.checkFn
+ }
+
+ api: {
+ if res.store.api != _|_ {
+ _base: {
+ "ident": res.store.ident
+ "expStoreIdent": res.store.expIdentPlural
+ "goType": goType
+ "goFilterType": goFilterType
+ "auxIdent": auxIdent
+ }
+
+ deleteByPK: {
+ primaryKeys: [ for f in res.struct if f.primaryKey {f} ]
+ _pkExpNames: strings.Join([ for f in primaryKeys { f.expIdent } ], "")
+ "expFnIdent": "Delete\(res.store.expIdent)By\(_pkExpNames)"
+ }
+
+ lookups: [
+ for l in res.store.api.lookups {
+ _base
+
+ "expFnIdent": l.expIdent
+
+ if (l.description != _|_) {
+ description: "// \(l.expIdent) " + strings.Join(strings.Split(l.description, "\n"), "\n// ")
+ }
+
+ // Copy all relevant fields from the struct
+ "args": [
+ for name in l.fields {
+ let f = res.struct[name]
+
+ "ident": f.ident
+ "storeIdent": f.storeIdent
+ "goType": f.goType
+ "ignoreCase": f.ignoreCase
+ },
+ ]
+
+ "nullConstraint": l.nullConstraint
+ "returnType": "\(goType)"
+ "collectionFnIdent": "\(res.store.ident)Collection"
+ },
+ ]
+
+ // all additional store functions we need for this resource
+ functions: [
+ for f in res.store.api.functions {
+ _base
+
+ "expFnIdent": f.expIdent
+
+ if (f.description != _|_) {
+ description: "// \(f.expIdent) " + strings.Join(strings.Split(f.description, "\n"), "\n// ")
+ }
+
+ "args": [ for a in f.args {
+ "ident": a.ident
+ "goType": strings.Replace(a.goType, "types.", "\(typePkg).", 1)
+ "spread": a.spread
+ }]
+ "return": [ for r in f.return {strings.Replace(r, "types.", "\(typePkg).", 1)}]
+ },
+ ]
+
+ sortableFields: {
+ _base
+
+ "fnIdent": "sortable\(expIdent)Fields"
+
+ fields: {
+ for f in res.struct if f.sortable || f.unique || f.primaryKey {
+ {
+ "\(strings.ToLower(f.name))": f.name
+ "\(strings.ToLower(f.ident))": f.name
+ }
+ }
+ }
+ }
+
+ collectCursorValues: {
+ _base
+
+ "fnIdent": "collect\(expIdent)CursorValues"
+
+ fields: [ for f in res.struct if f.sortable || f.unique || f.primaryKey {f} ]
+ primaryKeys: [ for f in res.struct if f.primaryKey {f} ]
+ }
+
+ checkConstraints: {
+ _base
+
+ "fnIdent": "check\(expIdent)Constraints"
+
+ checks: [
+ for lookup in res.store.api.lookups if lookup.constraintCheck {
+ lookupFnIdent: lookup.expIdent
+ fields: [ for name in lookup.fields {res.struct[name]}]
+ nullConstraint: [
+ for f in res.struct if list.Contains(lookup.nullConstraint, f.name) {
+ "expIdent": f.expIdent
+ },
+ ]
+ },
+ ]
+ }
+ }
+ }
+
+ settings: res.store.settings
+ }
+}
+
+// Codegen template payload, reused for multiple outputs
+_payload: {
+ package: string | *"store"
+
+ imports: {
+ // per-component type imports
+ for cmp in app.corteza.components for res in cmp.resources if res.store != _|_ {
+ "github.com/cortezaproject/corteza-server/\(cmp.ident)/types": "\(cmp.ident)Type"
+ }
+
+ for res in app.corteza.resources if res.store != _|_ {
+ "\(res.package.import)": "\(res.package.ident)Type"
+ }
+
+ for cmp in app.corteza.components for res in cmp.resources for i in res.imports {
+ "\(i.import)": ""
+ }
+ }
+
+ types: {
+ // for each resource in every store with store and actions defined
+ for cmp in app.corteza.components for res in cmp.resources if res.store != _|_ {
+ // use _Store resource as a function (https://cuetorials.com/patterns/functions/)
+ // and pass res(ource) and type-package string in as "arguments"
+ "\(res.store.ident)": { _StoreResource & { "res": res, "typePkg": "\(cmp.ident)Type" } }.result
+ },
+
+ for res in app.corteza.resources if res.store != _|_ {
+ "\(res.store.ident)": { _StoreResource & { "res": res, "typePkg": "\(res.package.ident)Type" } }.result
+ }
+ }
+}
+
+[...schema.#codegen] &
+[
+ {
+ "bulk": [
+ {
+ "template": "gocode/store/interfaces.go.tpl"
+ "output": "store/interfaces.gen.go"
+ }, {
+ "template": "gocode/store/rdbms/rdbms.go.tpl"
+ "output": "store/adapters/rdbms/rdbms.gen.go"
+ }, {
+ "template": "gocode/store/rdbms/aux_types.go.tpl"
+ "output": "store/adapters/rdbms/aux_types.gen.go"
+ }, {
+ "template": "gocode/store/rdbms/queries.go.tpl"
+ "output": "store/adapters/rdbms/queries.gen.go"
+ }, {
+ "template": "gocode/store/rdbms/filters.go.tpl"
+ "output": "store/adapters/rdbms/filters.gen.go"
+ }, {
+ "template": "gocode/store/tests/all.go.tpl"
+ "output": "store/tests/all_test.go"
+ },
+ ]
+
+ "payload": { _payload }
+ },
+]
diff --git a/codegen/tool/main.go b/codegen/tool/main.go
index 89146a10d..53184c971 100644
--- a/codegen/tool/main.go
+++ b/codegen/tool/main.go
@@ -7,16 +7,24 @@ import (
"os"
"path"
"text/template"
+ "time"
"github.com/cortezaproject/corteza-server/pkg/cli"
)
type (
+ inOut struct {
+ Template string `json:"template"`
+ Output string `json:"output"`
+ Syntax string `json:"syntax"`
+ }
+
task struct {
- Template string `json:"template"`
- Output string `json:"output"`
- Syntax string `json:"syntax"`
- Payload interface{} `json:"payload"`
+ inOut
+
+ Bulk []inOut `json:"bulk"`
+
+ Payload interface{} `json:"payload"`
}
)
@@ -49,32 +57,40 @@ func main() {
err error
)
- print("Waiting for stdin ...\n")
+ started := time.Now()
+ print("Waiting for stdin ...")
if err = input.Decode(&tasks); err != nil {
cli.HandleError(fmt.Errorf("failed to decode input from standard input: %v", err))
}
+ println(time.Now().Sub(started).Round(time.Second)/time.Second, "sec")
+
if tpl, err = loadTemplates(baseTemplate(), tplRootPath); err != nil {
cli.HandleError(fmt.Errorf("failed to load templates: %v", err))
}
for _, j := range tasks {
- output := path.Join(outputBase, j.Output)
- print(fmt.Sprintf("generating %s (from %s) ...", output, j.Template))
-
- switch j.Syntax {
- case "go":
- err = writeFormattedGo(output, tpl.Lookup(j.Template), j.Payload)
- default:
- err = write(output, tpl.Lookup(j.Template), j.Payload)
+ if len(j.Bulk) == 0 {
+ j.Bulk = append(j.Bulk, j.inOut)
}
- if err != nil {
- cli.HandleError(fmt.Errorf("failed to write template: %v", err))
- } else {
- print("done\n")
- }
+ for _, o := range j.Bulk {
+ output := path.Join(outputBase, o.Output)
+ print(fmt.Sprintf("generating %s (from %s) ...", output, o.Template))
+ switch o.Syntax {
+ case "go":
+ err = writeFormattedGo(output, tpl.Lookup(o.Template), j.Payload)
+ default:
+ err = write(output, tpl.Lookup(o.Template), j.Payload)
+ }
+
+ if err != nil {
+ cli.HandleError(fmt.Errorf("failed to write template: %v", err))
+ } else {
+ print("done\n")
+ }
+ }
}
}
diff --git a/codegen/tool/templating.go b/codegen/tool/templating.go
index 7f4babf07..59fc81f1d 100644
--- a/codegen/tool/templating.go
+++ b/codegen/tool/templating.go
@@ -47,17 +47,19 @@ func loadTemplates(rTpl *template.Template, rootDir string) (*template.Template,
func writeFormattedGo(dst string, tpl *template.Template, payload interface{}) error {
return write(dst, tpl, payload, func(in io.ReadWriter) (out io.ReadWriter, err error) {
var (
- bb []byte
+ org, bb []byte
)
- if bb, err = ioutil.ReadAll(in); err != nil {
+ if org, err = ioutil.ReadAll(in); err != nil {
return
}
- if bb, err = format.Source(bb); err != nil {
- // output error and return unformatted source
+ cp := bytes.NewBuffer(org)
+
+ if bb, err = format.Source(cp.Bytes()); err != nil {
+ // output error and return un-formatted source
_, _ = fmt.Fprintf(os.Stderr, "%s fmt warn: %v\n", dst, err)
- return in, err
+ return cp, nil
}
return bytes.NewBuffer(bb), nil
diff --git a/compose/attachment.cue b/compose/attachment.cue
new file mode 100644
index 000000000..6ad8ef1d6
--- /dev/null
+++ b/compose/attachment.cue
@@ -0,0 +1,53 @@
+package compose
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+attachment: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ owner_id: { goType: "uint64", storeIdent: "rel_owner", ident: "ownerID" }
+ namespace_id: { goType: "uint64", storeIdent: "rel_namespace", ident: "namespaceID" }
+ kind: {}
+ url: {}
+ preview_url: {}
+ name: {}
+ meta: { goType: "types.AttachmentMeta" }
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ kind: {}
+ namespace_id: { goType: "uint64", ident: "namespaceID" }
+ page_id: { goType: "uint64", ident: "pageID" }
+ record_id: { goType: "uint64", ident: "recordID" }
+ module_id: { goType: "uint64", ident: "moduleID" }
+ field_name: { }
+ }
+
+ byValue: ["kind", "namespace_id"]
+ }
+
+ store: {
+ ident: "composeAttachment"
+
+ settings: {
+ rdbms: {
+ table: "compose_attachment"
+ }
+ }
+ api: {
+ lookups: [
+ { fields: ["id"] },
+ ]
+ }
+ }
+}
diff --git a/compose/chart.cue b/compose/chart.cue
index 2169c6aaf..b24c0eaee 100644
--- a/compose/chart.cue
+++ b/compose/chart.cue
@@ -4,11 +4,37 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-chart: schema.#resource & {
+chart: schema.#Resource & {
parents: [
{handle: "namespace"},
]
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ name: {}
+ config: { goType: "types.ChartConfig" }
+ namespace_id: { ident: "namespaceID", goType: "uint64", storeIdent: "rel_namespace" }
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ chart_id: { goType: "[]uint64", ident: "chartID", storeIdent: "id" }
+ namespace_id: { goType: "uint64", ident: "namespaceID", storeIdent: "rel_namespace" }
+ handle: { goType: "string" }
+ name: { goType: "string" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ query: ["handle", "name"]
+ byValue: ["handle", "chart_id", "namespace_id"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"read": {}
@@ -16,4 +42,33 @@ chart: schema.#resource & {
"delete": {}
}
}
+
+ store: {
+ ident: "composeChart"
+
+ settings: {
+ rdbms: {
+ table: "compose_chart"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for compose chart by ID
+
+ It returns compose chart even if deleted
+ """
+ }, {
+ fields: ["namespace_id", "handle"]
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for compose chart by handle (case-insensitive)
+ """
+ },
+ ]
+ }
+ }
}
diff --git a/compose/component.cue b/compose/component.cue
index beaad796a..9525bb0dc 100644
--- a/compose/component.cue
+++ b/compose/component.cue
@@ -8,12 +8,14 @@ component: schema.#component & {
handle: "compose"
resources: {
- "chart": chart
- "module": module
- "module-field": moduleField
- "namespace": namespace
- "page": page
- "record": record
+ "attachment": attachment
+ "chart": chart
+ "module": module
+ "module-field": moduleField
+ "namespace": namespace
+ "page": page
+ "record": record
+ "record-value": recordValue
}
rbac: operations: {
@@ -24,3 +26,4 @@ component: schema.#component & {
"resource-translations.manage": description: "List, search, create, or update resource translations"
}
}
+
diff --git a/compose/module-field.cue b/compose/module-field.cue
index 6abbe9fd4..462c87e11 100644
--- a/compose/module-field.cue
+++ b/compose/module-field.cue
@@ -4,12 +4,48 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-moduleField: schema.#resource & {
+moduleField: schema.#Resource & {
parents: [
{handle: "namespace"},
{handle: "module"},
]
+ struct: {
+ id: schema.IdField
+ namespace_id: { ident: "namespaceID", goType: "uint64", store: false }
+ module_id: { ident: "moduleID", goType: "uint64", storeIdent: "rel_module" }
+ place: { goType: "int" }
+ kind: { goType: "string" }
+ name: {}
+ label: {}
+ options: { goType: "types.ModuleFieldOptions" }
+ private: { goType: "bool", storeIdent: "is_private" }
+ required: { goType: "bool", storeIdent: "is_required" }
+ visible: { goType: "bool", storeIdent: "is_visible" }
+ multi: { goType: "bool", storeIdent: "is_multi" }
+ default_value: { goType: "types.RecordValueSet" }
+ expressions: { goType: "types.ModuleFieldExpr" }
+ created_at: { goType: "time.Time" }
+ updated_at: { goType: "*time.Time" }
+ deleted_at: { goType: "*time.Time" }
+ }
+
+ filter: {
+ struct: {
+ module_id: { goType: "[]uint64" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ byNilState: ["deleted"]
+ }
+
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
rbac: {
operations: {
"record.value.read": description: "Read field value on records"
@@ -52,4 +88,27 @@ moduleField: schema.#resource & {
}
}
}
+
+ store: {
+ ident: "composeModuleField"
+
+ settings: {
+ rdbms: {
+ table: "compose_module_field"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["module_id", "name"]
+ constraintCheck: true
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for compose module field by name (case-insensitive)
+ """
+ },
+ ]
+ }
+ }
}
diff --git a/compose/module.cue b/compose/module.cue
index 36821899b..a15f59720 100644
--- a/compose/module.cue
+++ b/compose/module.cue
@@ -4,12 +4,39 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-module: schema.#resource & {
+module: schema.#Resource & {
handle: "module"
parents: [
{handle: "namespace"},
]
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ meta: { goType: "rawJson" }
+ fields: { goType: "types.ModuleFieldSet", store: false }
+ namespace_id: { ident: "namespaceID", goType: "uint64", storeIdent: "rel_namespace" }
+ name: {}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ module_id: { goType: "[]uint64", ident: "moduleID", storeIdent: "id" }
+ namespace_id: { goType: "uint64", ident: "namespaceID", storeIdent: "rel_namespace" }
+ handle: { goType: "string" }
+ name: { goType: "string" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ query: ["handle", "name"]
+ byValue: ["handle", "module_id", "namespace_id"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"read": {}
@@ -20,6 +47,42 @@ module: schema.#resource & {
}
}
+ store: {
+ ident: "composeModule"
+
+ settings: {
+ rdbms: {
+ table: "compose_module"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["namespace_id", "handle"]
+ constraintCheck: true
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for compose module by handle (case-insensitive)
+ """
+ }, {
+ fields: ["namespace_id", "name"]
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for compose module by name (case-insensitive)
+ """
+ }, {
+ fields: ["id"]
+ description: """
+ searches for compose module by ID
+
+ It returns compose module even if deleted
+ """
+ },
+ ]
+ }
+ }
+
locale: {
extended: true
diff --git a/compose/namespace.cue b/compose/namespace.cue
index 3a83c205a..cc8c69d63 100644
--- a/compose/namespace.cue
+++ b/compose/namespace.cue
@@ -4,7 +4,32 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-namespace: schema.#resource & {
+namespace: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ slug: { goType: "string" }
+ enabled: { goType: "bool" }
+ meta: { goType: "types.NamespaceMeta" }
+ name: {}
+ } & {
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ namespace_id: { goType: "[]uint64", ident: "namespaceID" }
+ slug: { goType: "string" }
+ name: { goType: "string" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ query: ["name", "slug"]
+ byValue: ["namespace_id", "name", "slug"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"read": {}
@@ -21,8 +46,6 @@ namespace: schema.#resource & {
}
locale: {
- resource: references: [ "ID"]
-
keys: {
name: {}
metaSubtitle: {
@@ -33,4 +56,34 @@ namespace: schema.#resource & {
}
}
}
+
+ store: {
+ ident: "composeNamespace"
+
+ settings: {
+ rdbms: {
+ table: "compose_namespace"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["slug"]
+ constraintCheck: true
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for namespace by slug (case-insensitive)
+ """
+ }, {
+ fields: ["id"]
+ description: """
+ searches for compose namespace by ID
+
+ It returns compose namespace even if deleted
+ """
+ },
+ ]
+ }
+ }
}
diff --git a/compose/page.cue b/compose/page.cue
index 06875a1ae..3f96cbc28 100644
--- a/compose/page.cue
+++ b/compose/page.cue
@@ -4,11 +4,46 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-page: schema.#resource & {
+page: schema.#Resource & {
parents: [
{handle: "namespace"},
]
+ struct: {
+ id: schema.IdField
+ self_id: { ident: "selfID", goType: "uint64" }
+ module_id: { ident: "moduleID", goType: "uint64", storeIdent: "rel_module" }
+ namespace_id: { ident: "namespaceID", goType: "uint64", storeIdent: "rel_namespace" }
+ handle: schema.HandleField
+ config: { goType: "types.PageConfig" }
+ blocks: { goType: "types.PageBlocks" }
+ children: { goType: "types.PageSet", store: false }
+ visible: { goType: "bool" }
+ weight: { goType: "int" }
+ title: { goType: "string" }
+ description: { goType: "string" }
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ namespace_id: { goType: "uint64", ident: "namespaceID", storeIdent: "rel_namespace" }
+ parent_id: { goType: "uint64", ident: "parentID" }
+ module_id: { goType: "uint64", ident: "moduleID", storeIdent: "rel_module" }
+ root: { goType: "bool" }
+ handle: { goType: "string" }
+ title: { goType: "string" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ query: ["handle", "title", "description"]
+ byValue: ["handle", "namespace_id", "module_id"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"read": {}
@@ -41,4 +76,50 @@ page: schema.#resource & {
}
}
}
+
+ store: {
+ ident: "composePage"
+
+ settings: {
+ rdbms: {
+ table: "compose_page"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["namespace_id", "handle"]
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for page by handle (case-insensitive)
+ """
+ }, {
+ fields: ["namespace_id", "module_id"]
+ nullConstraint: ["deleted_at"]
+ description: """
+ searches for page by moduleID
+ """
+ }, {
+ fields: ["id"]
+ description: """
+ searches for compose page by ID
+
+ It returns compose page even if deleted
+ """
+ },
+ ]
+
+ functions: [
+ {
+ expIdent: "ReorderComposePages"
+ args: [
+ { ident: "namespace_id", goType: "uint64" },
+ { ident: "parent_id", goType: "uint64" },
+ { ident: "page_ids", goType: "[]uint64" }
+ ]
+ }
+ ]
+ }
+ }
}
diff --git a/compose/record.cue b/compose/record.cue
index 0d34cc3a5..03484d05b 100644
--- a/compose/record.cue
+++ b/compose/record.cue
@@ -4,12 +4,39 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-record: schema.#resource & {
+record: schema.#Resource & {
parents: [
{handle: "namespace"},
{handle: "module"},
]
+ struct: {
+ id: schema.IdField
+ module_id: { ident: "moduleID", goType: "uint64" }
+ module: { goType: "*types.Module", store: false }
+ values: { goType: "types.RecordValueSet", store: false }
+ namespace_id: { ident: "namespaceID", goType: "uint64", storeIdent: "rel_namespace" }
+
+ owned_by: { goType: "uint64" }
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ module_id: { goType: "uint64" }
+ namespace_id: { goType: "uint64" }
+ query: { goType: "string" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"read": {}
@@ -17,4 +44,54 @@ record: schema.#resource & {
"delete": {}
}
}
+
+ store: {
+ ident: "composeRecord"
+
+ settings: {
+ rdbms: {
+ table: "compose_record"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ // export: false
+ description: """
+ searches for compose record by ID
+
+ It returns compose record even if deleted
+ """
+ },
+ ]
+
+ functions: [
+ {
+ expIdent: "ComposeRecordReport"
+ args: [
+ { ident: "mod", goType: "*types.Module" },
+ { ident: "metrics", goType: "string" },
+ { ident: "dimensions", goType: "string" },
+ { ident: "filters", goType: "string" }
+ ]
+ return: [ "[]map[string]interface{}" ]
+ }, {
+ expIdent: "ComposeRecordDatasource"
+ args: [
+ { ident: "mod", goType: "*types.Module" },
+ { ident: "ld", goType: "*report.LoadStepDefinition" }
+ ]
+ return: [ "report.Datasource" ]
+ }, {
+ expIdent: "PartialComposeRecordValueUpdate"
+ args: [
+ { ident: "mod", goType: "*types.Module" },
+ { ident: "values", goType: "*types.RecordValue", spread: true }
+ ]
+ }
+ ]
+ }
+ }
}
diff --git a/compose/record_value.cue b/compose/record_value.cue
new file mode 100644
index 000000000..0f4101065
--- /dev/null
+++ b/compose/record_value.cue
@@ -0,0 +1,60 @@
+package compose
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+recordValue: schema.#Resource & {
+ struct: {
+ record_id: { primaryKey: true, goType: "uint64", ident: "recordID" }
+ name: { primaryKey: true, }
+ place: { primaryKey: true, goType: "uint" }
+ ref: { goType: "uint64" }
+ value: { }
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ filter: {
+ struct: {
+ record_id: { goType: "[]uint64", ident: "recordID" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ byValue: ["record_id"]
+ byNilState: ["deleted"]
+ }
+
+
+ store: {
+ ident: "composeRecordValue"
+
+ settings: {
+ rdbms: {
+ table: "compose_record_value"
+ }
+ }
+
+ api: {
+
+
+ functions: [
+ {
+ expIdent: "ComposeRecordValueRefLookup"
+ args: [
+ { ident: "mod", goType: "*types.Module" },
+ { ident: "field", goType: "string" },
+ { ident: "ref", goType: "uint64" }
+ ]
+ return: [ "uint64" ]
+ }
+ ]
+ }
+ }
+}
diff --git a/compose/service/chart_test.go b/compose/service/chart_test.go
index f68131a41..460783a03 100644
--- a/compose/service/chart_test.go
+++ b/compose/service/chart_test.go
@@ -5,11 +5,11 @@ import (
"testing"
"github.com/cortezaproject/corteza-server/pkg/rbac"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
"github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/errors"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
@@ -17,7 +17,7 @@ import (
func TestCharts(t *testing.T) {
var (
ctx = context.Background()
- s, err = sqlite3.ConnectInMemory(ctx)
+ s, err = sqlite.ConnectInMemory(ctx)
namespaceID = nextID()
ns *types.Namespace
diff --git a/compose/service/module_test.go b/compose/service/module_test.go
index 68c5a4f3c..74b378236 100644
--- a/compose/service/module_test.go
+++ b/compose/service/module_test.go
@@ -9,7 +9,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/locale"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
@@ -17,10 +17,10 @@ import (
func TestModules(t *testing.T) {
var (
ctx = context.Background()
- s, err = sqlite3.ConnectInMemory(ctx)
+ s, err = sqlite.ConnectInMemory(ctx)
// ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
- // s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ // s, err = sqlite.ConnectInMemoryWithDebug(ctx)
namespaceID = nextID()
ns *types.Namespace
diff --git a/compose/service/page_test.go b/compose/service/page_test.go
index dd7efcf8a..4834d2b72 100644
--- a/compose/service/page_test.go
+++ b/compose/service/page_test.go
@@ -10,17 +10,17 @@ import (
"github.com/cortezaproject/corteza-server/pkg/logger"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
"github.com/stretchr/testify/require"
)
func TestPageDeleting(t *testing.T) {
var (
//ctx = context.Background()
- //s, err = sqlite3.ConnectInMemory(ctx)
+ //s, err = sqlite.ConnectInMemory(ctx)
ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
namespaceID = nextID()
ns *types.Namespace
diff --git a/compose/service/record_datasource.go b/compose/service/record_datasource.go
index b7b02f480..57037b721 100644
--- a/compose/service/record_datasource.go
+++ b/compose/service/record_datasource.go
@@ -66,11 +66,11 @@ func (svc record) Datasource(ctx context.Context, ld *report.LoadStepDefinition)
}
// Find mod
- mod, err := svc.store.LookupComposeModuleByID(ctx, moduleID)
+ mod, err := store.LookupComposeModuleByID(ctx, svc.store, moduleID)
if err != nil {
return nil, err
}
- mod.Fields, _, err = svc.store.SearchComposeModuleFields(ctx, types.ModuleFieldFilter{
+ mod.Fields, _, err = store.SearchComposeModuleFields(ctx, svc.store, types.ModuleFieldFilter{
ModuleID: []uint64{mod.ID},
})
if err != nil {
@@ -141,5 +141,5 @@ func (svc record) Datasource(ctx context.Context, ld *report.LoadStepDefinition)
ld.Columns = cols
}
- return svc.store.ComposeRecordDatasource(ctx, mod, ld)
+ return store.ComposeRecordDatasource(ctx, svc.store, mod, ld)
}
diff --git a/compose/service/record_test.go b/compose/service/record_test.go
index a71b98de2..9d720201e 100644
--- a/compose/service/record_test.go
+++ b/compose/service/record_test.go
@@ -13,7 +13,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/logger"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
sysTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -163,7 +163,7 @@ func TestRecord_boolFieldPermissionIssueKBR(t *testing.T) {
// uncomment to enable sql conn debugging
//ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
ctx = context.Background()
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
)
req.NoError(err)
@@ -304,7 +304,7 @@ func TestRecord_defValueFieldPermissionIssue(t *testing.T) {
var (
req = require.New(t)
ctx = context.Background()
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
)
t.Log("setting up the test environment")
@@ -445,7 +445,7 @@ func TestRecord_refAccessControl(t *testing.T) {
// uncomment to enable sql conn debugging
//ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
ctx = context.Background()
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
)
req.NoError(err)
@@ -608,7 +608,7 @@ func TestRecord_searchAccessControl(t *testing.T) {
// uncomment to enable sql conn debugging
//ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
ctx = context.Background()
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
)
req.NoError(err)
@@ -708,7 +708,7 @@ func TestRecord_contextualRolesAccessControl(t *testing.T) {
// uncomment to enable sql conn debugging
ctx = logger.ContextWithValue(context.Background(), logger.MakeDebugLogger())
//ctx = context.Background()
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
)
req.NoError(err)
diff --git a/compose/types/attachment.go b/compose/types/attachment.go
index 020c31b58..ddb62db07 100644
--- a/compose/types/attachment.go
+++ b/compose/types/attachment.go
@@ -18,7 +18,7 @@ type (
Url string `json:"url,omitempty"`
PreviewUrl string `json:"previewUrl,omitempty"`
Name string `json:"name,omitempty"`
- Meta attachmentMeta `json:"meta"`
+ Meta AttachmentMeta `json:"meta"`
NamespaceID uint64 `json:"namespaceID,string"`
@@ -48,22 +48,22 @@ type (
filter.Paging
}
- attachmentImageMeta struct {
+ AttachmentImageMeta struct {
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Animated bool `json:"animated"`
}
- attachmentFileMeta struct {
+ AttachmentFileMeta struct {
Size int64 `json:"size"`
Extension string `json:"ext"`
Mimetype string `json:"mimetype"`
- Image *attachmentImageMeta `json:"image,omitempty"`
+ Image *AttachmentImageMeta `json:"image,omitempty"`
}
- attachmentMeta struct {
- Original attachmentFileMeta `json:"original"`
- Preview *attachmentFileMeta `json:"preview,omitempty"`
+ AttachmentMeta struct {
+ Original AttachmentFileMeta `json:"original"`
+ Preview *AttachmentFileMeta `json:"preview,omitempty"`
}
)
@@ -73,23 +73,23 @@ const (
NamespaceAttachment string = "namespace"
)
-func (a *Attachment) SetOriginalImageMeta(width, height int, animated bool) *attachmentFileMeta {
+func (a *Attachment) SetOriginalImageMeta(width, height int, animated bool) *AttachmentFileMeta {
a.imageMeta(&a.Meta.Original, width, height, animated)
return &a.Meta.Original
}
-func (a *Attachment) SetPreviewImageMeta(width, height int, animated bool) *attachmentFileMeta {
+func (a *Attachment) SetPreviewImageMeta(width, height int, animated bool) *AttachmentFileMeta {
if a.Meta.Preview == nil {
- a.Meta.Preview = &attachmentFileMeta{}
+ a.Meta.Preview = &AttachmentFileMeta{}
}
a.imageMeta(a.Meta.Preview, width, height, animated)
return a.Meta.Preview
}
-func (a *Attachment) imageMeta(in *attachmentFileMeta, width, height int, animated bool) {
+func (a *Attachment) imageMeta(in *AttachmentFileMeta, width, height int, animated bool) {
if in.Image == nil {
- in.Image = &attachmentImageMeta{}
+ in.Image = &AttachmentImageMeta{}
}
if width > 0 && height > 0 {
@@ -99,11 +99,11 @@ func (a *Attachment) imageMeta(in *attachmentFileMeta, width, height int, animat
}
}
-func (meta *attachmentMeta) Scan(value interface{}) error {
+func (meta *AttachmentMeta) Scan(value interface{}) error {
//lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8
switch value.(type) {
case nil:
- *meta = attachmentMeta{}
+ *meta = AttachmentMeta{}
case []uint8:
if err := json.Unmarshal(value.([]byte), meta); err != nil {
return errors.Wrapf(err, "cannot scan '%v' into attachmentMeta", value)
@@ -113,6 +113,6 @@ func (meta *attachmentMeta) Scan(value interface{}) error {
return nil
}
-func (meta attachmentMeta) Value() (driver.Value, error) {
+func (meta AttachmentMeta) Value() (driver.Value, error) {
return json.Marshal(meta)
}
diff --git a/compose/types/module_field.go b/compose/types/module_field.go
index 7979a39d2..bf15ab3aa 100644
--- a/compose/types/module_field.go
+++ b/compose/types/module_field.go
@@ -49,6 +49,7 @@ type (
ModuleFieldFilter struct {
ModuleID []uint64
Deleted filter.State
+ Limit uint
}
)
diff --git a/compose/types/record_value.go b/compose/types/record_value.go
index d66512496..adc3be321 100644
--- a/compose/types/record_value.go
+++ b/compose/types/record_value.go
@@ -30,6 +30,7 @@ type (
RecordValueFilter struct {
RecordID []uint64
Deleted filter.State `json:"deleted"`
+ Limit uint
}
)
diff --git a/discovery/service/resource_activity_log.go b/discovery/service/resource_activity_log.go
index ae53b5252..b98b735f3 100644
--- a/discovery/service/resource_activity_log.go
+++ b/discovery/service/resource_activity_log.go
@@ -2,6 +2,7 @@ package service
import (
"context"
+
"github.com/cortezaproject/corteza-server/pkg/discovery/types"
"github.com/cortezaproject/corteza-server/store"
)
@@ -24,7 +25,7 @@ func ResourceActivity() *resourceActivity {
func (svc resourceActivity) Find(ctx context.Context, filter types.ResourceActivityFilter) (aa types.ResourceActivitySet, f types.ResourceActivityFilter, err error) {
err = func() error {
- aa, f, err = store.SearchResourceActivityLogs(ctx, svc.store, filter)
+ aa, f, err = store.SearchResourceActivitys(ctx, svc.store, filter)
if err != nil {
return err
}
diff --git a/federation/component.cue b/federation/component.cue
index febfa3762..c7f775fae 100644
--- a/federation/component.cue
+++ b/federation/component.cue
@@ -9,8 +9,10 @@ component: schema.#component & {
resources: {
"node": node
+ "node-sync": nodeSync
"exposed-module": exposedModule
"shared-module": sharedModule
+ "module-mapping": moduleMapping
}
rbac: operations: {
diff --git a/federation/exposed-module.cue b/federation/exposed-module.cue
index 501d4fe40..5ea70df62 100644
--- a/federation/exposed-module.cue
+++ b/federation/exposed-module.cue
@@ -4,14 +4,69 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-exposedModule: schema.#resource & {
+exposedModule: schema.#Resource & {
parents: [
{handle: "node"},
]
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ name: {}
+ node_id: { ident: "nodeID", goType: "uint64" }
+ compose_module_id: { ident: "composeModuleID", goType: "uint64" }
+ compose_namespace_id: { ident: "composeNamespaceID", goType: "uint64" }
+ fields: { goType: "types.ModuleFieldSet" }
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ node_id: { goType: "uint64", ident: "nodeID", storeIdent: "rel_node" }
+ compose_module_id: { goType: "uint64", ident: "composeModuleID", storeIdent: "rel_compose_module" }
+ compose_namespace_id: { goType: "uint64", ident: "composeNamespaceID", storeIdent: "rel_compose_namespace" }
+ }
+
+ byValue: ["compose_module_id", "compose_namespace_id", "node_id"]
+ }
+
+
rbac: {
operations: {
"manage": description: "Manage exposed module module"
}
}
+
+ store: {
+ ident: "federationExposedModule"
+
+ settings: {
+ rdbms: {
+ table: "federation_exposed_module"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for federation module by ID
+
+ It returns federation module
+ """
+ }
+ ]
+ }
+ }
}
diff --git a/federation/module-mapping.cue b/federation/module-mapping.cue
new file mode 100644
index 000000000..02f0c0b2c
--- /dev/null
+++ b/federation/module-mapping.cue
@@ -0,0 +1,69 @@
+package federation
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+moduleMapping: schema.#Resource & {
+ parents: [
+ {handle: "node"},
+ ]
+
+ features: {
+ labels: false
+ }
+
+ struct: {
+ node_id: { ident: "nodeID", goType: "uint64" }
+ federation_module_id: { ident: "federationModuleID", goType: "uint64" }
+ compose_module_id: { ident: "composeModuleID", goType: "uint64" }
+ compose_namespace_id: { ident: "composeNamespaceID", goType: "uint64" }
+ field_mapping: { goType: "types.ModuleFieldMappingSet" }
+ }
+
+ filter: {
+ struct: {
+ compose_module_id: { goType: "uint64", ident: "composeModuleID", storeIdent: "rel_compose_module" }
+ compose_namespace_id: { goType: "uint64", ident: "composeNamespaceID", storeIdent: "rel_compose_namespace" }
+ federation_module_id: { goType: "uint64", ident: "federationModuleID", storeIdent: "rel_federation_module" }
+ }
+
+ byValue: ["compose_module_id", "compose_namespace_id", "federation_module_id"]
+ }
+
+ rbac: {
+ operations: {
+ "manage": description: "Manage exposed module module"
+ }
+ }
+
+ store: {
+ ident: "federationModuleMapping"
+
+ settings: {
+ rdbms: {
+ table: "federation_module_mapping"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["federation_module_id", "compose_module_id", "compose_namespace_id"]
+ description: """
+ searches for module mapping by federation module id and compose module id
+
+ It returns module mapping
+ """
+ }, {
+ fields: ["federation_module_id"]
+ description: """
+ searches for module mapping by federation module id
+
+ It returns module mapping
+ """
+ }
+ ]
+ }
+ }
+}
diff --git a/federation/node-sync.cue b/federation/node-sync.cue
new file mode 100644
index 000000000..4ae1ce7ad
--- /dev/null
+++ b/federation/node-sync.cue
@@ -0,0 +1,61 @@
+package federation
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+nodeSync: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ node_id: { ident: "nodeID", goType: "uint64", primaryKey: true }
+ module_id: { ident: "moduleID", goType: "uint64" }
+ sync_type: { goType: "string" }
+ sync_status: { goType: "string" }
+ } & {
+ time_of_action: schema.SortableTimestampField
+ }
+
+ filter: {
+ struct: {
+ node_id: { goType: "uint64", storeIdent: "rel_node", ident: "nodeID" }
+ module_id: { goType: "uint64", storeIdent: "rel_module", ident: "moduleID" }
+ sync_status: { goType: "string", storeIdent: "sync_status" }
+ sync_type: { goType: "string", storeIdent: "sync_type" }
+ }
+
+ byValue: ["node_id", "module_id", "sync_status", "sync_type"]
+ }
+
+ store: {
+ ident: "federationNodeSync"
+
+ settings: {
+ rdbms: {
+ table: "federation_nodes_sync"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["node_id"]
+ description: """
+ searches for sync activity by node ID
+
+ It returns sync activity
+ """
+ }, {
+ fields: ["node_id", "module_id", "sync_type", "sync_status"]
+ description: """
+ searches for activity by node, type and status
+
+ It returns sync activity
+ """
+ }
+ ]
+ }
+ }
+}
diff --git a/federation/node.cue b/federation/node.cue
index fd5835c6c..8acaadb4a 100644
--- a/federation/node.cue
+++ b/federation/node.cue
@@ -4,11 +4,81 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-node: schema.#resource & {
+node: schema.#Resource & {
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ }
+
+ struct: {
+ id: schema.IdField
+ name: {}
+ shared_node_id: { ident: "sharedNodeID", goType: "uint64" }
+ base_url: { goType: "string", ident: "baseURL" }
+ status: { goType: "string" }
+ contact: { goType: "string" }
+ pair_token: { goType: "string" }
+ auth_token: { goType: "string" }
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ name: { goType: "string" }
+ base_url: { goType: "string", ident: "baseURL" }
+ status: { goType: "string" }
+ deleted: { goType: "filter.State", storeIdent: "deleted_at" }
+ }
+
+ query: ["name", "base_url"]
+ byQuery: ["status"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"manage": description: "Manage federation node"
"module.create": description: "Create shared module"
}
}
+
+ store: {
+ ident: "federationNode"
+
+ settings: {
+ rdbms: {
+ table: "federation_nodes"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for federation node by ID
+
+ It returns federation node
+ """
+ }, {
+ fields: ["base_url", "shared_node_id"]
+ description: """
+ searches for node by shared-node-id and base-url
+ """
+ }, {
+ fields: ["shared_node_id"]
+ description: """
+ searches for node by shared-node-id
+ """
+ }
+ ]
+ }
+ }
}
diff --git a/federation/service/node_sync.go b/federation/service/node_sync.go
index 0233bc4fe..ecc1c097b 100644
--- a/federation/service/node_sync.go
+++ b/federation/service/node_sync.go
@@ -39,19 +39,19 @@ func (svc nodeSync) Create(ctx context.Context, new *types.NodeSync) (*types.Nod
return NodeSyncErrNodeNotFound()
}
- return store.CreateFederationNodesSync(ctx, s, new)
+ return store.CreateFederationNodeSync(ctx, s, new)
})
return new, svc.recordAction(ctx, aProps, NodeSyncActionCreate, err)
}
func (svc nodeSync) Search(ctx context.Context, f types.NodeSyncFilter) (types.NodeSyncSet, types.NodeSyncFilter, error) {
- return store.SearchFederationNodesSyncs(ctx, svc.store, f)
+ return store.SearchFederationNodeSyncs(ctx, svc.store, f)
}
func (svc nodeSync) LookupLastSuccessfulSync(ctx context.Context, nodeID uint64, syncType string) (ns *types.NodeSync, err error) {
- // todo - filter by synctype does not work
- s, _, err := store.SearchFederationNodesSyncs(ctx, svc.store, types.NodeSyncFilter{
+ // todo - filter by sync-type does not work
+ s, _, err := store.SearchFederationNodeSyncs(ctx, svc.store, types.NodeSyncFilter{
NodeID: nodeID,
SyncType: syncType,
SyncStatus: types.NodeSyncStatusSuccess,
diff --git a/federation/shared-module.cue b/federation/shared-module.cue
index 614858066..c5a2a3eda 100644
--- a/federation/shared-module.cue
+++ b/federation/shared-module.cue
@@ -4,14 +4,69 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-sharedModule: schema.#resource & {
+sharedModule: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
parents: [
{handle: "node"},
]
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ node_id: { ident: "nodeID", goType: "uint64" }
+ name: {}
+ external_federation_module_id: { ident: "externalFederationModuleID", goType: "uint64" }
+ fields: { goType: "types.ModuleFieldSet" }
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ node_id: { goType: "uint64", ident: "nodeID", storeIdent: "ref_node" }
+ handle: { goType: "string" }
+ name: { goType: "string" }
+ external_federation_module_id: { goType: "uint64", storeIdent: "xref_module", ident: "externalFederationModuleID" }
+ }
+
+ query: ["name", "handle"]
+ byValue: ["handle", "node_id", "name", "external_federation_module_id"]
+ }
+
rbac: {
operations: {
"map": description: "Map shared module"
}
}
+
+ store: {
+ ident: "federationSharedModule"
+
+ settings: {
+ rdbms: {
+ table: "federation_shared_module"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for shared federation module by ID
+
+ It returns shared federation module
+ """
+ }
+ ]
+ }
+ }
}
diff --git a/federation/types/node.go b/federation/types/node.go
index 6fc2f753e..8ac124009 100644
--- a/federation/types/node.go
+++ b/federation/types/node.go
@@ -48,5 +48,7 @@ type (
Check func(node *Node) (bool, error) `json:"-"`
Deleted filter.State `json:"deleted"`
+
+ Limit uint
}
)
diff --git a/go.mod b/go.mod
index e2c1f9e0c..d2dd1de80 100644
--- a/go.mod
+++ b/go.mod
@@ -10,7 +10,6 @@ require (
github.com/766b/chi-prometheus v0.0.0-20211217152057-87afa9aa2ca8
github.com/99designs/basicauth-go v0.0.0-20160802081356-2a93ba0f464d
github.com/Masterminds/sprig v2.22.0+incompatible
- github.com/Masterminds/squirrel v1.5.2
github.com/PaesslerAG/gval v1.1.2
github.com/SentimensRG/ctx v0.0.0-20180729130232-0bfd988c655d
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
@@ -21,9 +20,10 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3
github.com/disintegration/imaging v1.6.2
- github.com/dop251/goja v0.0.0-20220214123719-b09a6bfa842f
+ github.com/dop251/goja v0.0.0-20220324112439-a18ffb9c5866
+ github.com/doug-martin/goqu/v9 v9.18.0
github.com/edwvee/exiffix v0.0.0-20210922235313-0f6cbda5e58f
- github.com/evanw/esbuild v0.14.27
+ github.com/evanw/esbuild v0.14.28
github.com/fsnotify/fsnotify v1.5.1
github.com/gabriel-vasile/mimetype v1.4.0
github.com/getsentry/sentry-go v0.13.0
@@ -33,7 +33,7 @@ require (
github.com/go-chi/jwtauth v1.2.0
github.com/go-oauth2/oauth2/v4 v4.4.3
github.com/go-sql-driver/mysql v1.6.0
- github.com/golang-jwt/jwt/v4 v4.4.0
+ github.com/golang-jwt/jwt/v4 v4.4.1
github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.2
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75
@@ -43,7 +43,6 @@ require (
github.com/gorilla/websocket v1.5.0
github.com/jmoiron/sqlx v1.3.4
github.com/joho/godotenv v1.4.0
- github.com/lann/builder v0.0.0-20180802200727-47ae307949d0
github.com/lestrrat-go/jwx v1.2.20
github.com/lestrrat-go/strftime v1.0.5
github.com/lib/pq v1.10.4
@@ -101,7 +100,6 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.15.0 // indirect
github.com/klauspost/cpuid v1.2.3 // indirect
- github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/lestrrat-go/backoff/v2 v2.0.8 // indirect
github.com/lestrrat-go/blackmagic v1.0.0 // indirect
github.com/lestrrat-go/httpcc v1.0.0 // indirect
@@ -124,13 +122,11 @@ require (
github.com/russellhaering/goxmldsig v1.1.1 // indirect
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd // indirect
github.com/spf13/pflag v1.0.5 // indirect
- github.com/tidwall/gjson v1.14.0 // indirect
- github.com/valyala/bytebufferpool v1.0.0 // indirect
- github.com/valyala/fasthttp v1.34.0 // indirect
+ github.com/stretchr/objx v0.2.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
- golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
- golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
+ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
+ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa // indirect
diff --git a/go.sum b/go.sum
index 43e7fc453..165584347 100644
--- a/go.sum
+++ b/go.sum
@@ -58,6 +58,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno=
github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo=
+github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
+github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY=
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
@@ -65,8 +67,6 @@ github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3Q
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
-github.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIRPzUXE=
-github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v24IBN1I=
github.com/PaesslerAG/gval v1.1.2 h1:EROKxV4/fAKWb0Qoj7NOxmHZA7gcpjOV9XgiRZMRCUU=
@@ -84,7 +84,6 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
-github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
@@ -127,14 +126,6 @@ github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcju
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/cortezaproject/corteza-locale v0.0.0-20220322170233-572348fc2ebb h1:zi9o1xd6ZG47wMPuI6SneR9h4rN9uFGxapKpMPoZk5U=
-github.com/cortezaproject/corteza-locale v0.0.0-20220322170233-572348fc2ebb/go.mod h1:wsI1UftEdBqTuEDKBZmx2LfNu/kZun5pRbCAi420JCg=
-github.com/cortezaproject/corteza-locale v0.0.0-20220324124427-6775aced3be1 h1:IZEJ5PtErB0vWwywp+CGOdSIiaWkchiQxuZ0yI/2A3M=
-github.com/cortezaproject/corteza-locale v0.0.0-20220324124427-6775aced3be1/go.mod h1:wsI1UftEdBqTuEDKBZmx2LfNu/kZun5pRbCAi420JCg=
-github.com/cortezaproject/corteza-locale v0.0.0-20220325122632-efe005772021 h1:imm4kwnqdZ7/fDg9xg1hQphVob/oYg94dzGtC6JcpO0=
-github.com/cortezaproject/corteza-locale v0.0.0-20220325122632-efe005772021/go.mod h1:wsI1UftEdBqTuEDKBZmx2LfNu/kZun5pRbCAi420JCg=
-github.com/cortezaproject/corteza-locale v0.0.0-20220330093001-c81c7910e7eb h1:SxCeZLksG1tNjScUi6aiM0JPPseTxMr2KZL2bYu7J74=
-github.com/cortezaproject/corteza-locale v0.0.0-20220330093001-c81c7910e7eb/go.mod h1:wsI1UftEdBqTuEDKBZmx2LfNu/kZun5pRbCAi420JCg=
github.com/cortezaproject/corteza-locale v0.0.0-20220420093544-33f288d70ae8 h1:k3inoIRB4K3bs5VvgISZPSphUetDIdARgyO2OyAN6Rs=
github.com/cortezaproject/corteza-locale v0.0.0-20220420093544-33f288d70ae8/go.mod h1:wsI1UftEdBqTuEDKBZmx2LfNu/kZun5pRbCAi420JCg=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
@@ -155,6 +146,7 @@ github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14y
github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d h1:1iy2qD6JEhHKKhUOA9IWs7mjco7lnw2qx8FsRI2wirE=
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.0-20210816181553-5444fa50b93d/go.mod h1:tmAIfUFEirG/Y8jhZ9M+h36obRZAk/1fcSpXwAVlfqE=
+github.com/denisenkom/go-mssqldb v0.10.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4=
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3 h1:AqeKSZIG/NIC75MNQlPy/LM3LxfpLwahICJBHwSMFNc=
github.com/dgryski/dgoogauth v0.0.0-20190221195224-5a805980a5f3/go.mod h1:hEfFauPHz7+NnjR/yHJGhrKo1Za+zStgwUETx3yzqgY=
@@ -163,9 +155,11 @@ github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
-github.com/dop251/goja v0.0.0-20220214123719-b09a6bfa842f h1:ztRywKO1rqqS8li0TDcnwi9AGsqAH0ky9NaND69/Ccc=
-github.com/dop251/goja v0.0.0-20220214123719-b09a6bfa842f/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
+github.com/dop251/goja v0.0.0-20220324112439-a18ffb9c5866 h1:LAjokPR4PSrBQ2uLG9jFAa4ajdXUn4acffvcdfN58WA=
+github.com/dop251/goja v0.0.0-20220324112439-a18ffb9c5866/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
+github.com/doug-martin/goqu/v9 v9.18.0 h1:/6bcuEtAe6nsSMVK/M+fOiXUNfyFF3yYtE07DBPFMYY=
+github.com/doug-martin/goqu/v9 v9.18.0/go.mod h1:nf0Wc2/hV3gYK9LiyqIrzBEVGlI8qW3GuDCEobC4wBQ=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/edwvee/exiffix v0.0.0-20210922235313-0f6cbda5e58f h1:RMnUwTnNR070mFAEIoqMYjNirHj8i0h79VXTYyBCyVA=
github.com/edwvee/exiffix v0.0.0-20210922235313-0f6cbda5e58f/go.mod h1:KoE3Ti1qbQXCb3s/XGj0yApHnbnNnn1bXTtB5Auq/Vc=
@@ -180,8 +174,8 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw=
-github.com/evanw/esbuild v0.14.27 h1:flPbSFFXiuX2V886WmwJnu9itv5clDXcLCX5jNK6/W8=
-github.com/evanw/esbuild v0.14.27/go.mod h1:GG+zjdi59yh3ehDn4ZWfPcATxjPDUH53iU4ZJbp7dkY=
+github.com/evanw/esbuild v0.14.28 h1:FiJzaVHy5vhmddiwvJQlE75KZfWE3RLkX3AHBL6r0f0=
+github.com/evanw/esbuild v0.14.28/go.mod h1:GG+zjdi59yh3ehDn4ZWfPcATxjPDUH53iU4ZJbp7dkY=
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
@@ -247,8 +241,9 @@ github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keL
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
-github.com/golang-jwt/jwt/v4 v4.4.0 h1:EmVIxB5jzbllGIjiCV5JG4VylbK3KE400tLGLI1cdfU=
-github.com/golang-jwt/jwt/v4 v4.4.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ=
+github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+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-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -403,7 +398,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.10.10 h1:a/y8CglcM7gLGYmlbP/stPE5sR3hbhFRUjCBfd/0B3I=
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
@@ -424,10 +418,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
-github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=
-github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
-github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=
-github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/lestrrat-go/backoff/v2 v2.0.7/go.mod h1:rHP/q/r9aT27n24JQLa7JhSQZCKBBOiM/uP402WwN8Y=
github.com/lestrrat-go/backoff/v2 v2.0.8 h1:oNb5E5isby2kiro9AgdHLv5N5tint1AnDVVf2E2un5A=
@@ -453,6 +443,7 @@ github.com/lestrrat-go/pdebug/v3 v3.0.1/go.mod h1:za+m+Ve24yCxTEhR59N7UlnJomWwCi
github.com/lestrrat-go/strftime v1.0.5 h1:A7H3tT8DhTz8u65w+JRpiBxM4dINQhUXAZnhBa2xeOE=
github.com/lestrrat-go/strftime v1.0.5/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
+github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk=
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -470,6 +461,7 @@ github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2y
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
+github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
@@ -603,6 +595,8 @@ github.com/steinfletcher/apitest-jsonpath v1.7.1 h1:dj0Z/7DJt2Ts/R52OeVbnMp+gegc
github.com/steinfletcher/apitest-jsonpath v1.7.1/go.mod h1:FzU2i3ZIyIdF6yBI8a0DZ10gCC6jhiD1yAdU0nCz5Do=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
+github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -617,9 +611,8 @@ github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ
github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo=
github.com/tidwall/buntdb v1.1.2/go.mod h1:xAzi36Hir4FarpSHyfuZ6JzPJdjRZ8QlLZSntE2mqlI=
github.com/tidwall/gjson v1.3.4/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls=
+github.com/tidwall/gjson v1.12.1 h1:ikuZsLdhr8Ws0IdROXUS1Gi4v9Z4pGqpX/CvJkxvfpo=
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
-github.com/tidwall/gjson v1.14.0 h1:6aeJ0bzojgWLa82gDQHcx3S0Lr/O51I9bJ5nv6JFx5w=
-github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb h1:5NSYaAdrnblKByzd7XByQEJVT8+9v0W/tIY0Oo4OwrE=
github.com/tidwall/grect v0.0.0-20161006141115-ba9a043346eb/go.mod h1:lKYYLFIr9OIgdgrtgkZ9zgRxRdvPYsExnYBsEAd8W5M=
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
@@ -641,12 +634,9 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
github.com/valyala/fasthttp v1.14.0 h1:67bfuW9azCMwW/Jlq/C+VeihNpAuJMWkYPBig1gdi3A=
github.com/valyala/fasthttp v1.14.0/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE=
-github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4=
-github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
-github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
@@ -690,6 +680,7 @@ go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@@ -796,8 +787,6 @@ golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -901,8 +890,6 @@ golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
diff --git a/pkg/actionlog/types.go b/pkg/actionlog/types.go
index 0ca7da1bf..6f872cd73 100644
--- a/pkg/actionlog/types.go
+++ b/pkg/actionlog/types.go
@@ -6,6 +6,7 @@ import (
"strconv"
"time"
+ "github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/pkg/errors"
)
@@ -67,6 +68,9 @@ type (
Resource string `json:"resource"`
Action string `json:"action"`
Limit uint `json:"limit"`
+
+ // Standard helpers for sorting
+ filter.Sorting
}
loggableMetaValue interface {
diff --git a/pkg/codegen/assets/store_base.gen.go.tpl b/pkg/codegen/assets/store_base.gen.go.tpl
deleted file mode 100644
index 902f5777e..000000000
--- a/pkg/codegen/assets/store_base.gen.go.tpl
+++ /dev/null
@@ -1,133 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: {{ .Source }}
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
-{{- range .Import }}
- {{ normalizeImport . }}
-{{- end }}
-
-{{- if .Functions}}
- {{- range .Functions }}
- {{- if .Import }}
- {{- range .Import }}
- {{ normalizeImport . }}
- {{- end }}
- {{- end }}
- {{- end }}
-{{- end -}}
-)
-
-type (
- {{- $Types := .Types }}
- {{- $Fields := .Fields }}
-
- {{ export .Types.Plural }} interface {
-
-{{ if .Publish }}
- {{- if .Search.Enable }}
- Search{{ export $Types.Plural }}(ctx context.Context{{ template "extraArgsDef" . }}, f {{ $Types.GoFilterType }}) ({{ $Types.GoSetType }}, {{ $Types.GoFilterType }}, error)
- {{- end }}
-{{- range .Lookups }}
- Lookup{{ export $Types.Singular }}By{{ export .Suffix }}(ctx context.Context{{ template "extraArgsDef" $ }}{{- range .Fields }}, {{ cc2underscore .Field }} {{ .Type }}{{- end }}) (*{{ $Types.GoType }}, error)
-{{- end }}
- {{ if .Create.Enable }}
- Create{{ export $Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error
- {{- end }}
- {{ if .Update.Enable }}
- Update{{ export $Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error
- {{- end }}
- {{ if .Upsert.Enable }}
- Upsert{{ export $Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error
- {{- end }}
- {{ if .Delete.Enable }}
- Delete{{ export $Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error
- Delete{{ export $Types.Singular }}By{{ template "primaryKeySuffix" $Fields }}(ctx context.Context{{ template "extraArgsDef" . }} {{ template "primaryKeyArgsDef" $Fields }}) error
- {{- end }}
-
- Truncate{{ export $Types.Plural }}(ctx context.Context{{ template "extraArgsDef" . }}) error
-{{ end }}
-
-{{- if .Functions}}
- // Additional custom functions
- {{- range .Functions }}
-
- // {{ .Name }} (custom function)
- {{ .Name }}(ctx context.Context{{ template "extraArgsDef" . }}) ({{ join ", " .Return }})
- {{- end }}
-{{- end -}}
- }
-)
-
-{{/* convering scenario with non-exported main functions and no additional functions defined
- where we get "imported and not used error" */}}
-var _ *{{ $Types.GoType }}
-var _ context.Context
-
-{{ if .Publish }}
-{{- if .Search.Enable }}
-// Search{{ export $.Types.Plural }} returns all matching {{ $.Types.Plural }} from store
-func Search{{ export $Types.Plural }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}, f {{ $Types.GoFilterType }}) ({{ $Types.GoSetType }}, {{ $Types.GoFilterType }}, error) {
- return s.Search{{ export $Types.Plural }}(ctx{{ template "extraArgsCall" . }}, f)
-}
-{{- end -}}
-
-{{ range .Lookups }}
-
-// Lookup{{ export $.Types.Singular }}By{{ export .Suffix }} {{ comment .Description true -}}
-func Lookup{{ export $Types.Singular }}By{{ export .Suffix }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" $ }}{{- range .Fields }}, {{ cc2underscore .Field }} {{ .Type }}{{- end }}) (*{{ $Types.GoType }}, error) {
- return s.Lookup{{ export $Types.Singular }}By{{ export .Suffix }}(ctx{{ template "extraArgsCall" $ }}{{- range .Fields }}, {{ cc2underscore .Field }}{{- end }})
-}
-{{- end }}
-
-{{ if .Create.Enable }}
-// Create{{ export $.Types.Singular }} creates one or more {{ $.Types.Plural }} in store
-func Create{{ export $Types.Singular }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error {
- return s.Create{{ export $Types.Singular }}(ctx{{ template "extraArgsCall" . }}, rr... )
-}
-{{- end }}
-
-{{ if .Update.Enable }}
-// Update{{ export $.Types.Singular }} updates one or more (existing) {{ $.Types.Plural }} in store
-func Update{{ export $Types.Singular }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error {
- return s.Update{{ export $Types.Singular }}(ctx{{ template "extraArgsCall" . }}, rr... )
-}
-{{ end }}
-
-{{ if .Upsert.Enable }}
-// Upsert{{ export $.Types.Singular }} creates new or updates existing one or more {{ $.Types.Plural }} in store
-func Upsert{{ export $Types.Singular }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error {
- return s.Upsert{{ export $Types.Singular }}(ctx{{ template "extraArgsCall" . }}, rr... )
-}
-{{ end }}
-
-{{ if .Delete.Enable }}
-// Delete{{ export $.Types.Singular }} Deletes one or more {{ $.Types.Plural }} from store
-func Delete{{ export $Types.Singular }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}, rr ... *{{ $Types.GoType }}) error {
- return s.Delete{{ export $Types.Singular }}(ctx{{ template "extraArgsCall" . }}, rr...)
-}
-
-// Delete{{ export $.Types.Singular }}By{{ template "primaryKeySuffix" $.Fields }} Deletes {{ $.Types.Singular }} from store
-func Delete{{ export $Types.Singular }}By{{ template "primaryKeySuffix" $Fields }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }} {{ template "primaryKeyArgsDef" $Fields }}) error {
- return s.Delete{{ export $Types.Singular }}By{{ template "primaryKeySuffix" $Fields }}(ctx{{ template "extraArgsCall" . }}{{ template "primaryKeyArgsCall" $Fields }})
-}
-{{ end }}
-
-// Truncate{{ export $.Types.Plural }} Deletes all {{ $.Types.Plural }} from store
-func Truncate{{ export $Types.Plural }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}) error {
- return s.Truncate{{ export $Types.Plural }}(ctx{{ template "extraArgsCall" . }})
-}
-{{ end }}
-
-{{ range .Functions }}
-func {{ .Name }}(ctx context.Context, s {{ export $Types.Plural }}{{ template "extraArgsDef" . }}) ({{ join ", " .Return }}) {
- return s.{{ .Name }}(ctx{{ template "extraArgsCall" . }})
-}
-{{ end }}
diff --git a/pkg/codegen/assets/store_interfaces_joined.gen.go.tpl b/pkg/codegen/assets/store_interfaces_joined.gen.go.tpl
deleted file mode 100644
index 1697fa883..000000000
--- a/pkg/codegen/assets/store_interfaces_joined.gen.go.tpl
+++ /dev/null
@@ -1,22 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_interfaces_joined.gen.go.tpl
-// Definitions:
-{{- range .Definitions }}
-// - {{ .Source }}
-{{- end }}
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-
-type (
- // Sortable interface combines interfaces of all supported store interfaces
- storerGenerated interface {
- {{ range .Definitions -}}
- {{ export .Types.Plural }}
- {{ end }}
- }
-)
diff --git a/pkg/codegen/assets/store_partials.go.tpl b/pkg/codegen/assets/store_partials.go.tpl
deleted file mode 100644
index 318a0fbd8..000000000
--- a/pkg/codegen/assets/store_partials.go.tpl
+++ /dev/null
@@ -1,49 +0,0 @@
-{{- define "primaryKeyArgsDef" -}}
- {{- range $field := . -}}
- {{- if $field.IsPrimaryKey -}}
- , {{ $field.Arg }} {{ camelCase $field.Type }}
- {{- end -}}
- {{- end -}}
-{{- end -}}
-
-{{- define "primaryKeyArgsCall" -}}
- {{- range $field := . -}}
- {{- if $field.IsPrimaryKey -}}
- , {{ $field.Arg }}
- {{- end -}}
- {{- end -}}
-{{- end -}}
-
-{{- define "primaryKeySuffix" -}}
- {{- range $field := . }}{{ if $field.IsPrimaryKey }}{{ $field.Field }}{{ end }}{{ end -}}
-{{- end -}}
-
-{{ define "extraArgsDefFirst" }}
- {{- range .Arguments -}}
- _{{ .Name }} {{ .Type }},
- {{- end -}}
-{{ end }}
-
-{{ define "extraArgsDef" }}
- {{- range .Arguments -}}
- , _{{ .Name }} {{ .Type }}
- {{- end -}}
-{{ end }}
-
-{{ define "extraArgsDefTypesOnly" }}
- {{- range .Arguments -}}
- , {{ .Type }}
- {{- end -}}
-{{ end }}
-
-{{ define "extraArgsCallFirst" }}
- {{- range .Arguments -}}
- _{{ .Name }},
- {{- end -}}
-{{ end }}
-
-{{ define "extraArgsCall" }}
- {{- range .Arguments -}}
- , _{{ .Name }}{{ if (hasPrefix "..." .Type) }}...{{ end }}
- {{- end -}}
-{{ end }}
diff --git a/pkg/codegen/assets/store_rdbms.gen.go.tpl b/pkg/codegen/assets/store_rdbms.gen.go.tpl
deleted file mode 100644
index e490437af..000000000
--- a/pkg/codegen/assets/store_rdbms.gen.go.tpl
+++ /dev/null
@@ -1,783 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: {{ .Source }}
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/pkg/errors"
-{{- if $.Search.EnablePaging }}
- "github.com/cortezaproject/corteza-server/pkg/filter"
-{{- if and $.Search.Enable (not $.Search.Custom) }}
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-{{- end }}
-{{- end }}
-{{- range .Import }}
- {{ normalizeImport . }}
-{{- end }}
-)
-
-var _ = errors.Is
-
-{{/*
-const (
- {{- if .Create.Enable }}
- TriggerBefore{{ export $.Types.Singular }}Create triggerKey = "{{ unexport $.Types.Singular }}BeforeCreate"
- {{- end }}
- {{- if .Update.Enable }}
- TriggerBefore{{ export $.Types.Singular }}Update triggerKey = "{{ unexport $.Types.Singular }}BeforeUpdate"
- {{- end }}
- {{- if .Upsert.Enable }}
- TriggerBefore{{ export $.Types.Singular }}Upsert triggerKey = "{{ unexport $.Types.Singular }}BeforeUpsert"
- {{- end }}
- {{- if .Delete.Enable }}
- TriggerBefore{{ export $.Types.Singular }}Delete triggerKey = "{{ unexport $.Types.Singular }}BeforeDelete"
- {{- end }}
-)
-*/}}
-
-{{ if $.Search.Enable }}
-{{ if $.Search.Custom }}
-// {{ toggleExport .Search.Export "Search" $.Types.Plural }} not generated
-// {search: {custom:true}}
-{{ else }}
-// {{ toggleExport .Search.Export "Search" $.Types.Plural }} returns all matching rows
-//
-// This function calls convert{{ export $.Types.Singular }}Filter with the given
-// {{ $.Types.GoFilterType }} and expects to receive a working squirrel.SelectBuilder
-func (s Store) {{ toggleExport .Search.Export "Search" $.Types.Plural }}(ctx context.Context{{ template "extraArgsDef" . }}, f {{ $.Types.GoFilterType }}) ({{ $.Types.GoSetType }}, {{ $.Types.GoFilterType }}, error) {
- var (
- err error
- set []*{{ $.Types.GoType }}
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- {{- if .RDBMS.CustomFilterConverter }}
- q, err = s.convert{{ export $.Types.Singular }}Filter({{ template "extraArgsCallFirst" . }}f)
- if err != nil {
- return err
- }
- {{- else }}
- q = s.{{ unexport $.Types.Plural }}SelectBuilder()
- {{- end }}
-
- {{ if $.Search.EnablePaging }}
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- {{- range $.RDBMS.Columns.PrimaryKeyFields }}
- if f.Sort.Get({{ printf "%q" .Column }}) == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: {{ printf "%q" .Column }},
- Descending: {{ if .SortDescending }}true{{ else }}f.Sort.LastDescending(){{ end }},
- })
- }
- {{- end }}
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- {{ end }}
-
- {{ if .RDBMS.CustomSortConverter }}
- if q, err = s.{{ unexport $.Types.Plural }}Sorter({{ template "extraArgsCallFirst" . }}q, sort); err != nil {
- return err
- }
-
- {{ else if $.Search.EnableSorting }}
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortable{{ export $.Types.Singular }}Columns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
- {{ end }}
-
- {{- if $.Search.EnablePaging }}
- set, f.PrevPage, f.NextPage, err = s.{{ unexport "fetchFullPageOf" $.Types.Plural }}(
- ctx{{ template "extraArgsCall" . }},
- q, f.Sort, f.PageCursor,
- f.Limit,
- {{ if $.Search.EnableFilterCheckFn }}f.Check{{ else }}nil{{ end }},
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- {{- else }}
- set, err = s.{{ export "query" $.Types.Plural }}(ctx{{ template "extraArgsCall" . }}, q, {{ if $.Search.EnableFilterCheckFn }}f.Check{{else}}nil{{ end }})
- return err
- {{- end }}
- }()
-}
-{{ end }}
-{{ end }}
-
-
-{{ if $.Search.EnablePaging }}
-// {{ unexport "fetchFullPageOf" $.Types.Plural }} collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) {{ unexport "fetchFullPageOf" $.Types.Plural }} (
- ctx context.Context{{ template "extraArgsDef" . }},
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*{{ $.Types.GoType }}) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*{{ $.Types.GoType }}, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*{{ $.Types.GoType }}
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*{{ $.Types.GoType }}, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
- {{ if .RDBMS.CustomPreLoadProcessor }}
- if tryQuery, err = s.{{ unexport $.Types.Singular }}PreLoadProcessor(tryQuery); err != nil {
- return
- }
- {{- end}}
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.{{ export "query" $.Types.Plural }}(ctx{{ template "extraArgsCall" . }}, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collect{{ export $.Types.Singular }}CursorValues({{ template "extraArgsCallFirst" . }}set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collect{{ export $.Types.Singular }}CursorValues({{ template "extraArgsCallFirst" . }}set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collect{{ export $.Types.Singular }}CursorValues({{ template "extraArgsCallFirst" . }}set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-{{ end }}
-
-
-// {{ export "query" $.Types.Plural }} queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) {{ export "query" $.Types.Plural }} (
- ctx context.Context{{ template "extraArgsDef" . }},
- q squirrel.Sqlizer,
- check func(*{{ $.Types.GoType }}) (bool, error),
-) ([]*{{ $.Types.GoType }}, error) {
- var (
- tmp = make([]*{{ $.Types.GoType }}, 0, DefaultSliceCapacity)
- set = make([]*{{ $.Types.GoType }}, 0, DefaultSliceCapacity)
- res *{{ $.Types.GoType }}
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internal{{ export $.Types.Singular }}RowScanner({{ template "extraArgsCallFirst" . }}rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
-{{ if .RDBMS.CustomPostLoadProcessor }}
- if err = s.{{ unexport $.Types.Singular }}PostLoadProcessor(ctx{{ template "extraArgsCall" . }}, tmp...); err != nil {
- return nil, err
- }
-{{end }}
-
- for _, res = range tmp {
- {{ if $.Search.EnableFilterCheckFn }}
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
- {{ end }}
- set = append(set, res)
- }
-
- return set, nil
-}
-
-
-
-
-{{- range $.Lookups }}
-// {{ toggleExport .Export "Lookup" $.Types.Singular "By" .Suffix }} {{ comment .Description true -}}
-func (s Store) {{ toggleExport .Export "Lookup" $.Types.Singular "By" .Suffix }}(ctx context.Context{{ template "extraArgsDef" $ }}{{- range .RDBMSColumns }}, {{ cc2underscore .Field }} {{ .Type }}{{- end }}) (*{{ $.Types.GoType }}, error) {
- return s.execLookup{{ $.Types.Singular }}(ctx{{ template "extraArgsCall" $ }}, squirrel.Eq{
- {{- range .RDBMSColumns }}
- s.preprocessColumn({{ printf "%q" .AliasedColumn }}, {{ printf "%q" .LookupFilterPreprocess }}): store.PreprocessValue({{ cc2underscore .Field }}, {{ printf "%q" .LookupFilterPreprocess }}),
- {{- end }}
-
- {{ range $field, $value := .Filter }}
- "{{ ($field | $.RDBMS.Columns.Find).AliasedColumn }}": {{ $value }},
- {{- end }}
- })
-}
-{{ end }}
-
-{{ if .Create.Enable }}
-// {{ toggleExport .Create.Export "Create" $.Types.Singular }} creates one or more rows in {{ $.RDBMS.Table }} table
-func (s Store) {{ toggleExport .Create.Export "Create" $.Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $.Types.GoType }}) (err error) {
- for _, res := range rr {
- err = s.check{{ export $.Types.Singular }}Constraints(ctx {{ template "extraArgsCall" $ }}, res)
- if err != nil {
- return err
- }
-
-{{/*
- err = s.{{ unexport $.Types.Singular }}Hook(ctx, TriggerBefore{{ export $.Types.Singular }}Create{{ template "extraArgsCall" . }}, res)
- if err != nil {
- return err
- }
-*/}}
-
- err = s.execCreate{{ export $.Types.Plural }}(ctx, s.internal{{ export $.Types.Singular }}Encoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-{{ end }}
-
-{{ if .Update.Enable }}
-// {{ toggleExport .Update.Export "Update" $.Types.Singular }} updates one or more existing rows in {{ $.RDBMS.Table }}
-func (s Store) {{ toggleExport .Update.Export "Update" $.Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $.Types.GoType }}) error {
- return s.partial{{ export $.Types.Singular "Update" }}(ctx{{ template "extraArgsCall" . }}, nil, rr...)
-}
-
-// partial{{ export $.Types.Singular "Update" }} updates one or more existing rows in {{ $.RDBMS.Table }}
-func (s Store) partial{{ export $.Types.Singular "Update" }}(ctx context.Context{{ template "extraArgsDef" . }}, onlyColumns []string, rr ... *{{ $.Types.GoType }}) (err error) {
- for _, res := range rr {
- err = s.check{{ export $.Types.Singular }}Constraints(ctx {{ template "extraArgsCall" $ }}, res)
- if err != nil {
- return err
- }
-
-{{/*
- err = s.{{ unexport $.Types.Singular }}Hook(ctx, TriggerBefore{{ export $.Types.Singular }}Update{{ template "extraArgsCall" . }}, res)
- if err != nil {
- return err
- }
-*/}}
- err = s.execUpdate{{ export $.Types.Plural }}(
- ctx,
- {{ template "filterByPrimaryKeys" $.RDBMS.Columns.PrimaryKeyFields }},
- s.internal{{ export $.Types.Singular }}Encoder(res).Skip(
- {{- range $.RDBMS.Columns.PrimaryKeyFields -}}
- {{ printf "%q" .Column }},
- {{- end -}}
- ).Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-{{ end }}
-
-{{ if .Upsert.Enable }}
-// {{ toggleExport .Upsert.Export "Upsert" $.Types.Singular }} updates one or more existing rows in {{ $.RDBMS.Table }}
-func (s Store) {{ toggleExport .Upsert.Export "Upsert" $.Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $.Types.GoType }}) (err error) {
- for _, res := range rr {
- err = s.check{{ export $.Types.Singular }}Constraints(ctx {{ template "extraArgsCall" $ }}, res)
- if err != nil {
- return err
- }
-
-{{/*
- err = s.{{ unexport $.Types.Singular }}Hook(ctx, TriggerBefore{{ export $.Types.Singular }}Upsert{{ template "extraArgsCall" . }}, res)
- if err != nil {
- return err
- }
-*/}}
-
- err = s.execUpsert{{ export $.Types.Plural }}(ctx, s.internal{{ export $.Types.Singular }}Encoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-{{ end }}
-
-{{ if .Delete.Enable }}
-// {{ toggleExport .Delete.Export "Delete" $.Types.Singular }} Deletes one or more rows from {{ $.RDBMS.Table }} table
-func (s Store) {{ toggleExport .Delete.Export "Delete" $.Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, rr ... *{{ $.Types.GoType }}) (err error) {
- for _, res := range rr {
-{{/*
- err = s.{{ unexport $.Types.Singular }}Hook(ctx, TriggerBefore{{ export $.Types.Singular }}Delete{{ template "extraArgsCall" . }}, res)
- if err != nil {
- return err
- }
-*/}}
- err= s.execDelete{{ export $.Types.Plural }}(ctx,{{ template "filterByPrimaryKeys" $.RDBMS.Columns.PrimaryKeyFields }})
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// {{ toggleExport .Delete.Export "Delete" $.Types.Singular "By" }}{{ template "primaryKeySuffix" $.RDBMS.Columns }} Deletes row from the {{ $.RDBMS.Table }} table
-func (s Store) {{ toggleExport .Delete.Export "Delete" $.Types.Singular "By" }}{{ template "primaryKeySuffix" $.RDBMS.Columns }}(ctx context.Context{{ template "extraArgsDef" . }}{{ template "primaryKeyArgsDef" $.RDBMS.Columns }}) error {
- return s.execDelete{{ export $.Types.Plural }}(ctx, {{ template "filterByPrimaryKeysWithArgs" $.RDBMS.Columns.PrimaryKeyFields }})
-}
-{{ end }}
-
-// {{ toggleExport .Truncate.Export "Truncate" $.Types.Plural }} Deletes all rows from the {{ $.RDBMS.Table }} table
-func (s Store) {{ toggleExport .Truncate.Export "Truncate" $.Types.Plural }}(ctx context.Context{{ template "extraArgsDef" . }}) error {
- return s.Truncate(ctx, s.{{ unexport $.Types.Singular }}Table())
-}
-
-// execLookup{{ $.Types.Singular }} prepares {{ $.Types.Singular }} query and executes it,
-// returning {{ $.Types.GoType }} (or error)
-func (s Store) execLookup{{ $.Types.Singular }}(ctx context.Context{{ template "extraArgsDef" . }}, cnd squirrel.Sqlizer) (res *{{ $.Types.GoType }}, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.{{ unexport $.Types.Plural }}SelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internal{{ $.Types.Singular }}RowScanner({{ template "extraArgsCallFirst" . }}row)
- if err != nil {
- return
- }
-
-{{ if .RDBMS.CustomPostLoadProcessor }}
- if err = s.{{ unexport $.Types.Singular }}PostLoadProcessor(ctx{{ template "extraArgsCall" . }}, res); err != nil {
- return nil, err
- }
-{{ end }}
-
- return res, nil
-}
-
-{{ if .Create.Enable }}
-// execCreate{{ export $.Types.Plural }} updates all matched (by cnd) rows in {{ $.RDBMS.Table }} with given data
-func (s Store) execCreate{{ export $.Types.Plural }}(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.{{ unexport $.Types.Singular }}Table()).SetMap(payload))
-}
-{{ end }}
-
-{{ if .Update.Enable }}
-// execUpdate{{ export $.Types.Plural }} updates all matched (by cnd) rows in {{ $.RDBMS.Table }} with given data
-func (s Store) execUpdate{{ export $.Types.Plural }}(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.{{ unexport $.Types.Singular }}Table({{ printf "%q" .RDBMS.Alias }})).Where(cnd).SetMap(set))
-}
-{{ end }}
-
-{{ if .Upsert.Enable }}
-// execUpsert{{ export $.Types.Plural }} inserts new or updates matching (by-primary-key) rows in {{ $.RDBMS.Table }} with given data
-func (s Store) execUpsert{{ export $.Types.Plural }}(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.{{ unexport $.Types.Singular }}Table(),
- set,
-{{ range $.RDBMS.Columns }}
- {{- if or .IsPrimaryKey -}}
- s.preprocessColumn({{ printf "%q" .Column }}, {{ printf "%q" .LookupFilterPreprocess }}),
- {{ end }}
-{{- end }}
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-{{ end }}
-
-{{ if .Delete.Enable }}
-// execDelete{{ export $.Types.Plural }} Deletes all matched (by cnd) rows in {{ $.RDBMS.Table }} with given data
-func (s Store) execDelete{{ export $.Types.Plural }}(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.{{ unexport $.Types.Singular }}Table({{ printf "%q" .RDBMS.Alias }})).Where(cnd))
-}
-{{ end }}
-
-func (s Store) internal{{ export $.Types.Singular }}RowScanner({{ template "extraArgsDefFirst" . }}row rowScanner) (res *{{ $.Types.GoType }}, err error) {
- res = &{{ $.Types.GoType }}{}
-
- err = row.Scan(
- {{- range $.RDBMS.Columns }}
- &res.{{ .Field }},
- {{- end }}
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan {{ unexport $.Types.Singular }} db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// Query{{ export $.Types.Plural }} returns squirrel.SelectBuilder with set table and all columns
-func (s Store) {{ unexport $.Types.Plural }}SelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.{{ unexport $.Types.Singular }}Table({{ printf "%q" .RDBMS.Alias }}), s.{{ unexport $.Types.Singular }}Columns({{ printf "%q" $.RDBMS.Alias }})...)
-}
-
-// {{ unexport $.Types.Singular }}Table name of the db table
-func (Store) {{ unexport $.Types.Singular }}Table(aa ... string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "{{ $.RDBMS.Table }}" + alias
-}
-
-// {{ $.Types.Singular }}Columns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) {{ unexport $.Types.Singular }}Columns(aa ... string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- {{- range $.RDBMS.Columns }}
- alias + "{{ .Column }}",
- {{- end }}
- }
-}
-
-// {{ printf "%v" .Search }}
-
-{{ if $.Search.EnableSorting }}
-// sortable{{ $.Types.Singular }}Columns returns all {{ $.Types.Singular }} columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortable{{ $.Types.Singular }}Columns() map[string]string {
- return map[string]string{
- {{ range $.RDBMS.Columns }}
- {{- if .IsSortable -}}
- "{{ toLower .Column }}": "{{ .Column }}",
- {{- if not (eq (.Field|toLower) (.Column|toLower)) }}
- "{{ toLower .Field }}": "{{ .Column }}",
- {{ end -}}
- {{ end -}}
- {{- end }}
- }
-}
-{{ end }}
-
-// internal{{ export $.Types.Singular }}Encoder encodes fields from {{ $.Types.GoType }} to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encode{{ export $.Types.Singular }}
-// func when rdbms.customEncoder=true
-func (s Store) internal{{ export $.Types.Singular }}Encoder(res *{{ $.Types.GoType }}) store.Payload {
-{{- if .RDBMS.CustomEncoder }}
- return s.encode{{ export $.Types.Singular }}(res)
-{{- else }}
- return store.Payload{
- {{- range $.RDBMS.Columns }}
- "{{ .Column }}": res.{{ .Field }},
- {{- end }}
- }
-{{- end }}
-}
-
-{{ if and $.Search.EnablePaging (not $.RDBMS.CustomCursorCollector) }}
-// collect{{ export $.Types.Singular }}CursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collect{{ export $.Types.Singular }}CursorValues({{ template "extraArgsDef" $ }}res *{{ $.Types.GoType }}, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
- {{ range $.RDBMS.Columns.PrimaryKeyFields }}
- pk{{ export .Column }} bool
- {{ end }}
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- {{- range $.RDBMS.Columns }}
- {{- if or .IsSortable .IsUnique .IsPrimaryKey -}}
- case "{{ .Column }}":
- cursor.Set(c.Column, res.{{ .Field }}, c.Descending)
- {{ if .IsUnique -}}
- hasUnique = true
- {{ end }}
- {{ if .IsPrimaryKey -}}
- pk{{ export .Column }} = true
- {{ end }}
- {{- end }}
- {{- end }}
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !({{ range $.RDBMS.Columns.PrimaryKeyFields }}pk{{ export .Column }} && {{ end }} true) {
- collect({{ range $.RDBMS.Columns.PrimaryKeyFields }}&filter.SortExpr{Column: "{{ .Column }}", Descending: {{ .SortDescending }}},{{ end }})
- }
-
- return cursor
-}
-{{ end }}
-
-// check{{ export $.Types.Singular }}Constraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) check{{ export $.Types.Singular }}Constraints(ctx context.Context{{ template "extraArgsDef" $ }}, res *{{ $.Types.GoType }}) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-{{- range $.Lookups }}
- {{ if .UniqueConstraintCheck }}
- {{- range .RDBMSColumns }}
- {{ if eq .Type "uint64" }}
- valid = valid && res.{{ .Field }} > 0
- {{ else if eq .Type "string" }}
- valid = valid && len(res.{{ .Field }}) > 0
- {{ else }}
- // cannot check field {{ .Field }} with unsupported type: {{ .Type }}
- {{ end }}
- {{- end }}
- {{- end }}
-{{- end }}
-
- if !valid {
- return nil
- }
-
- var checks = make([]func () error, 0)
-{{- range $.Lookups }}
- {{ if .UniqueConstraintCheck }}
- checks = append(checks, func () error {
- // Skip lookup by {{ .Suffix }} if {{ export $.Types.Singular }} does not match filters
- {{- range $field, $value := .Filter }}
- if res.{{ $field }} != {{ $value }} {
- return nil
- }
- {{ end }}
-
- ex, err := s.{{ toggleExport .Export "Lookup" $.Types.Singular "By" .Suffix }}(ctx{{ template "extraArgsCall" $ }}{{- range .RDBMSColumns }}, res.{{ .Field }} {{- end }})
- if err == nil && ex != nil {{- range $.RDBMS.Columns.PrimaryKeyFields }} && ex.{{ .Field }} != res.{{ .Field }} {{ end }} {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
- {{ end }}
-{{ end }}
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
-
- return nil
-}
-
-{{/*
-func (s *Store) {{ unexport $.Types.Singular }}Hook(ctx context.Context, key triggerKey{{ template "extraArgsDef" . }}, res *{{ $.Types.GoType }}) error {
- if fn, has := s.config.TriggerHandlers[key]; has {
- return fn.(func (ctx context.Context, s *Store{{ template "extraArgsDef" . }}, res *{{ $.Types.GoType }}) error)(ctx, s{{ template "extraArgsCall" . }}, res)
- }
-
- return nil
-}
-*/}}
-
-
-{{/* ************************************************************ */}}
-
-{{- define "filterByPrimaryKeys" -}}
- squirrel.Eq{
- {{ range . -}}
- s.preprocessColumn({{ printf "%q" .AliasedColumn }}, {{ printf "%q" .LookupFilterPreprocess }}): store.PreprocessValue(res.{{ .Field }}, {{ printf "%q" .LookupFilterPreprocess }}),
- {{- end }}
- }
-{{- end -}}
-
-{{- define "filterByPrimaryKeysWithArgs" -}}
- squirrel.Eq{
- {{ range . -}}
- s.preprocessColumn({{ printf "%q" .AliasedColumn }}, {{ printf "%q" .LookupFilterPreprocess }}): store.PreprocessValue({{ .Arg }}, {{ printf "%q" .LookupFilterPreprocess }}),
- {{ end }}
- }
-{{- end -}}
diff --git a/pkg/codegen/assets/store_test_all.gen.go.tpl b/pkg/codegen/assets/store_test_all.gen.go.tpl
deleted file mode 100644
index 453d1a801..000000000
--- a/pkg/codegen/assets/store_test_all.gen.go.tpl
+++ /dev/null
@@ -1,28 +0,0 @@
-package tests
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_test_all.gen.go.tpl
-// Definitions:
-{{ range . }}
-{{- if .Exported -}}
-// - {{ .Source }}
-{{ end -}}{{- end }}
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-
-import (
- "github.com/cortezaproject/corteza-server/store"
- "testing"
-)
-
-func testAllGenerated(t *testing.T, s store.Storer) {
-{{- range . }}
- // Run generated tests for {{ .Types.Base }}
- t.Run({{ printf "%q" .Types.Base }}, func(t *testing.T) {
- test{{ export .Types.Base }}(t, s)
- })
-{{ end -}}
-}
diff --git a/pkg/codegen/codegen.go b/pkg/codegen/codegen.go
index 2aeceb1b0..63bb2e4d5 100644
--- a/pkg/codegen/codegen.go
+++ b/pkg/codegen/codegen.go
@@ -57,10 +57,6 @@ func Proc() {
restSrc []string
restDefs []*restDef
- storeSrcPath = filepath.Join("store", "*.yaml")
- storeSrc []string
- storeDefs []*storeDef
-
aFuncsSrcPath = filepath.Join("*", "automation", "*_handler.yaml")
aFuncsSrc []string
aFuncsDefs []*aFuncDefs
@@ -156,9 +152,6 @@ func Proc() {
restSrc = glob(restSrcPath)
output("loaded %d rest definitions from %s\n", len(restSrc), restSrcPath)
- storeSrc = glob(storeSrcPath)
- output("loaded %d store definitions from %s\n", len(storeSrc), storeSrcPath)
-
aFuncsSrc = glob(aFuncsSrcPath)
output("loaded %d function definitions from %s\n", len(aFuncsSrc), aFuncsSrcPath)
@@ -176,7 +169,6 @@ func Proc() {
fileList = append(fileList, typeSrc...)
fileList = append(fileList, exprTypeSrc...)
fileList = append(fileList, restSrc...)
- fileList = append(fileList, storeSrc...)
fileList = append(fileList, aFuncsSrc...)
for _, d := range fileList {
@@ -247,12 +239,6 @@ func Proc() {
return
}
- if storeDefs, err = procStore(storeSrc...); err == nil {
- if genCode {
- err = genStore(tpls, storeDefs...)
- }
- }
-
if outputErr(err, "failed to process store:\n") {
return
}
diff --git a/pkg/codegen/store.go b/pkg/codegen/store.go
deleted file mode 100644
index 0636b243a..000000000
--- a/pkg/codegen/store.go
+++ /dev/null
@@ -1,621 +0,0 @@
-package codegen
-
-import (
- "fmt"
- "os"
- "path"
- "regexp"
- "strings"
- "text/template"
-
- "github.com/cortezaproject/corteza-server/pkg/slice"
- "gopkg.in/yaml.v3"
-)
-
-type (
- // definitions are in one file
- storeDef struct {
- Package string
- App string
- Source string
- Filename string
-
- Import []string `yaml:"import"`
-
- // Tries to autogenerate type by changing it to singular and prefixing it with *types.
- Types storeTypeDef `yaml:"types"`
-
- // All known fields that we need to store on a particular type
- //
- // For now, this set does not variate between different implementation
- // To support that, a (sub)set will need to be defined under each implementation (rdbms, mysql, mongo...)
- //
- Fields storeTypeFieldSetDef `yaml:"fields"`
- RDBMS storeTypeRdbmsDef `yaml:"rdbms"`
- Functions []*storeTypeFunctionsDef `yaml:"functions"`
- Arguments []*storeTypeExtraArgumentDef `yaml:"arguments"`
-
- Search storeTypeSearchDef `yaml:"search"`
- Lookups []*storeTypeLookups `yaml:"lookups"`
- Create storeTypeCreateDef `yaml:"create"`
- Update storeTypeUpdateDef `yaml:"update"`
- Upsert storeTypeUpsertDef `yaml:"upsert"`
- Delete storeTypeDeleteDef `yaml:"delete"`
- Truncate storeTypeTruncateDef `yaml:"truncate"`
-
- // Make interfaces and store functions
- Publish bool `yaml:"publish"`
- }
-
- storeTypeDef struct {
- // Name of the package where type can be found
- // (defaults to types)
- Package string `yaml:"package"`
-
- // Name of the base type
- // (defaults to base name of the yaml file)
- Base string `yaml:"base"`
-
- // Singular variation of name
- // (defaults to (s trimmed))
- Singular string `yaml:"singular"`
-
- // Plural variantion of name
- // (defaults to (s appended))
- Plural string `yaml:"plural"`
-
- // Name of the set go type
- // (defaults to .)
- GoType string `yaml:"type"`
-
- // Name of the set go type
- // (defaults to Set)
- GoSetType string `yaml:"setType"`
-
- // Name of the filter go type
- // (defaults to Filter)
- GoFilterType string `yaml:"filterType"`
- }
-
- storeTypeRdbmsDef struct {
- // Alias used in SQL queries
- Alias string `yaml:"alias,omitempty"`
- Table string `yaml:"table,omitempty"`
-
- CustomFilterConverter bool `yaml:"customFilterConverter"`
- CustomSortConverter bool `yaml:"customSortConverter"`
- CustomCursorCollector bool `yaml:"customCursorCollector"`
- CustomPreLoadProcessor bool `yaml:"customPreLoadProcessor"`
- CustomPostLoadProcessor bool `yaml:"customPostLoadProcessor"`
- CustomEncoder bool `yaml:"customEncoder"`
-
- Columns storeTypeRdbmsColumnSetDef
-
- // map fields to columns
- FieldMap map[string]*storeTypeRdbmsColumnDef `yaml:"mapFields"`
- }
-
- storeTypeFunctionsDef struct {
- Name string `yaml:"name"`
- Arguments []storeTypeExtraArgumentDef `yaml:"arguments"`
- Return []string `yaml:"return"`
- Import []string `yaml:"import"`
- }
-
- storeTypeExtraArgumentDef struct {
- Name string
- Type string
- }
-
- storeTypeFieldSetDef []*storeTypeFieldDef
-
- storeTypeFieldDef struct {
- Field string `yaml:"field"`
-
- // Autodiscovery logic (when not explicitly set)
- // uint64: when field has "ID" suffix
- // time.Time: when field equals with "created_at"
- // *time.Time: when field ends with "_at"
- // string: default
- Type string `yaml:"type"`
-
- // If field is flagged as PK it is used in update & Delete conditions
- // Note: if no other field is set as primary and field with ID name
- // exists, that field is auto-set as primary.
- IsPrimaryKey bool `yaml:"isPrimaryKey"`
-
- // FilterPreprocess sets preprocessing function used on
- // conditions for lookup functions
- //
- // See specific implementation for details
- LookupFilterPreprocess string `yaml:"lookupFilterPreprocessor"`
-
- // Is field sortable?
- IsSortable bool `yaml:"sortable"`
-
- // When sorting is disabled and paging enabled and we need to have fixed default
- // sorting set and sometimes default sorting needs to be in descending order
- SortDescending bool `yaml:"sortDescending"`
-
- // Is field unique
- IsUnique bool `yaml:"unique"`
- }
-
- storeTypeRdbmsColumnSetDef []*storeTypeRdbmsColumnDef
-
- storeTypeRdbmsColumnDef struct {
- storeTypeFieldDef
-
- // When not explicitly set, defaults to snake-cased value from field
- //
- // Exceptions:
- // If field name ends with ID (ID), it converts that to rel_
- Column string `yaml:"column"`
-
- alias string
- }
-
- storeTypeLookups struct {
- // LookupBy
- // When not explicitly defined, it names of all fields
- Export bool `yaml:"export"`
- Suffix string `yaml:"suffix"`
- Description string `yaml:"description"`
- UniqueConstraintCheck bool `yaml:"uniqueConstraintCheck"`
- Filter map[string]string `yaml:"filter"`
-
- // maps all defined fields, will be filtered & exposed via Fields() fn
- fields storeTypeFieldSetDef
-
- // maps all defined columns, will be filtered & exposed via RDBMSColumns() fn
- columns storeTypeRdbmsColumnSetDef
-
- // lookup fields, as defined
- YamlFields []string `yaml:"fields"`
- }
-
- storeTypeSearchDef struct {
- Enable bool `yaml:"enable"`
- Export bool `yaml:"export"`
- Custom bool `yaml:"custom"`
- EnablePaging bool `yaml:"enablePaging"`
- EnableSorting bool `yaml:"enableSorting"`
- EnableFilterCheckFn bool `yaml:"enableFilterCheckFunction"`
- }
-
- storeTypeCreateDef struct {
- Enable bool `yaml:"enable"`
- Export bool `yaml:"export"`
- }
-
- storeTypeUpdateDef struct {
- Enable bool `yaml:"enable"`
- Export bool `yaml:"export"`
- }
-
- storeTypeUpsertDef struct {
- Enable bool `yaml:"enable"`
- Export bool `yaml:"export"`
- }
-
- storeTypeDeleteDef struct {
- Enable bool `yaml:"enable"`
- Export bool `yaml:"export"`
- }
-
- storeTypeTruncateDef struct {
- Export bool `yaml:"export"`
- }
-)
-
-var (
- outputDir string = "store"
- spaceSplit = regexp.MustCompile(`\s+`)
-)
-
-func procStore(mm ...string) ([]*storeDef, error) {
- procDef := func(m string) (*storeDef, error) {
- // initialize & set default
- def := &storeDef{
- Source: m,
-
- RDBMS: storeTypeRdbmsDef{
- CustomFilterConverter: false,
- CustomEncoder: false,
- },
-
- Search: storeTypeSearchDef{
- Enable: true,
- Export: true,
- Custom: false,
- EnablePaging: true,
- EnableSorting: true,
- EnableFilterCheckFn: true,
- },
-
- Create: storeTypeCreateDef{
- Enable: true,
- Export: true,
- },
-
- Update: storeTypeUpdateDef{
- Enable: true,
- Export: true,
- },
-
- Upsert: storeTypeUpsertDef{
- Enable: true,
- Export: true,
- },
-
- Delete: storeTypeDeleteDef{
- Enable: true,
- Export: true,
- },
-
- Truncate: storeTypeTruncateDef{
- Export: true,
- },
-
- Publish: true,
- }
- f, err := os.Open(m)
- if err != nil {
- return nil, fmt.Errorf("%s read failed: %w", m, err)
- }
-
- defer f.Close()
-
- if err := yaml.NewDecoder(f).Decode(&def); err != nil {
- return nil, err
- }
-
- def.Filename = path.Base(m)
- def.Filename = def.Filename[:len(def.Filename)-5]
-
- if !def.Search.Enable {
- // No use for any of that if search is disabled...
- def.Search.EnablePaging = false
- def.Search.EnableSorting = false
- def.Search.EnableFilterCheckFn = false
- }
-
- if !def.Create.Enable {
- // No use for any of that if operation is disabled...
- def.Create.Export = false
- }
-
- if !def.Update.Enable {
- // No use for any of that if operation is disabled...
- def.Update.Export = false
- }
-
- if !def.Upsert.Enable {
- // No use for any of that if operation is disabled...
- def.Upsert.Export = false
- }
-
- if !def.Delete.Enable {
- // No use for any of that if operation is disabled...
- def.Delete.Export = false
- }
-
- if def.Types.Base == "" {
- def.Types.Base = export(strings.Split(def.Filename, "_")...)
- }
-
- if def.Types.Singular == "" {
- def.Types.Singular = strings.TrimRight(def.Types.Base, "s")
- }
- if def.Types.Plural == "" {
- def.Types.Plural = def.Types.Singular + "s"
- }
-
- if def.Types.Package == "" {
- def.Types.Package = "types"
- }
-
- if def.Types.GoType == "" {
- def.Types.GoType = def.Types.Package + "." + export(def.Types.Singular)
- }
-
- if def.Types.GoSetType == "" {
- def.Types.GoSetType = def.Types.GoType + "Set"
- }
-
- if def.Types.GoFilterType == "" {
- def.Types.GoFilterType = def.Types.GoType + "Filter"
- }
-
- if def.RDBMS.Alias == "" {
- def.RDBMS.Alias = def.Types.Base[0:1]
- }
-
- for field := range def.RDBMS.FieldMap {
- if nil == def.Fields.Find(field) {
- return nil, fmt.Errorf("invalid RDBMS field map: unknown field %q used", field)
- }
- }
-
- var hasPrimaryKey = def.Fields.HasPrimaryKey()
- for _, fld := range def.Fields {
- if !hasPrimaryKey && fld.Field == "ID" {
- fld.IsPrimaryKey = true
- fld.IsSortable = true
- }
-
- switch {
- case fld.Type != "":
- // type set
- case strings.HasSuffix(fld.Field, "ID") || strings.HasSuffix(fld.Field, "By"):
- fld.Type = "uint64"
- case fld.Field == "CreatedAt":
- fld.Type = "time.Time"
- case strings.HasSuffix(fld.Field, "At"):
- fld.Type = "uint64"
- default:
- fld.Type = "string"
- }
-
- col, ok := def.RDBMS.FieldMap[fld.Field]
- if ok {
- col.storeTypeFieldDef = *fld
- } else {
- // In the most common case when field is NOT mapped,
- // just create new column def struct and split it in
- col = &storeTypeRdbmsColumnDef{storeTypeFieldDef: *fld}
- }
-
- // Make a copy for RDBMS columns
- col.alias = def.RDBMS.Alias
-
- if col.Column == "" {
- // Map common naming if needed
- switch {
- case fld.Field != "ID" && strings.HasSuffix(fld.Field, "ID"):
- col.Column = "rel_" + cc2underscore(fld.Field[:len(fld.Field)-2])
- default:
- col.Column = cc2underscore(fld.Field)
- }
- }
-
- def.RDBMS.Columns = append(def.RDBMS.Columns, col)
- }
-
- for i, l := range def.Lookups {
- if len(l.YamlFields) == 0 {
- return nil, fmt.Errorf("define at least one lookup field in lookup #%d", i)
- }
-
- // Checking if fields exist in the fields
- for _, f := range l.YamlFields {
- if def.Fields.Find(f) == nil {
- return nil, fmt.Errorf("undefined lookup field %q used", f)
-
- }
- }
-
- // Checking if filters exist in the fields
- for f, v := range l.Filter {
- if def.Fields.Find(f) == nil {
- return nil, fmt.Errorf("undefined lookup filter %q used", f)
- }
-
- if v == "" {
- // Set empty strings to nil
- l.Filter[f] = "nil"
- }
-
- }
-
- if l.Suffix == "" {
- l.Suffix = strings.Join(l.YamlFields, "")
- }
-
- l.fields = def.Fields
- l.columns = def.RDBMS.Columns
- }
-
- return def, nil
- }
-
- dd := make([]*storeDef, 0, len(mm))
- for _, m := range mm {
- def, err := procDef(m)
- if err != nil {
- return nil, fmt.Errorf("failed to process %s: %w", m, err)
- }
-
- dd = append(dd, def)
- }
-
- return dd, nil
-}
-
-// genStore generates all store related code, functions, interfaces...
-//
-// Templates can be found under assets/store*.tpl
-func genStore(tpl *template.Template, dd ...*storeDef) (err error) {
- var (
- // general interfaces
- tplInterfacesJoined = tpl.Lookup("store_interfaces_joined.gen.go.tpl")
- tplBase = tpl.Lookup("store_base.gen.go.tpl")
-
- // general tests
- tplTestAll = tpl.Lookup("store_test_all.gen.go.tpl")
-
- // @todo in-memory
-
- // rdbms specific
- tplRdbms = tpl.Lookup("store_rdbms.gen.go.tpl")
-
- // @todo redis
- // @todo mongodb
- // @todo elasticsearch
-
- dst string
- )
-
- // Output all test setup into a single file
- dst = path.Join(outputDir, "tests", "gen_test.go")
- if err = goTemplate(dst, tplTestAll, dd); err != nil {
- return
- }
-
- // Multi-file output
- for _, d := range dd {
- dst = path.Join(outputDir, "rdbms", d.Filename+".gen.go")
- if err = goTemplate(dst, tplRdbms, d); err != nil {
- return
- }
-
- dst = path.Join(outputDir, d.Filename+".gen.go")
- if err = goTemplate(dst, tplBase, d); err != nil {
- return
- }
- }
-
- if err = genStoreInterfacesJoined(tplInterfacesJoined, path.Join("store", "interfaces.gen.go"), path.Base(dst), dd); err != nil {
- return
- }
-
- return nil
-}
-
-func genStoreInterfaces(tpl *template.Template, dst, pkg string, d *storeDef) error {
- d.Package = pkg
- return goTemplate(dst, tpl, d)
-}
-
-func genStoreInterfacesJoined(tpl *template.Template, dst, pkg string, dd []*storeDef) error {
- payload := map[string]interface{}{
- "Package": pkg,
- "Definitions": dd,
- "Import": collectStoreDefImports("", dd...),
- }
-
- return goTemplate(dst, tpl, payload)
-}
-
-func collectStoreDefImports(basePkg string, dd ...*storeDef) []string {
- ii := make([]string, 0, len(dd))
- for _, d := range dd {
- for _, i := range d.Import {
- if !slice.HasString(ii, i) && (basePkg == "" || !strings.HasSuffix(i, basePkg)) {
- ii = append(ii, i)
- }
- }
- }
-
- return ii
-}
-
-// Exported returns true if at least one of the functions is exported
-func (d storeDef) Exported() bool {
- return d.Search.Export ||
- d.Create.Export ||
- d.Update.Export ||
- d.Upsert.Export ||
- d.Delete.Export
-}
-
-func (ff storeTypeFieldSetDef) Find(name string) *storeTypeFieldDef {
- for _, f := range ff {
- if f.Field == name {
- return f
- }
- }
-
- return nil
-}
-
-func (ff storeTypeFieldSetDef) HasPrimaryKey() bool {
- for _, f := range ff {
- if f.IsPrimaryKey {
- return true
- }
- }
-
- return false
-}
-
-func (ff storeTypeFieldSetDef) PrimaryKeyFields() storeTypeFieldSetDef {
- pkSet := storeTypeFieldSetDef{}
- for _, f := range ff {
- if f.IsPrimaryKey {
- pkSet = append(pkSet, f)
- }
- }
-
- return pkSet
-}
-
-func (f storeTypeFieldDef) Arg() string {
- if f.Field == "ID" {
- return f.Field
- }
-
- return strings.ToLower(f.Field[:1]) + f.Field[1:]
-}
-
-func (f storeTypeRdbmsColumnDef) AliasedColumn() string {
- return fmt.Sprintf("%s.%s", f.alias, f.Column)
-}
-
-func (ff storeTypeRdbmsColumnSetDef) Find(name string) *storeTypeRdbmsColumnDef {
- for _, f := range ff {
- if f.Field == name {
- return f
- }
- }
-
- return nil
-}
-
-func (ff storeTypeRdbmsColumnSetDef) HasPrimaryKey() bool {
- for _, f := range ff {
- if f.IsPrimaryKey {
- return true
- }
- }
-
- return false
-}
-
-func (ff storeTypeRdbmsColumnSetDef) PrimaryKeyFields() storeTypeRdbmsColumnSetDef {
- pkSet := storeTypeRdbmsColumnSetDef{}
- for _, f := range ff {
- if f.IsPrimaryKey {
- pkSet = append(pkSet, f)
- }
- }
-
- return pkSet
-}
-
-// UnmarshalYAML makes sure that export flag is set to true when not explicity disabled
-func (d *storeTypeLookups) UnmarshalYAML(n *yaml.Node) error {
- type dAux storeTypeLookups
- var aux = (*dAux)(d)
- aux.Export = true
-
- return n.Decode(aux)
-}
-
-func (d *storeTypeLookups) Fields() storeTypeFieldSetDef {
- var cc = make([]*storeTypeFieldDef, 0, len(d.columns))
- for _, field := range d.YamlFields {
- cc = append(cc, d.fields.Find(field))
- }
-
- return cc
-}
-
-func (d *storeTypeLookups) RDBMSColumns() storeTypeRdbmsColumnSetDef {
- var cc = make([]*storeTypeRdbmsColumnDef, 0, len(d.columns))
- for _, field := range d.YamlFields {
- cc = append(cc, d.columns.Find(field))
- }
-
- return cc
-}
diff --git a/pkg/discovery/service.go b/pkg/discovery/service.go
index dda9d29e0..66c08cf99 100644
--- a/pkg/discovery/service.go
+++ b/pkg/discovery/service.go
@@ -3,12 +3,13 @@ package discovery
import (
"context"
"fmt"
+ "sync"
+ "time"
+
"github.com/cortezaproject/corteza-server/pkg/discovery/types"
"github.com/cortezaproject/corteza-server/pkg/eventbus"
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/pkg/options"
- "sync"
- "time"
"go.uber.org/zap"
)
@@ -28,7 +29,7 @@ type (
}
resourceActivityLogStore interface {
- CreateResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) error
+ CreateResourceActivity(ctx context.Context, rr ...*types.ResourceActivity) error
}
eventbusRegistry interface {
@@ -96,7 +97,7 @@ func (svc *service) InitResourceActivityLog(ctx context.Context, resourceType []
return err
}
- err = svc.store.CreateResourceActivityLog(ctx, a)
+ err = svc.store.CreateResourceActivity(ctx, a)
if err != nil {
svc.logger.With(zap.Error(err)).Error("could not record activity event")
return err
@@ -130,7 +131,7 @@ func (svc *service) Record(ctx context.Context, a *types.ResourceActivity) {
// discovery to fail...
ctx = context.Background()
- if err := svc.store.CreateResourceActivityLog(ctx, a); err != nil {
+ if err := svc.store.CreateResourceActivity(ctx, a); err != nil {
svc.logger.With(zap.Error(err)).Error("could not record activity event")
}
}
diff --git a/pkg/discovery/types/types.go b/pkg/discovery/types/types.go
index 068cec47e..007408f59 100644
--- a/pkg/discovery/types/types.go
+++ b/pkg/discovery/types/types.go
@@ -3,12 +3,13 @@ package types
import (
"encoding/json"
"fmt"
+ "time"
+
composeTypes "github.com/cortezaproject/corteza-server/compose/types"
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/cortezaproject/corteza-server/pkg/id"
systemTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/jmoiron/sqlx/types"
- "time"
)
type (
@@ -39,8 +40,6 @@ type (
FromTimestamp *time.Time `json:"from"`
ToTimestamp *time.Time `json:"to"`
- Limit uint `json:"limit"`
-
// Check fn is called by store backend for each resource found function can
// modify the activity and return false if store should not return it
//
diff --git a/pkg/envoy/store/compose.go b/pkg/envoy/store/compose.go
index aef7202c7..1881ec2ee 100644
--- a/pkg/envoy/store/compose.go
+++ b/pkg/envoy/store/compose.go
@@ -252,7 +252,7 @@ func (d *composeDecoder) decodeComposeRecord(ctx context.Context, s store.Storer
var err error
for {
- rr, fn, err = s.SearchComposeRecords(ctx, mod, types.RecordFilter(aux))
+ rr, fn, err = store.SearchComposeRecords(ctx, s, mod, types.RecordFilter(aux))
if err != nil {
return err
}
diff --git a/pkg/envoy/store/setting_marshal.go b/pkg/envoy/store/setting_marshal.go
index 3edbd8529..1acc9ca46 100644
--- a/pkg/envoy/store/setting_marshal.go
+++ b/pkg/envoy/store/setting_marshal.go
@@ -25,7 +25,7 @@ func (n *setting) Prepare(ctx context.Context, pl *payload) (err error) {
// Init global state
if gSettings == nil {
gSettings = make(map[string]bool)
- ss, _, err := store.SearchSettings(ctx, pl.s, types.SettingsFilter{})
+ ss, _, err := store.SearchSettingValues(ctx, pl.s, types.SettingsFilter{})
if err != store.ErrNotFound && err != nil {
return err
}
@@ -66,7 +66,7 @@ func (n *setting) Encode(ctx context.Context, pl *payload) (err error) {
}
if _, exists := gSettings[res.Name]; !exists {
- return store.CreateSetting(ctx, pl.s, res)
+ return store.CreateSettingValue(ctx, pl.s, res)
}
// On existing setting, replace/merge right basically overwrites the existing value;
@@ -74,7 +74,7 @@ func (n *setting) Encode(ctx context.Context, pl *payload) (err error) {
switch n.cfg.OnExisting {
case resource.Replace,
resource.MergeRight:
- return store.UpdateSetting(ctx, pl.s, res)
+ return store.UpdateSettingValue(ctx, pl.s, res)
}
return nil
diff --git a/pkg/envoy/store/system.go b/pkg/envoy/store/system.go
index 9edcbdc2b..ce1af54a8 100644
--- a/pkg/envoy/store/system.go
+++ b/pkg/envoy/store/system.go
@@ -340,7 +340,7 @@ func (d *systemDecoder) decodeSettings(ctx context.Context, s store.Storer, ff [
aux := *f
for {
- nn, _, err = s.SearchSettings(ctx, types.SettingsFilter(aux))
+ nn, _, err = store.SearchSettingValues(ctx, s, types.SettingsFilter(aux))
if err != nil {
return &auxRsp{
err: err,
diff --git a/pkg/filter/state.go b/pkg/filter/state.go
index 9f5d7cfcd..fe264709c 100644
--- a/pkg/filter/state.go
+++ b/pkg/filter/state.go
@@ -1,7 +1,6 @@
package filter
import (
- "github.com/Masterminds/squirrel"
"strconv"
)
@@ -26,36 +25,3 @@ const (
func (s State) String() string {
return strconv.Itoa(int(s))
}
-
-// squirrel.SelectBuilder
-func StateCondition(q squirrel.SelectBuilder, field string, fs State) squirrel.SelectBuilder {
- switch fs {
- case StateExclusive:
- // only null values
- return q.Where(squirrel.NotEq{field: nil})
-
- case StateInclusive:
- // no filter
- return q
-
- default:
- // exclude all non-null values
- return q.Where(squirrel.Eq{field: nil})
- }
-}
-
-// squirrel.SelectBuilder
-func StateConditionNegBool(q squirrel.SelectBuilder, field string, fs State) squirrel.SelectBuilder {
- switch fs {
- case StateExcluded:
- // only true
- return q.Where(squirrel.Eq{field: true})
-
- case StateExclusive:
- // only false
- return q.Where(squirrel.Eq{field: false})
-
- default:
- return q
- }
-}
diff --git a/pkg/flag/types/type.go b/pkg/flag/types/type.go
index 65c8433d8..e7f1a0f0d 100644
--- a/pkg/flag/types/type.go
+++ b/pkg/flag/types/type.go
@@ -21,5 +21,6 @@ type (
ResourceID []uint64
OwnedBy []uint64
Name []string
+ Limit uint
}
)
diff --git a/pkg/label/types/type.go b/pkg/label/types/type.go
index d6fceeb5c..f1472c07d 100644
--- a/pkg/label/types/type.go
+++ b/pkg/label/types/type.go
@@ -16,6 +16,7 @@ type (
Kind string
ResourceID []uint64
Filter map[string]string
+ Limit uint
}
)
diff --git a/pkg/provision/auth.go b/pkg/provision/auth.go
index f43147635..5545eb3c4 100644
--- a/pkg/provision/auth.go
+++ b/pkg/provision/auth.go
@@ -33,10 +33,10 @@ func emailSettings(ctx context.Context, s store.Storer) error {
return s.Tx(ctx, func(ctx context.Context, s store.Storer) error {
return ss.Walk(func(setting *types.SettingValue) error {
- _, err := store.LookupSettingByNameOwnedBy(ctx, s, setting.Name, 0)
+ _, err := store.LookupSettingValueByNameOwnedBy(ctx, s, setting.Name, 0)
if errors.IsNotFound(err) {
setting.UpdatedAt = *now()
- return store.CreateSetting(ctx, s, setting)
+ return store.CreateSettingValue(ctx, s, setting)
}
return err
diff --git a/pkg/provision/migrations_202103_templates.go b/pkg/provision/migrations_202103_templates.go
index 7f077ca41..f4eb73b73 100644
--- a/pkg/provision/migrations_202103_templates.go
+++ b/pkg/provision/migrations_202103_templates.go
@@ -63,7 +63,7 @@ func migrateEmailTemplates(ctx context.Context, log *zap.Logger, s store.Storer)
return store.Tx(ctx, s, func(ctx context.Context, s store.Storer) error {
for name, tmpl := range m {
- sval, err := store.LookupSettingByNameOwnedBy(ctx, s, name, 0)
+ sval, err := store.LookupSettingValueByNameOwnedBy(ctx, s, name, 0)
if errors.IsNotFound(err) {
// setting not found, that's ok, see the next one
continue
@@ -97,7 +97,7 @@ func migrateEmailTemplates(ctx context.Context, log *zap.Logger, s store.Storer)
// Go over all settings again and remove them
for name := range m {
- if err := store.DeleteSettingByNameOwnedBy(ctx, s, name, 0); err != nil {
+ if err := store.DeleteSettingValueByNameOwnedBy(ctx, s, name, 0); err != nil {
return err
}
}
diff --git a/pkg/provision/migrations_202109_roles.go b/pkg/provision/migrations_202109_roles.go
index f66fdb8f4..bdeb8d7b1 100644
--- a/pkg/provision/migrations_202109_roles.go
+++ b/pkg/provision/migrations_202109_roles.go
@@ -56,12 +56,12 @@ func migratePre202109Roles(ctx context.Context, log *zap.Logger, s store.Storer)
}
// transfer all rbac rules
- if err = s.TransferRoleMembers(ctx, obsoleteAdminsID, m["admins"].ID); err != nil {
+ if err = store.TransferRoleMembers(ctx, s, obsoleteAdminsID, m["admins"].ID); err != nil {
return
}
// transfer all rbac rules
- if err = s.TransferRbacRules(ctx, obsoleteAdminsID, m["admins"].ID); err != nil {
+ if err = store.TransferRbacRules(ctx, s, obsoleteAdminsID, m["admins"].ID); err != nil {
return
}
}
diff --git a/pkg/provision/migrations_202109_settings_cleanup.go b/pkg/provision/migrations_202109_settings_cleanup.go
index 9b1cc980f..18d053356 100644
--- a/pkg/provision/migrations_202109_settings_cleanup.go
+++ b/pkg/provision/migrations_202109_settings_cleanup.go
@@ -26,7 +26,7 @@ func cleanupPre202109Settings(ctx context.Context, log *zap.Logger, s store.Stor
}
for _, name := range names {
- if err = store.DeleteSettingByNameOwnedBy(ctx, s, name, 0); err != nil {
+ if err = store.DeleteSettingValueByNameOwnedBy(ctx, s, name, 0); err != nil {
return
}
}
diff --git a/pkg/provision/oidc.go b/pkg/provision/oidc.go
index 5a0968bd9..5191fc22e 100644
--- a/pkg/provision/oidc.go
+++ b/pkg/provision/oidc.go
@@ -16,7 +16,7 @@ import (
// Provisions OIDC providers from PROVISION_OIDC_PROVIDER env variable
//
// Env variable should contains space delimited pairs of providers ( ....)
-func oidcAutoDiscovery(ctx context.Context, log *zap.Logger, s store.Settings, opt options.AuthOpt) (err error) {
+func oidcAutoDiscovery(ctx context.Context, log *zap.Logger, s store.SettingValues, opt options.AuthOpt) (err error) {
var provider = strings.TrimSpace(options.EnvString("PROVISION_OIDC_PROVIDER", ""))
log.Debug("OIDC auto discovery provision",
@@ -73,7 +73,7 @@ func oidcAutoDiscovery(ctx context.Context, log *zap.Logger, s store.Settings, o
return
}
-func authAddExternals(ctx context.Context, log *zap.Logger, s store.Settings) (err error) {
+func authAddExternals(ctx context.Context, log *zap.Logger, s store.SettingValues) (err error) {
var (
kinds = []string{
"github",
diff --git a/pkg/ql/ast_nodes.go b/pkg/ql/ast_nodes.go
index 2a02ba3f9..062dfb212 100644
--- a/pkg/ql/ast_nodes.go
+++ b/pkg/ql/ast_nodes.go
@@ -3,16 +3,14 @@ package ql
import (
"fmt"
"strings"
-
- "github.com/Masterminds/squirrel"
)
// SelectStatement represents a SQL SELECT statement.
type (
ASTNode interface {
fmt.Stringer
- squirrel.Sqlizer
+ ToSQL() (string, []interface{}, error)
Validate() error
}
diff --git a/pkg/ql/ast_parser_test.go b/pkg/ql/ast_parser_test.go
index 61f49c004..434386360 100644
--- a/pkg/ql/ast_parser_test.go
+++ b/pkg/ql/ast_parser_test.go
@@ -2,9 +2,10 @@ package ql
import (
"fmt"
- "github.com/stretchr/testify/require"
"reflect"
"testing"
+
+ "github.com/stretchr/testify/require"
)
// Ensure the parser can parse strings into Statement ASTs.
@@ -278,7 +279,7 @@ func TestAstParser_Parser(t *testing.T) {
"test case: %d. %s\n"+
" expected: %#v\n"+
" got: %#v\n\n", i, test.in, test.tree, tree)
- } else if sql, args, err := tree.ToSql(); err != nil {
+ } else if sql, args, err := tree.ToSQL(); err != nil {
t.Fatal(err)
} else if test.sql != "" && sql != test.sql {
t.Errorf("sql does not match:\n"+
diff --git a/pkg/ql/squirrel.go b/pkg/ql/squirrel.go
index df852e229..c453c0cf3 100644
--- a/pkg/ql/squirrel.go
+++ b/pkg/ql/squirrel.go
@@ -1,21 +1,16 @@
package ql
-// Squirrel Sqlizer interface implementators for all ast node types
-// This helps us to throw columns into squirrel's select builder
-
import (
"fmt"
-
- "github.com/Masterminds/squirrel"
)
-// ToSql concatenates outputs and arguments from all nodes
-func (nn ASTNodes) ToSql() (out string, args []interface{}, err error) {
+// ToSQL concatenates outputs and arguments from all nodes
+func (nn ASTNodes) ToSQL() (out string, args []interface{}, err error) {
var _out string
var _args []interface{}
for _, s := range nn {
- if _out, _args, err = s.ToSql(); err != nil {
+ if _out, _args, err = s.ToSQL(); err != nil {
return
} else {
if _, ok := s.(ASTNodes); ok {
@@ -33,13 +28,13 @@ func (nn ASTNodes) ToSql() (out string, args []interface{}, err error) {
return out, args, err
}
-// ToSql concatenates outputs and arguments from all nodes, comma delimited
-func (nn ASTSet) ToSql() (out string, args []interface{}, err error) {
+// ToSQL concatenates outputs and arguments from all nodes, comma delimited
+func (nn ASTSet) ToSQL() (out string, args []interface{}, err error) {
var _out string
var _args []interface{}
for i, s := range nn {
- if _out, _args, err = s.ToSql(); err != nil {
+ if _out, _args, err = s.ToSQL(); err != nil {
return
} else {
if i > 0 {
@@ -55,24 +50,25 @@ func (nn ASTSet) ToSql() (out string, args []interface{}, err error) {
return out, args, err
}
-// ToSql returns column alias expression or output of underlying expression's ToSql()
-func (n Column) ToSql() (string, []interface{}, error) {
+// ToSQL returns column alias expression or output of underlying expression's ToSQL()
+func (n Column) ToSQL() (string, []interface{}, error) {
if n.Alias != "" {
- return squirrel.Alias(n.Expr, n.Alias).ToSql()
+ panic("@todo reimplement this")
+ //return squirrel.Alias(n.Expr, n.Alias).ToSQL()
} else {
- return n.Expr.ToSql()
+ return n.Expr.ToSQL()
}
}
-func (n Ident) ToSql() (string, []interface{}, error) {
+func (n Ident) ToSQL() (string, []interface{}, error) {
return n.Value, n.Args, nil
}
-func (n LNull) ToSql() (string, []interface{}, error) {
+func (n LNull) ToSQL() (string, []interface{}, error) {
return "NULL", nil, nil
}
-func (n LBoolean) ToSql() (string, []interface{}, error) {
+func (n LBoolean) ToSQL() (string, []interface{}, error) {
if n.Value {
return "TRUE", nil, nil
} else {
@@ -80,8 +76,8 @@ func (n LBoolean) ToSql() (string, []interface{}, error) {
}
}
-func (n Function) ToSql() (string, []interface{}, error) {
- if paramsSql, args, err := n.Arguments.ToSql(); err != nil {
+func (n Function) ToSQL() (string, []interface{}, error) {
+ if paramsSql, args, err := n.Arguments.ToSQL(); err != nil {
return "", nil, err
} else {
return fmt.Sprintf("%s(%s)", n.Name, paramsSql), args, nil
@@ -89,15 +85,15 @@ func (n Function) ToSql() (string, []interface{}, error) {
}
-func (n Keyword) ToSql() (string, []interface{}, error) {
+func (n Keyword) ToSQL() (string, []interface{}, error) {
return n.Keyword, nil, nil
}
-func (n Interval) ToSql() (string, []interface{}, error) {
+func (n Interval) ToSQL() (string, []interface{}, error) {
return fmt.Sprintf("INTERVAL ? %s", n.Unit), []interface{}{n.Value}, nil
}
-func (n Operator) ToSql() (string, []interface{}, error) {
+func (n Operator) ToSQL() (string, []interface{}, error) {
var op = n.Kind
switch n.Kind {
@@ -109,20 +105,20 @@ func (n Operator) ToSql() (string, []interface{}, error) {
return " " + op + " ", nil, nil
}
-func (n LString) ToSql() (string, []interface{}, error) {
+func (n LString) ToSQL() (string, []interface{}, error) {
return "?", []interface{}{n.Value}, nil
}
-func (n LNumber) ToSql() (string, []interface{}, error) {
+func (n LNumber) ToSQL() (string, []interface{}, error) {
return n.Value, nil, nil
}
-func (n NodeF) ToSql() (string, []interface{}, error) {
+func (n NodeF) ToSQL() (string, []interface{}, error) {
var (
// used for sprintf to complete the base expression
fArgs []interface{}
- // collection of al args from ToSql() that
+ // collection of al args from ToSQL() that
// are passed on to the caller
adtArgs []interface{}
)
@@ -139,7 +135,7 @@ func (n NodeF) ToSql() (string, []interface{}, error) {
}
}
- if fa, aa, err := s.ToSql(); err != nil {
+ if fa, aa, err := s.ToSQL(); err != nil {
return "", nil, err
} else {
fArgs = append(fArgs, fa)
diff --git a/pkg/rbac/service.go b/pkg/rbac/service.go
index f5172fc18..56bdf25fc 100644
--- a/pkg/rbac/service.go
+++ b/pkg/rbac/service.go
@@ -29,7 +29,9 @@ type (
}
// RuleFilter is a dummy struct to satisfy store codegen
- RuleFilter struct{}
+ RuleFilter struct {
+ Limit uint
+ }
RoleSettings struct {
Bypass []uint64
diff --git a/store/Makefile b/store/Makefile
deleted file mode 100644
index 7df8dd62f..000000000
--- a/store/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-
-include ../Makefile.inc
-
-GOTOOL ?= go tool
-GOTEST ?= go test
-GOFLAGS ?= -mod=vendor
-
-COVER_MODE ?= count
-COVER_PROFILE ?= .cover.out
-COVER_FLAGS ?= -covermode=$(COVER_MODE) -coverprofile=$(COVER_PROFILE)
-
-# Run go test cmd with flags, eg:
-# $> TEST_FLAGS="-v" make test
-# $> TEST_FLAGS="-v -run 'Test_Store/.+/ComposeCharts'" make test
-TEST_FLAGS ?=
-
-test.store:
- $(GOTEST) $(TEST_FLAGS) ./tests/...
-
-test.cover.store:
- @ $(GOTEST) $(TEST_FLAGS) -coverprofile=$(COVER_PROFILE) -coverpkg=./... ./tests/...
- @ $(GOTOOL) cover -html=$(COVER_PROFILE)
- @ $(GOTOOL) cover
- @ rm $(COVER_PROFILE)
-
-watch.test.%: $(FSWATCH)
- ( make test.$* || exit 0 ) && ( $(FSWATCH) -o . | xargs -n1 -I{} make test.$* )
-
-watch.codegen:
- @ make -C ../ $@
-
-codegen:
- @ make -C ../ $@
diff --git a/store/README.md b/store/README.md
deleted file mode 100644
index 99649576d..000000000
--- a/store/README.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Corteza storage layer
-
-Provides unified storage for Corteza with composable and interchangeable backends.
-Backends can be any RDBMS, Key-Value, NoSQL, FS, Memory.
-
-## FAQ
-
-* Why are we changing create/update function signature (input struct is no longer returned)?
-** Because store functions are no longer manipulating the input.
-
-* Why naming inconsistency between search/lookup and create/update/...?
-** To ensure function names sound more natural
-
-* Why changing find prefix to search/lookup?
-** To be consistent with actions
-
-* Why do we use custom mapping (and not db:... tag on struct)?
- Separation of concerns
-** consistency with store backends that do not support db tags
-** de-cluttering types* namespace
-
-## Testing
-
-Running store tests:
-```shell script
-make test.store
-```
-
-See [Makefile](Makefile) for details
-
-## Known issues
-
-SQLite, transactions & locking::
-Transactions in SQLite are explicitly disabled due to issues
-with locking (see `sqlite/sqlite.go`, line with `cfg.TxDisabled # true`)
-
-Until this is resolved, SQLite storage backend should not be used
-in production environment.
-
-We're still keeping and maintaining it to provide the simplest and most performant backend for (service) unit testing to avoid overly complex mocking of storage.
-This will likely change when we have support for built-in in-memory storage (MEMORY_DSN)
diff --git a/store/actionlog.gen.go b/store/actionlog.gen.go
deleted file mode 100644
index dcc5ad2d3..000000000
--- a/store/actionlog.gen.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/actionlog.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/pkg/actionlog"
-)
-
-type (
- Actionlogs interface {
- SearchActionlogs(ctx context.Context, f actionlog.Filter) (actionlog.ActionSet, actionlog.Filter, error)
-
- CreateActionlog(ctx context.Context, rr ...*actionlog.Action) error
-
- TruncateActionlogs(ctx context.Context) error
- }
-)
-
-var _ *actionlog.Action
-var _ context.Context
-
-// SearchActionlogs returns all matching Actionlogs from store
-func SearchActionlogs(ctx context.Context, s Actionlogs, f actionlog.Filter) (actionlog.ActionSet, actionlog.Filter, error) {
- return s.SearchActionlogs(ctx, f)
-}
-
-// CreateActionlog creates one or more Actionlogs in store
-func CreateActionlog(ctx context.Context, s Actionlogs, rr ...*actionlog.Action) error {
- return s.CreateActionlog(ctx, rr...)
-}
-
-// TruncateActionlogs Deletes all Actionlogs from store
-func TruncateActionlogs(ctx context.Context, s Actionlogs) error {
- return s.TruncateActionlogs(ctx)
-}
diff --git a/store/actionlog.yaml b/store/actionlog.yaml
deleted file mode 100644
index 165b4d97a..000000000
--- a/store/actionlog.yaml
+++ /dev/null
@@ -1,47 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/pkg/actionlog
-
-
-types:
- package: actionlog
- type: actionlog.Action
- filterType: actionlog.Filter
-
-fields:
- - { field: ID, sortable: true, sortDescending: true }
- - { field: Timestamp, type: "time.Time" }
- - { field: RequestOrigin }
- - { field: RequestID }
- - { field: ActorIPAddr }
- - { field: ActorID }
- - { field: Resource }
- - { field: Action }
- - { field: Error }
- - { field: Severity, type: "actionlog.Severity" }
- - { field: Description }
- - { field: Meta, type: "actionlog.UserMeta" }
-
-rdbms:
- alias: alg
- table: actionlog
- customFilterConverter: true
- customRowScanner: true
- customEncoder: true
- mapFields:
- Timestamp: { column: ts }
- RequestID: { column: request_id }
- ActorID: { column: actor_id }
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
-
-update:
- enable: false
-
-upsert:
- enable: false
-
-delete:
- enable: false
diff --git a/store/adapters/rdbms/aux_types.gen.go b/store/adapters/rdbms/aux_types.gen.go
new file mode 100644
index 000000000..656c10b71
--- /dev/null
+++ b/store/adapters/rdbms/aux_types.gen.go
@@ -0,0 +1,2688 @@
+package rdbms
+
+// This file is auto-generated.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+
+import (
+ automationType "github.com/cortezaproject/corteza-server/automation/types"
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ federationType "github.com/cortezaproject/corteza-server/federation/types"
+ actionlogType "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ discoveryType "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ "github.com/cortezaproject/corteza-server/pkg/expr"
+ flagType "github.com/cortezaproject/corteza-server/pkg/flag/types"
+ labelsType "github.com/cortezaproject/corteza-server/pkg/label/types"
+ rbacType "github.com/cortezaproject/corteza-server/pkg/rbac"
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "time"
+)
+
+type (
+
+ // auxActionlog is an auxiliary structure used for transporting to/from RDBMS store
+ auxActionlog struct {
+ ID uint64 `db:"id"`
+ Timestamp time.Time `db:"timestamp"`
+ RequestOrigin string `db:"request_origin"`
+ RequestID string `db:"request_id"`
+ ActorIPAddr string `db:"actor_ip_addr"`
+ ActorID uint64 `db:"actor_id"`
+ Resource string `db:"resource"`
+ Action string `db:"action"`
+ Error string `db:"error"`
+ Severity actionlogType.Severity `db:"severity"`
+ Description string `db:"description"`
+ Meta actionlogType.Meta `db:"meta"`
+ }
+
+ // auxApigwFilter is an auxiliary structure used for transporting to/from RDBMS store
+ auxApigwFilter struct {
+ ID uint64 `db:"id"`
+ Route uint64 `db:"route"`
+ Weight uint64 `db:"weight"`
+ Ref string `db:"ref"`
+ Kind string `db:"kind"`
+ Enabled bool `db:"enabled"`
+ Params systemType.ApigwFilterParams `db:"params"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxApigwRoute is an auxiliary structure used for transporting to/from RDBMS store
+ auxApigwRoute struct {
+ ID uint64 `db:"id"`
+ Endpoint string `db:"endpoint"`
+ Method string `db:"method"`
+ Enabled bool `db:"enabled"`
+ Group uint64 `db:"group"`
+ Meta systemType.ApigwRouteMeta `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxApplication is an auxiliary structure used for transporting to/from RDBMS store
+ auxApplication struct {
+ ID uint64 `db:"id"`
+ Name string `db:"name"`
+ OwnerID uint64 `db:"owner_id"`
+ Enabled bool `db:"enabled"`
+ Weight int `db:"weight"`
+ Unify *systemType.ApplicationUnify `db:"unify"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxAttachment is an auxiliary structure used for transporting to/from RDBMS store
+ auxAttachment struct {
+ ID uint64 `db:"id"`
+ OwnerID uint64 `db:"owner_id"`
+ Kind string `db:"kind"`
+ Url string `db:"url"`
+ PreviewUrl string `db:"preview_url"`
+ Name string `db:"name"`
+ Meta systemType.AttachmentMeta `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxAuthClient is an auxiliary structure used for transporting to/from RDBMS store
+ auxAuthClient struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Meta *systemType.AuthClientMeta `db:"meta"`
+ Secret string `db:"secret"`
+ Scope string `db:"scope"`
+ ValidGrant string `db:"valid_grant"`
+ RedirectURI string `db:"redirect_uri"`
+ Trusted bool `db:"trusted"`
+ Enabled bool `db:"enabled"`
+ ValidFrom *time.Time `db:"valid_from"`
+ ExpiresAt *time.Time `db:"expires_at"`
+ Security *systemType.AuthClientSecurity `db:"security"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ OwnedBy uint64 `db:"owned_by"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxAuthConfirmedClient is an auxiliary structure used for transporting to/from RDBMS store
+ auxAuthConfirmedClient struct {
+ UserID uint64 `db:"user_id"`
+ ClientID uint64 `db:"client_id"`
+ ConfirmedAt time.Time `db:"confirmed_at"`
+ }
+
+ // auxAuthOa2token is an auxiliary structure used for transporting to/from RDBMS store
+ auxAuthOa2token struct {
+ ID uint64 `db:"id"`
+ Code string `db:"code"`
+ Access string `db:"access"`
+ Refresh string `db:"refresh"`
+ ExpiresAt time.Time `db:"expires_at"`
+ CreatedAt time.Time `db:"created_at"`
+ Data rawJson `db:"data"`
+ ClientID uint64 `db:"client_id"`
+ UserID uint64 `db:"user_id"`
+ RemoteAddr string `db:"remote_addr"`
+ UserAgent string `db:"user_agent"`
+ }
+
+ // auxAuthSession is an auxiliary structure used for transporting to/from RDBMS store
+ auxAuthSession struct {
+ ID string `db:"id"`
+ Data []byte `db:"data"`
+ UserID uint64 `db:"user_id"`
+ ExpiresAt time.Time `db:"expires_at"`
+ CreatedAt time.Time `db:"created_at"`
+ RemoteAddr string `db:"remote_addr"`
+ UserAgent string `db:"user_agent"`
+ }
+
+ // auxAutomationSession is an auxiliary structure used for transporting to/from RDBMS store
+ auxAutomationSession struct {
+ ID uint64 `db:"id"`
+ WorkflowID uint64 `db:"workflow_id"`
+ EventType string `db:"event_type"`
+ ResourceType string `db:"resource_type"`
+ Status automationType.SessionStatus `db:"status"`
+ Input *expr.Vars `db:"input"`
+ Output *expr.Vars `db:"output"`
+ Stacktrace automationType.Stacktrace `db:"stacktrace"`
+ CreatedBy uint64 `db:"created_by"`
+ CreatedAt time.Time `db:"created_at"`
+ PurgeAt *time.Time `db:"purge_at"`
+ CompletedAt *time.Time `db:"completed_at"`
+ SuspendedAt *time.Time `db:"suspended_at"`
+ Error string `db:"error"`
+ }
+
+ // auxAutomationTrigger is an auxiliary structure used for transporting to/from RDBMS store
+ auxAutomationTrigger struct {
+ ID uint64 `db:"id"`
+ WorkflowID uint64 `db:"workflow_id"`
+ StepID uint64 `db:"step_id"`
+ Enabled bool `db:"enabled"`
+ ResourceType string `db:"resource_type"`
+ EventType string `db:"event_type"`
+ Meta *automationType.TriggerMeta `db:"meta"`
+ Constraints automationType.TriggerConstraintSet `db:"constraints"`
+ Input *expr.Vars `db:"input"`
+ OwnedBy uint64 `db:"owned_by"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxAutomationWorkflow is an auxiliary structure used for transporting to/from RDBMS store
+ auxAutomationWorkflow struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Meta *automationType.WorkflowMeta `db:"meta"`
+ Enabled bool `db:"enabled"`
+ Trace bool `db:"trace"`
+ KeepSessions int `db:"keep_sessions"`
+ Scope *expr.Vars `db:"scope"`
+ Steps automationType.WorkflowStepSet `db:"steps"`
+ Paths automationType.WorkflowPathSet `db:"paths"`
+ Issues automationType.WorkflowIssueSet `db:"issues"`
+ RunAs uint64 `db:"run_as"`
+ OwnedBy uint64 `db:"owned_by"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxComposeAttachment is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeAttachment struct {
+ ID uint64 `db:"id"`
+ OwnerID uint64 `db:"owner_id"`
+ NamespaceID uint64 `db:"namespace_id"`
+ Kind string `db:"kind"`
+ Url string `db:"url"`
+ PreviewUrl string `db:"preview_url"`
+ Name string `db:"name"`
+ Meta composeType.AttachmentMeta `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxComposeChart is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeChart struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Name string `db:"name"`
+ Config composeType.ChartConfig `db:"config"`
+ NamespaceID uint64 `db:"namespace_id"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxComposeModule is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeModule struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Meta rawJson `db:"meta"`
+ NamespaceID uint64 `db:"namespace_id"`
+ Name string `db:"name"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxComposeModuleField is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeModuleField struct {
+ ID uint64 `db:"id"`
+ ModuleID uint64 `db:"module_id"`
+ Place int `db:"place"`
+ Kind string `db:"kind"`
+ Name string `db:"name"`
+ Label string `db:"label"`
+ Options composeType.ModuleFieldOptions `db:"options"`
+ Private bool `db:"private"`
+ Required bool `db:"required"`
+ Visible bool `db:"visible"`
+ Multi bool `db:"multi"`
+ DefaultValue composeType.RecordValueSet `db:"default_value"`
+ Expressions composeType.ModuleFieldExpr `db:"expressions"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxComposeNamespace is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeNamespace struct {
+ ID uint64 `db:"id"`
+ Slug string `db:"slug"`
+ Enabled bool `db:"enabled"`
+ Meta composeType.NamespaceMeta `db:"meta"`
+ Name string `db:"name"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxComposePage is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposePage struct {
+ ID uint64 `db:"id"`
+ SelfID uint64 `db:"self_id"`
+ ModuleID uint64 `db:"module_id"`
+ NamespaceID uint64 `db:"namespace_id"`
+ Handle string `db:"handle"`
+ Config composeType.PageConfig `db:"config"`
+ Blocks composeType.PageBlocks `db:"blocks"`
+ Visible bool `db:"visible"`
+ Weight int `db:"weight"`
+ Title string `db:"title"`
+ Description string `db:"description"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxComposeRecord is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeRecord struct {
+ ID uint64 `db:"id"`
+ ModuleID uint64 `db:"module_id"`
+ NamespaceID uint64 `db:"namespace_id"`
+ OwnedBy uint64 `db:"owned_by"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxComposeRecordValue is an auxiliary structure used for transporting to/from RDBMS store
+ auxComposeRecordValue struct {
+ RecordID uint64 `db:"record_id"`
+ Name string `db:"name"`
+ Place uint `db:"place"`
+ Ref uint64 `db:"ref"`
+ Value string `db:"value"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxCredential is an auxiliary structure used for transporting to/from RDBMS store
+ auxCredential struct {
+ ID uint64 `db:"id"`
+ OwnerID uint64 `db:"owner_id"`
+ Kind string `db:"kind"`
+ Label string `db:"label"`
+ Credentials string `db:"credentials"`
+ Meta rawJson `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ LastUsedAt *time.Time `db:"last_used_at"`
+ ExpiresAt *time.Time `db:"expires_at"`
+ }
+
+ // auxFederationExposedModule is an auxiliary structure used for transporting to/from RDBMS store
+ auxFederationExposedModule struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Name string `db:"name"`
+ NodeID uint64 `db:"node_id"`
+ ComposeModuleID uint64 `db:"compose_module_id"`
+ ComposeNamespaceID uint64 `db:"compose_namespace_id"`
+ Fields federationType.ModuleFieldSet `db:"fields"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxFederationModuleMapping is an auxiliary structure used for transporting to/from RDBMS store
+ auxFederationModuleMapping struct {
+ NodeID uint64 `db:"node_id"`
+ FederationModuleID uint64 `db:"federation_module_id"`
+ ComposeModuleID uint64 `db:"compose_module_id"`
+ ComposeNamespaceID uint64 `db:"compose_namespace_id"`
+ FieldMapping federationType.ModuleFieldMappingSet `db:"field_mapping"`
+ }
+
+ // auxFederationNode is an auxiliary structure used for transporting to/from RDBMS store
+ auxFederationNode struct {
+ ID uint64 `db:"id"`
+ Name string `db:"name"`
+ SharedNodeID uint64 `db:"shared_node_id"`
+ BaseURL string `db:"base_url"`
+ Status string `db:"status"`
+ Contact string `db:"contact"`
+ PairToken string `db:"pair_token"`
+ AuthToken string `db:"auth_token"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxFederationNodeSync is an auxiliary structure used for transporting to/from RDBMS store
+ auxFederationNodeSync struct {
+ NodeID uint64 `db:"node_id"`
+ ModuleID uint64 `db:"module_id"`
+ SyncType string `db:"sync_type"`
+ SyncStatus string `db:"sync_status"`
+ TimeOfAction time.Time `db:"time_of_action"`
+ }
+
+ // auxFederationSharedModule is an auxiliary structure used for transporting to/from RDBMS store
+ auxFederationSharedModule struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ NodeID uint64 `db:"node_id"`
+ Name string `db:"name"`
+ ExternalFederationModuleID uint64 `db:"external_federation_module_id"`
+ Fields federationType.ModuleFieldSet `db:"fields"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxFlag is an auxiliary structure used for transporting to/from RDBMS store
+ auxFlag struct {
+ Kind string `db:"kind"`
+ ResourceID uint64 `db:"resource_id"`
+ OwnedBy uint64 `db:"owned_by"`
+ Name string `db:"name"`
+ Active bool `db:"active"`
+ }
+
+ // auxLabel is an auxiliary structure used for transporting to/from RDBMS store
+ auxLabel struct {
+ Kind string `db:"kind"`
+ ResourceID uint64 `db:"resource_id"`
+ Name string `db:"name"`
+ Value string `db:"value"`
+ }
+
+ // auxQueue is an auxiliary structure used for transporting to/from RDBMS store
+ auxQueue struct {
+ ID uint64 `db:"id"`
+ Consumer string `db:"consumer"`
+ Queue string `db:"queue"`
+ Meta systemType.QueueMeta `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxQueueMessage is an auxiliary structure used for transporting to/from RDBMS store
+ auxQueueMessage struct {
+ ID uint64 `db:"id"`
+ Queue string `db:"queue"`
+ Payload []byte `db:"payload"`
+ Processed *time.Time `db:"processed"`
+ Created *time.Time `db:"created"`
+ }
+
+ // auxRbacRule is an auxiliary structure used for transporting to/from RDBMS store
+ auxRbacRule struct {
+ RoleID uint64 `db:"role_id"`
+ Resource string `db:"resource"`
+ Operation string `db:"operation"`
+ Access rbacType.Access `db:"access"`
+ }
+
+ // auxReminder is an auxiliary structure used for transporting to/from RDBMS store
+ auxReminder struct {
+ ID uint64 `db:"id"`
+ Resource string `db:"resource"`
+ Payload rawJson `db:"payload"`
+ SnoozeCount uint `db:"snooze_count"`
+ AssignedTo uint64 `db:"assigned_to"`
+ AssignedBy uint64 `db:"assigned_by"`
+ AssignedAt time.Time `db:"assigned_at"`
+ DismissedBy uint64 `db:"dismissed_by"`
+ DismissedAt *time.Time `db:"dismissed_at"`
+ RemindAt *time.Time `db:"remind_at"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ }
+
+ // auxReport is an auxiliary structure used for transporting to/from RDBMS store
+ auxReport struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Meta *systemType.ReportMeta `db:"meta"`
+ Scenarios systemType.ReportScenarioSet `db:"scenarios"`
+ Sources systemType.ReportDataSourceSet `db:"sources"`
+ Blocks systemType.ReportBlockSet `db:"blocks"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ OwnedBy uint64 `db:"owned_by"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxResourceActivity is an auxiliary structure used for transporting to/from RDBMS store
+ auxResourceActivity struct {
+ ID uint64 `db:"id"`
+ Timestamp time.Time `db:"timestamp"`
+ ResourceType string `db:"resource_type"`
+ ResourceAction string `db:"resource_action"`
+ ResourceID uint64 `db:"resource_id"`
+ Meta rawJson `db:"meta"`
+ }
+
+ // auxResourceTranslation is an auxiliary structure used for transporting to/from RDBMS store
+ auxResourceTranslation struct {
+ ID uint64 `db:"id"`
+ Lang systemType.Lang `db:"lang"`
+ Resource string `db:"resource"`
+ K string `db:"k"`
+ Message string `db:"message"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ OwnedBy uint64 `db:"owned_by"`
+ CreatedBy uint64 `db:"created_by"`
+ UpdatedBy uint64 `db:"updated_by"`
+ DeletedBy uint64 `db:"deleted_by"`
+ }
+
+ // auxRole is an auxiliary structure used for transporting to/from RDBMS store
+ auxRole struct {
+ ID uint64 `db:"id"`
+ Name string `db:"name"`
+ Handle string `db:"handle"`
+ Meta *systemType.RoleMeta `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ ArchivedAt *time.Time `db:"archived_at"`
+ }
+
+ // auxRoleMember is an auxiliary structure used for transporting to/from RDBMS store
+ auxRoleMember struct {
+ UserID uint64 `db:"user_id"`
+ RoleID uint64 `db:"role_id"`
+ }
+
+ // auxSettingValue is an auxiliary structure used for transporting to/from RDBMS store
+ auxSettingValue struct {
+ Name string `db:"name"`
+ OwnedBy uint64 `db:"owned_by"`
+ Value rawJson `db:"value"`
+ UpdatedBy uint64 `db:"updated_by"`
+ UpdatedAt time.Time `db:"updated_at"`
+ }
+
+ // auxTemplate is an auxiliary structure used for transporting to/from RDBMS store
+ auxTemplate struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Language string `db:"language"`
+ Type systemType.DocumentType `db:"type"`
+ Partial bool `db:"partial"`
+ Meta systemType.TemplateMeta `db:"meta"`
+ Template string `db:"template"`
+ OwnerID uint64 `db:"owner_id"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ LastUsedAt *time.Time `db:"last_used_at"`
+ }
+
+ // auxUser is an auxiliary structure used for transporting to/from RDBMS store
+ auxUser struct {
+ ID uint64 `db:"id"`
+ Handle string `db:"handle"`
+ Email string `db:"email"`
+ EmailConfirmed bool `db:"email_confirmed"`
+ Username string `db:"username"`
+ Name string `db:"name"`
+ Kind systemType.UserKind `db:"kind"`
+ Meta *systemType.UserMeta `db:"meta"`
+ CreatedAt time.Time `db:"created_at"`
+ UpdatedAt *time.Time `db:"updated_at"`
+ DeletedAt *time.Time `db:"deleted_at"`
+ SuspendedAt *time.Time `db:"suspended_at"`
+ }
+)
+
+// encodes Actionlog to auxActionlog
+//
+// This function is auto-generated
+func (aux *auxActionlog) encode(res *actionlogType.Action) (_ error) {
+ aux.ID = res.ID
+ aux.Timestamp = res.Timestamp
+ aux.RequestOrigin = res.RequestOrigin
+ aux.RequestID = res.RequestID
+ aux.ActorIPAddr = res.ActorIPAddr
+ aux.ActorID = res.ActorID
+ aux.Resource = res.Resource
+ aux.Action = res.Action
+ aux.Error = res.Error
+ aux.Severity = res.Severity
+ aux.Description = res.Description
+ aux.Meta = res.Meta
+ return
+}
+
+// decodes Actionlog from auxActionlog
+//
+// This function is auto-generated
+func (aux auxActionlog) decode() (res *actionlogType.Action, _ error) {
+ res = new(actionlogType.Action)
+ res.ID = aux.ID
+ res.Timestamp = aux.Timestamp
+ res.RequestOrigin = aux.RequestOrigin
+ res.RequestID = aux.RequestID
+ res.ActorIPAddr = aux.ActorIPAddr
+ res.ActorID = aux.ActorID
+ res.Resource = aux.Resource
+ res.Action = aux.Action
+ res.Error = aux.Error
+ res.Severity = aux.Severity
+ res.Description = aux.Description
+ res.Meta = aux.Meta
+ return
+}
+
+// scans row and fills auxActionlog fields
+//
+// This function is auto-generated
+func (aux *auxActionlog) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Timestamp,
+ &aux.RequestOrigin,
+ &aux.RequestID,
+ &aux.ActorIPAddr,
+ &aux.ActorID,
+ &aux.Resource,
+ &aux.Action,
+ &aux.Error,
+ &aux.Severity,
+ &aux.Description,
+ &aux.Meta,
+ )
+}
+
+// encodes ApigwFilter to auxApigwFilter
+//
+// This function is auto-generated
+func (aux *auxApigwFilter) encode(res *systemType.ApigwFilter) (_ error) {
+ aux.ID = res.ID
+ aux.Route = res.Route
+ aux.Weight = res.Weight
+ aux.Ref = res.Ref
+ aux.Kind = res.Kind
+ aux.Enabled = res.Enabled
+ aux.Params = res.Params
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes ApigwFilter from auxApigwFilter
+//
+// This function is auto-generated
+func (aux auxApigwFilter) decode() (res *systemType.ApigwFilter, _ error) {
+ res = new(systemType.ApigwFilter)
+ res.ID = aux.ID
+ res.Route = aux.Route
+ res.Weight = aux.Weight
+ res.Ref = aux.Ref
+ res.Kind = aux.Kind
+ res.Enabled = aux.Enabled
+ res.Params = aux.Params
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxApigwFilter fields
+//
+// This function is auto-generated
+func (aux *auxApigwFilter) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Route,
+ &aux.Weight,
+ &aux.Ref,
+ &aux.Kind,
+ &aux.Enabled,
+ &aux.Params,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes ApigwRoute to auxApigwRoute
+//
+// This function is auto-generated
+func (aux *auxApigwRoute) encode(res *systemType.ApigwRoute) (_ error) {
+ aux.ID = res.ID
+ aux.Endpoint = res.Endpoint
+ aux.Method = res.Method
+ aux.Enabled = res.Enabled
+ aux.Group = res.Group
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes ApigwRoute from auxApigwRoute
+//
+// This function is auto-generated
+func (aux auxApigwRoute) decode() (res *systemType.ApigwRoute, _ error) {
+ res = new(systemType.ApigwRoute)
+ res.ID = aux.ID
+ res.Endpoint = aux.Endpoint
+ res.Method = aux.Method
+ res.Enabled = aux.Enabled
+ res.Group = aux.Group
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxApigwRoute fields
+//
+// This function is auto-generated
+func (aux *auxApigwRoute) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Endpoint,
+ &aux.Method,
+ &aux.Enabled,
+ &aux.Group,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes Application to auxApplication
+//
+// This function is auto-generated
+func (aux *auxApplication) encode(res *systemType.Application) (_ error) {
+ aux.ID = res.ID
+ aux.Name = res.Name
+ aux.OwnerID = res.OwnerID
+ aux.Enabled = res.Enabled
+ aux.Weight = res.Weight
+ aux.Unify = res.Unify
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes Application from auxApplication
+//
+// This function is auto-generated
+func (aux auxApplication) decode() (res *systemType.Application, _ error) {
+ res = new(systemType.Application)
+ res.ID = aux.ID
+ res.Name = aux.Name
+ res.OwnerID = aux.OwnerID
+ res.Enabled = aux.Enabled
+ res.Weight = aux.Weight
+ res.Unify = aux.Unify
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxApplication fields
+//
+// This function is auto-generated
+func (aux *auxApplication) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Name,
+ &aux.OwnerID,
+ &aux.Enabled,
+ &aux.Weight,
+ &aux.Unify,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes Attachment to auxAttachment
+//
+// This function is auto-generated
+func (aux *auxAttachment) encode(res *systemType.Attachment) (_ error) {
+ aux.ID = res.ID
+ aux.OwnerID = res.OwnerID
+ aux.Kind = res.Kind
+ aux.Url = res.Url
+ aux.PreviewUrl = res.PreviewUrl
+ aux.Name = res.Name
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes Attachment from auxAttachment
+//
+// This function is auto-generated
+func (aux auxAttachment) decode() (res *systemType.Attachment, _ error) {
+ res = new(systemType.Attachment)
+ res.ID = aux.ID
+ res.OwnerID = aux.OwnerID
+ res.Kind = aux.Kind
+ res.Url = aux.Url
+ res.PreviewUrl = aux.PreviewUrl
+ res.Name = aux.Name
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxAttachment fields
+//
+// This function is auto-generated
+func (aux *auxAttachment) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.OwnerID,
+ &aux.Kind,
+ &aux.Url,
+ &aux.PreviewUrl,
+ &aux.Name,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes AuthClient to auxAuthClient
+//
+// This function is auto-generated
+func (aux *auxAuthClient) encode(res *systemType.AuthClient) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Meta = res.Meta
+ aux.Secret = res.Secret
+ aux.Scope = res.Scope
+ aux.ValidGrant = res.ValidGrant
+ aux.RedirectURI = res.RedirectURI
+ aux.Trusted = res.Trusted
+ aux.Enabled = res.Enabled
+ aux.ValidFrom = res.ValidFrom
+ aux.ExpiresAt = res.ExpiresAt
+ aux.Security = res.Security
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.OwnedBy = res.OwnedBy
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes AuthClient from auxAuthClient
+//
+// This function is auto-generated
+func (aux auxAuthClient) decode() (res *systemType.AuthClient, _ error) {
+ res = new(systemType.AuthClient)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Meta = aux.Meta
+ res.Secret = aux.Secret
+ res.Scope = aux.Scope
+ res.ValidGrant = aux.ValidGrant
+ res.RedirectURI = aux.RedirectURI
+ res.Trusted = aux.Trusted
+ res.Enabled = aux.Enabled
+ res.ValidFrom = aux.ValidFrom
+ res.ExpiresAt = aux.ExpiresAt
+ res.Security = aux.Security
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.OwnedBy = aux.OwnedBy
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxAuthClient fields
+//
+// This function is auto-generated
+func (aux *auxAuthClient) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Meta,
+ &aux.Secret,
+ &aux.Scope,
+ &aux.ValidGrant,
+ &aux.RedirectURI,
+ &aux.Trusted,
+ &aux.Enabled,
+ &aux.ValidFrom,
+ &aux.ExpiresAt,
+ &aux.Security,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.OwnedBy,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes AuthConfirmedClient to auxAuthConfirmedClient
+//
+// This function is auto-generated
+func (aux *auxAuthConfirmedClient) encode(res *systemType.AuthConfirmedClient) (_ error) {
+ aux.UserID = res.UserID
+ aux.ClientID = res.ClientID
+ aux.ConfirmedAt = res.ConfirmedAt
+ return
+}
+
+// decodes AuthConfirmedClient from auxAuthConfirmedClient
+//
+// This function is auto-generated
+func (aux auxAuthConfirmedClient) decode() (res *systemType.AuthConfirmedClient, _ error) {
+ res = new(systemType.AuthConfirmedClient)
+ res.UserID = aux.UserID
+ res.ClientID = aux.ClientID
+ res.ConfirmedAt = aux.ConfirmedAt
+ return
+}
+
+// scans row and fills auxAuthConfirmedClient fields
+//
+// This function is auto-generated
+func (aux *auxAuthConfirmedClient) scan(row scalable) error {
+ return row.Scan(
+ &aux.UserID,
+ &aux.ClientID,
+ &aux.ConfirmedAt,
+ )
+}
+
+// encodes AuthOa2token to auxAuthOa2token
+//
+// This function is auto-generated
+func (aux *auxAuthOa2token) encode(res *systemType.AuthOa2token) (_ error) {
+ aux.ID = res.ID
+ aux.Code = res.Code
+ aux.Access = res.Access
+ aux.Refresh = res.Refresh
+ aux.ExpiresAt = res.ExpiresAt
+ aux.CreatedAt = res.CreatedAt
+ aux.Data = res.Data
+ aux.ClientID = res.ClientID
+ aux.UserID = res.UserID
+ aux.RemoteAddr = res.RemoteAddr
+ aux.UserAgent = res.UserAgent
+ return
+}
+
+// decodes AuthOa2token from auxAuthOa2token
+//
+// This function is auto-generated
+func (aux auxAuthOa2token) decode() (res *systemType.AuthOa2token, _ error) {
+ res = new(systemType.AuthOa2token)
+ res.ID = aux.ID
+ res.Code = aux.Code
+ res.Access = aux.Access
+ res.Refresh = aux.Refresh
+ res.ExpiresAt = aux.ExpiresAt
+ res.CreatedAt = aux.CreatedAt
+ res.Data = aux.Data
+ res.ClientID = aux.ClientID
+ res.UserID = aux.UserID
+ res.RemoteAddr = aux.RemoteAddr
+ res.UserAgent = aux.UserAgent
+ return
+}
+
+// scans row and fills auxAuthOa2token fields
+//
+// This function is auto-generated
+func (aux *auxAuthOa2token) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Code,
+ &aux.Access,
+ &aux.Refresh,
+ &aux.ExpiresAt,
+ &aux.CreatedAt,
+ &aux.Data,
+ &aux.ClientID,
+ &aux.UserID,
+ &aux.RemoteAddr,
+ &aux.UserAgent,
+ )
+}
+
+// encodes AuthSession to auxAuthSession
+//
+// This function is auto-generated
+func (aux *auxAuthSession) encode(res *systemType.AuthSession) (_ error) {
+ aux.ID = res.ID
+ aux.Data = res.Data
+ aux.UserID = res.UserID
+ aux.ExpiresAt = res.ExpiresAt
+ aux.CreatedAt = res.CreatedAt
+ aux.RemoteAddr = res.RemoteAddr
+ aux.UserAgent = res.UserAgent
+ return
+}
+
+// decodes AuthSession from auxAuthSession
+//
+// This function is auto-generated
+func (aux auxAuthSession) decode() (res *systemType.AuthSession, _ error) {
+ res = new(systemType.AuthSession)
+ res.ID = aux.ID
+ res.Data = aux.Data
+ res.UserID = aux.UserID
+ res.ExpiresAt = aux.ExpiresAt
+ res.CreatedAt = aux.CreatedAt
+ res.RemoteAddr = aux.RemoteAddr
+ res.UserAgent = aux.UserAgent
+ return
+}
+
+// scans row and fills auxAuthSession fields
+//
+// This function is auto-generated
+func (aux *auxAuthSession) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Data,
+ &aux.UserID,
+ &aux.ExpiresAt,
+ &aux.CreatedAt,
+ &aux.RemoteAddr,
+ &aux.UserAgent,
+ )
+}
+
+// encodes AutomationSession to auxAutomationSession
+//
+// This function is auto-generated
+func (aux *auxAutomationSession) encode(res *automationType.Session) (_ error) {
+ aux.ID = res.ID
+ aux.WorkflowID = res.WorkflowID
+ aux.EventType = res.EventType
+ aux.ResourceType = res.ResourceType
+ aux.Status = res.Status
+ aux.Input = res.Input
+ aux.Output = res.Output
+ aux.Stacktrace = res.Stacktrace
+ aux.CreatedBy = res.CreatedBy
+ aux.CreatedAt = res.CreatedAt
+ aux.PurgeAt = res.PurgeAt
+ aux.CompletedAt = res.CompletedAt
+ aux.SuspendedAt = res.SuspendedAt
+ aux.Error = res.Error
+ return
+}
+
+// decodes AutomationSession from auxAutomationSession
+//
+// This function is auto-generated
+func (aux auxAutomationSession) decode() (res *automationType.Session, _ error) {
+ res = new(automationType.Session)
+ res.ID = aux.ID
+ res.WorkflowID = aux.WorkflowID
+ res.EventType = aux.EventType
+ res.ResourceType = aux.ResourceType
+ res.Status = aux.Status
+ res.Input = aux.Input
+ res.Output = aux.Output
+ res.Stacktrace = aux.Stacktrace
+ res.CreatedBy = aux.CreatedBy
+ res.CreatedAt = aux.CreatedAt
+ res.PurgeAt = aux.PurgeAt
+ res.CompletedAt = aux.CompletedAt
+ res.SuspendedAt = aux.SuspendedAt
+ res.Error = aux.Error
+ return
+}
+
+// scans row and fills auxAutomationSession fields
+//
+// This function is auto-generated
+func (aux *auxAutomationSession) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.WorkflowID,
+ &aux.EventType,
+ &aux.ResourceType,
+ &aux.Status,
+ &aux.Input,
+ &aux.Output,
+ &aux.Stacktrace,
+ &aux.CreatedBy,
+ &aux.CreatedAt,
+ &aux.PurgeAt,
+ &aux.CompletedAt,
+ &aux.SuspendedAt,
+ &aux.Error,
+ )
+}
+
+// encodes AutomationTrigger to auxAutomationTrigger
+//
+// This function is auto-generated
+func (aux *auxAutomationTrigger) encode(res *automationType.Trigger) (_ error) {
+ aux.ID = res.ID
+ aux.WorkflowID = res.WorkflowID
+ aux.StepID = res.StepID
+ aux.Enabled = res.Enabled
+ aux.ResourceType = res.ResourceType
+ aux.EventType = res.EventType
+ aux.Meta = res.Meta
+ aux.Constraints = res.Constraints
+ aux.Input = res.Input
+ aux.OwnedBy = res.OwnedBy
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes AutomationTrigger from auxAutomationTrigger
+//
+// This function is auto-generated
+func (aux auxAutomationTrigger) decode() (res *automationType.Trigger, _ error) {
+ res = new(automationType.Trigger)
+ res.ID = aux.ID
+ res.WorkflowID = aux.WorkflowID
+ res.StepID = aux.StepID
+ res.Enabled = aux.Enabled
+ res.ResourceType = aux.ResourceType
+ res.EventType = aux.EventType
+ res.Meta = aux.Meta
+ res.Constraints = aux.Constraints
+ res.Input = aux.Input
+ res.OwnedBy = aux.OwnedBy
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxAutomationTrigger fields
+//
+// This function is auto-generated
+func (aux *auxAutomationTrigger) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.WorkflowID,
+ &aux.StepID,
+ &aux.Enabled,
+ &aux.ResourceType,
+ &aux.EventType,
+ &aux.Meta,
+ &aux.Constraints,
+ &aux.Input,
+ &aux.OwnedBy,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes AutomationWorkflow to auxAutomationWorkflow
+//
+// This function is auto-generated
+func (aux *auxAutomationWorkflow) encode(res *automationType.Workflow) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Meta = res.Meta
+ aux.Enabled = res.Enabled
+ aux.Trace = res.Trace
+ aux.KeepSessions = res.KeepSessions
+ aux.Scope = res.Scope
+ aux.Steps = res.Steps
+ aux.Paths = res.Paths
+ aux.Issues = res.Issues
+ aux.RunAs = res.RunAs
+ aux.OwnedBy = res.OwnedBy
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes AutomationWorkflow from auxAutomationWorkflow
+//
+// This function is auto-generated
+func (aux auxAutomationWorkflow) decode() (res *automationType.Workflow, _ error) {
+ res = new(automationType.Workflow)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Meta = aux.Meta
+ res.Enabled = aux.Enabled
+ res.Trace = aux.Trace
+ res.KeepSessions = aux.KeepSessions
+ res.Scope = aux.Scope
+ res.Steps = aux.Steps
+ res.Paths = aux.Paths
+ res.Issues = aux.Issues
+ res.RunAs = aux.RunAs
+ res.OwnedBy = aux.OwnedBy
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxAutomationWorkflow fields
+//
+// This function is auto-generated
+func (aux *auxAutomationWorkflow) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Meta,
+ &aux.Enabled,
+ &aux.Trace,
+ &aux.KeepSessions,
+ &aux.Scope,
+ &aux.Steps,
+ &aux.Paths,
+ &aux.Issues,
+ &aux.RunAs,
+ &aux.OwnedBy,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes ComposeAttachment to auxComposeAttachment
+//
+// This function is auto-generated
+func (aux *auxComposeAttachment) encode(res *composeType.Attachment) (_ error) {
+ aux.ID = res.ID
+ aux.OwnerID = res.OwnerID
+ aux.NamespaceID = res.NamespaceID
+ aux.Kind = res.Kind
+ aux.Url = res.Url
+ aux.PreviewUrl = res.PreviewUrl
+ aux.Name = res.Name
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposeAttachment from auxComposeAttachment
+//
+// This function is auto-generated
+func (aux auxComposeAttachment) decode() (res *composeType.Attachment, _ error) {
+ res = new(composeType.Attachment)
+ res.ID = aux.ID
+ res.OwnerID = aux.OwnerID
+ res.NamespaceID = aux.NamespaceID
+ res.Kind = aux.Kind
+ res.Url = aux.Url
+ res.PreviewUrl = aux.PreviewUrl
+ res.Name = aux.Name
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposeAttachment fields
+//
+// This function is auto-generated
+func (aux *auxComposeAttachment) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.OwnerID,
+ &aux.NamespaceID,
+ &aux.Kind,
+ &aux.Url,
+ &aux.PreviewUrl,
+ &aux.Name,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes ComposeChart to auxComposeChart
+//
+// This function is auto-generated
+func (aux *auxComposeChart) encode(res *composeType.Chart) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Name = res.Name
+ aux.Config = res.Config
+ aux.NamespaceID = res.NamespaceID
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposeChart from auxComposeChart
+//
+// This function is auto-generated
+func (aux auxComposeChart) decode() (res *composeType.Chart, _ error) {
+ res = new(composeType.Chart)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Name = aux.Name
+ res.Config = aux.Config
+ res.NamespaceID = aux.NamespaceID
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposeChart fields
+//
+// This function is auto-generated
+func (aux *auxComposeChart) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Name,
+ &aux.Config,
+ &aux.NamespaceID,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes ComposeModule to auxComposeModule
+//
+// This function is auto-generated
+func (aux *auxComposeModule) encode(res *composeType.Module) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Meta = res.Meta
+ aux.NamespaceID = res.NamespaceID
+ aux.Name = res.Name
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposeModule from auxComposeModule
+//
+// This function is auto-generated
+func (aux auxComposeModule) decode() (res *composeType.Module, _ error) {
+ res = new(composeType.Module)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Meta = aux.Meta
+ res.NamespaceID = aux.NamespaceID
+ res.Name = aux.Name
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposeModule fields
+//
+// This function is auto-generated
+func (aux *auxComposeModule) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Meta,
+ &aux.NamespaceID,
+ &aux.Name,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes ComposeModuleField to auxComposeModuleField
+//
+// This function is auto-generated
+func (aux *auxComposeModuleField) encode(res *composeType.ModuleField) (_ error) {
+ aux.ID = res.ID
+ aux.ModuleID = res.ModuleID
+ aux.Place = res.Place
+ aux.Kind = res.Kind
+ aux.Name = res.Name
+ aux.Label = res.Label
+ aux.Options = res.Options
+ aux.Private = res.Private
+ aux.Required = res.Required
+ aux.Visible = res.Visible
+ aux.Multi = res.Multi
+ aux.DefaultValue = res.DefaultValue
+ aux.Expressions = res.Expressions
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposeModuleField from auxComposeModuleField
+//
+// This function is auto-generated
+func (aux auxComposeModuleField) decode() (res *composeType.ModuleField, _ error) {
+ res = new(composeType.ModuleField)
+ res.ID = aux.ID
+ res.ModuleID = aux.ModuleID
+ res.Place = aux.Place
+ res.Kind = aux.Kind
+ res.Name = aux.Name
+ res.Label = aux.Label
+ res.Options = aux.Options
+ res.Private = aux.Private
+ res.Required = aux.Required
+ res.Visible = aux.Visible
+ res.Multi = aux.Multi
+ res.DefaultValue = aux.DefaultValue
+ res.Expressions = aux.Expressions
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposeModuleField fields
+//
+// This function is auto-generated
+func (aux *auxComposeModuleField) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.ModuleID,
+ &aux.Place,
+ &aux.Kind,
+ &aux.Name,
+ &aux.Label,
+ &aux.Options,
+ &aux.Private,
+ &aux.Required,
+ &aux.Visible,
+ &aux.Multi,
+ &aux.DefaultValue,
+ &aux.Expressions,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes ComposeNamespace to auxComposeNamespace
+//
+// This function is auto-generated
+func (aux *auxComposeNamespace) encode(res *composeType.Namespace) (_ error) {
+ aux.ID = res.ID
+ aux.Slug = res.Slug
+ aux.Enabled = res.Enabled
+ aux.Meta = res.Meta
+ aux.Name = res.Name
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposeNamespace from auxComposeNamespace
+//
+// This function is auto-generated
+func (aux auxComposeNamespace) decode() (res *composeType.Namespace, _ error) {
+ res = new(composeType.Namespace)
+ res.ID = aux.ID
+ res.Slug = aux.Slug
+ res.Enabled = aux.Enabled
+ res.Meta = aux.Meta
+ res.Name = aux.Name
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposeNamespace fields
+//
+// This function is auto-generated
+func (aux *auxComposeNamespace) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Slug,
+ &aux.Enabled,
+ &aux.Meta,
+ &aux.Name,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes ComposePage to auxComposePage
+//
+// This function is auto-generated
+func (aux *auxComposePage) encode(res *composeType.Page) (_ error) {
+ aux.ID = res.ID
+ aux.SelfID = res.SelfID
+ aux.ModuleID = res.ModuleID
+ aux.NamespaceID = res.NamespaceID
+ aux.Handle = res.Handle
+ aux.Config = res.Config
+ aux.Blocks = res.Blocks
+ aux.Visible = res.Visible
+ aux.Weight = res.Weight
+ aux.Title = res.Title
+ aux.Description = res.Description
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposePage from auxComposePage
+//
+// This function is auto-generated
+func (aux auxComposePage) decode() (res *composeType.Page, _ error) {
+ res = new(composeType.Page)
+ res.ID = aux.ID
+ res.SelfID = aux.SelfID
+ res.ModuleID = aux.ModuleID
+ res.NamespaceID = aux.NamespaceID
+ res.Handle = aux.Handle
+ res.Config = aux.Config
+ res.Blocks = aux.Blocks
+ res.Visible = aux.Visible
+ res.Weight = aux.Weight
+ res.Title = aux.Title
+ res.Description = aux.Description
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposePage fields
+//
+// This function is auto-generated
+func (aux *auxComposePage) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.SelfID,
+ &aux.ModuleID,
+ &aux.NamespaceID,
+ &aux.Handle,
+ &aux.Config,
+ &aux.Blocks,
+ &aux.Visible,
+ &aux.Weight,
+ &aux.Title,
+ &aux.Description,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes ComposeRecord to auxComposeRecord
+//
+// This function is auto-generated
+func (aux *auxComposeRecord) encode(res *composeType.Record) (_ error) {
+ aux.ID = res.ID
+ aux.ModuleID = res.ModuleID
+ aux.NamespaceID = res.NamespaceID
+ aux.OwnedBy = res.OwnedBy
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes ComposeRecord from auxComposeRecord
+//
+// This function is auto-generated
+func (aux auxComposeRecord) decode() (res *composeType.Record, _ error) {
+ res = new(composeType.Record)
+ res.ID = aux.ID
+ res.ModuleID = aux.ModuleID
+ res.NamespaceID = aux.NamespaceID
+ res.OwnedBy = aux.OwnedBy
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxComposeRecord fields
+//
+// This function is auto-generated
+func (aux *auxComposeRecord) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.ModuleID,
+ &aux.NamespaceID,
+ &aux.OwnedBy,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes ComposeRecordValue to auxComposeRecordValue
+//
+// This function is auto-generated
+func (aux *auxComposeRecordValue) encode(res *composeType.RecordValue) (_ error) {
+ aux.RecordID = res.RecordID
+ aux.Name = res.Name
+ aux.Place = res.Place
+ aux.Ref = res.Ref
+ aux.Value = res.Value
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes ComposeRecordValue from auxComposeRecordValue
+//
+// This function is auto-generated
+func (aux auxComposeRecordValue) decode() (res *composeType.RecordValue, _ error) {
+ res = new(composeType.RecordValue)
+ res.RecordID = aux.RecordID
+ res.Name = aux.Name
+ res.Place = aux.Place
+ res.Ref = aux.Ref
+ res.Value = aux.Value
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxComposeRecordValue fields
+//
+// This function is auto-generated
+func (aux *auxComposeRecordValue) scan(row scalable) error {
+ return row.Scan(
+ &aux.RecordID,
+ &aux.Name,
+ &aux.Place,
+ &aux.Ref,
+ &aux.Value,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes Credential to auxCredential
+//
+// This function is auto-generated
+func (aux *auxCredential) encode(res *systemType.Credential) (_ error) {
+ aux.ID = res.ID
+ aux.OwnerID = res.OwnerID
+ aux.Kind = res.Kind
+ aux.Label = res.Label
+ aux.Credentials = res.Credentials
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.LastUsedAt = res.LastUsedAt
+ aux.ExpiresAt = res.ExpiresAt
+ return
+}
+
+// decodes Credential from auxCredential
+//
+// This function is auto-generated
+func (aux auxCredential) decode() (res *systemType.Credential, _ error) {
+ res = new(systemType.Credential)
+ res.ID = aux.ID
+ res.OwnerID = aux.OwnerID
+ res.Kind = aux.Kind
+ res.Label = aux.Label
+ res.Credentials = aux.Credentials
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.LastUsedAt = aux.LastUsedAt
+ res.ExpiresAt = aux.ExpiresAt
+ return
+}
+
+// scans row and fills auxCredential fields
+//
+// This function is auto-generated
+func (aux *auxCredential) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.OwnerID,
+ &aux.Kind,
+ &aux.Label,
+ &aux.Credentials,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.LastUsedAt,
+ &aux.ExpiresAt,
+ )
+}
+
+// encodes FederationExposedModule to auxFederationExposedModule
+//
+// This function is auto-generated
+func (aux *auxFederationExposedModule) encode(res *federationType.ExposedModule) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Name = res.Name
+ aux.NodeID = res.NodeID
+ aux.ComposeModuleID = res.ComposeModuleID
+ aux.ComposeNamespaceID = res.ComposeNamespaceID
+ aux.Fields = res.Fields
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes FederationExposedModule from auxFederationExposedModule
+//
+// This function is auto-generated
+func (aux auxFederationExposedModule) decode() (res *federationType.ExposedModule, _ error) {
+ res = new(federationType.ExposedModule)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Name = aux.Name
+ res.NodeID = aux.NodeID
+ res.ComposeModuleID = aux.ComposeModuleID
+ res.ComposeNamespaceID = aux.ComposeNamespaceID
+ res.Fields = aux.Fields
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxFederationExposedModule fields
+//
+// This function is auto-generated
+func (aux *auxFederationExposedModule) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Name,
+ &aux.NodeID,
+ &aux.ComposeModuleID,
+ &aux.ComposeNamespaceID,
+ &aux.Fields,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes FederationModuleMapping to auxFederationModuleMapping
+//
+// This function is auto-generated
+func (aux *auxFederationModuleMapping) encode(res *federationType.ModuleMapping) (_ error) {
+ aux.NodeID = res.NodeID
+ aux.FederationModuleID = res.FederationModuleID
+ aux.ComposeModuleID = res.ComposeModuleID
+ aux.ComposeNamespaceID = res.ComposeNamespaceID
+ aux.FieldMapping = res.FieldMapping
+ return
+}
+
+// decodes FederationModuleMapping from auxFederationModuleMapping
+//
+// This function is auto-generated
+func (aux auxFederationModuleMapping) decode() (res *federationType.ModuleMapping, _ error) {
+ res = new(federationType.ModuleMapping)
+ res.NodeID = aux.NodeID
+ res.FederationModuleID = aux.FederationModuleID
+ res.ComposeModuleID = aux.ComposeModuleID
+ res.ComposeNamespaceID = aux.ComposeNamespaceID
+ res.FieldMapping = aux.FieldMapping
+ return
+}
+
+// scans row and fills auxFederationModuleMapping fields
+//
+// This function is auto-generated
+func (aux *auxFederationModuleMapping) scan(row scalable) error {
+ return row.Scan(
+ &aux.NodeID,
+ &aux.FederationModuleID,
+ &aux.ComposeModuleID,
+ &aux.ComposeNamespaceID,
+ &aux.FieldMapping,
+ )
+}
+
+// encodes FederationNode to auxFederationNode
+//
+// This function is auto-generated
+func (aux *auxFederationNode) encode(res *federationType.Node) (_ error) {
+ aux.ID = res.ID
+ aux.Name = res.Name
+ aux.SharedNodeID = res.SharedNodeID
+ aux.BaseURL = res.BaseURL
+ aux.Status = res.Status
+ aux.Contact = res.Contact
+ aux.PairToken = res.PairToken
+ aux.AuthToken = res.AuthToken
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes FederationNode from auxFederationNode
+//
+// This function is auto-generated
+func (aux auxFederationNode) decode() (res *federationType.Node, _ error) {
+ res = new(federationType.Node)
+ res.ID = aux.ID
+ res.Name = aux.Name
+ res.SharedNodeID = aux.SharedNodeID
+ res.BaseURL = aux.BaseURL
+ res.Status = aux.Status
+ res.Contact = aux.Contact
+ res.PairToken = aux.PairToken
+ res.AuthToken = aux.AuthToken
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxFederationNode fields
+//
+// This function is auto-generated
+func (aux *auxFederationNode) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Name,
+ &aux.SharedNodeID,
+ &aux.BaseURL,
+ &aux.Status,
+ &aux.Contact,
+ &aux.PairToken,
+ &aux.AuthToken,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes FederationNodeSync to auxFederationNodeSync
+//
+// This function is auto-generated
+func (aux *auxFederationNodeSync) encode(res *federationType.NodeSync) (_ error) {
+ aux.NodeID = res.NodeID
+ aux.ModuleID = res.ModuleID
+ aux.SyncType = res.SyncType
+ aux.SyncStatus = res.SyncStatus
+ aux.TimeOfAction = res.TimeOfAction
+ return
+}
+
+// decodes FederationNodeSync from auxFederationNodeSync
+//
+// This function is auto-generated
+func (aux auxFederationNodeSync) decode() (res *federationType.NodeSync, _ error) {
+ res = new(federationType.NodeSync)
+ res.NodeID = aux.NodeID
+ res.ModuleID = aux.ModuleID
+ res.SyncType = aux.SyncType
+ res.SyncStatus = aux.SyncStatus
+ res.TimeOfAction = aux.TimeOfAction
+ return
+}
+
+// scans row and fills auxFederationNodeSync fields
+//
+// This function is auto-generated
+func (aux *auxFederationNodeSync) scan(row scalable) error {
+ return row.Scan(
+ &aux.NodeID,
+ &aux.ModuleID,
+ &aux.SyncType,
+ &aux.SyncStatus,
+ &aux.TimeOfAction,
+ )
+}
+
+// encodes FederationSharedModule to auxFederationSharedModule
+//
+// This function is auto-generated
+func (aux *auxFederationSharedModule) encode(res *federationType.SharedModule) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.NodeID = res.NodeID
+ aux.Name = res.Name
+ aux.ExternalFederationModuleID = res.ExternalFederationModuleID
+ aux.Fields = res.Fields
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes FederationSharedModule from auxFederationSharedModule
+//
+// This function is auto-generated
+func (aux auxFederationSharedModule) decode() (res *federationType.SharedModule, _ error) {
+ res = new(federationType.SharedModule)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.NodeID = aux.NodeID
+ res.Name = aux.Name
+ res.ExternalFederationModuleID = aux.ExternalFederationModuleID
+ res.Fields = aux.Fields
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxFederationSharedModule fields
+//
+// This function is auto-generated
+func (aux *auxFederationSharedModule) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.NodeID,
+ &aux.Name,
+ &aux.ExternalFederationModuleID,
+ &aux.Fields,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes Flag to auxFlag
+//
+// This function is auto-generated
+func (aux *auxFlag) encode(res *flagType.Flag) (_ error) {
+ aux.Kind = res.Kind
+ aux.ResourceID = res.ResourceID
+ aux.OwnedBy = res.OwnedBy
+ aux.Name = res.Name
+ aux.Active = res.Active
+ return
+}
+
+// decodes Flag from auxFlag
+//
+// This function is auto-generated
+func (aux auxFlag) decode() (res *flagType.Flag, _ error) {
+ res = new(flagType.Flag)
+ res.Kind = aux.Kind
+ res.ResourceID = aux.ResourceID
+ res.OwnedBy = aux.OwnedBy
+ res.Name = aux.Name
+ res.Active = aux.Active
+ return
+}
+
+// scans row and fills auxFlag fields
+//
+// This function is auto-generated
+func (aux *auxFlag) scan(row scalable) error {
+ return row.Scan(
+ &aux.Kind,
+ &aux.ResourceID,
+ &aux.OwnedBy,
+ &aux.Name,
+ &aux.Active,
+ )
+}
+
+// encodes Label to auxLabel
+//
+// This function is auto-generated
+func (aux *auxLabel) encode(res *labelsType.Label) (_ error) {
+ aux.Kind = res.Kind
+ aux.ResourceID = res.ResourceID
+ aux.Name = res.Name
+ aux.Value = res.Value
+ return
+}
+
+// decodes Label from auxLabel
+//
+// This function is auto-generated
+func (aux auxLabel) decode() (res *labelsType.Label, _ error) {
+ res = new(labelsType.Label)
+ res.Kind = aux.Kind
+ res.ResourceID = aux.ResourceID
+ res.Name = aux.Name
+ res.Value = aux.Value
+ return
+}
+
+// scans row and fills auxLabel fields
+//
+// This function is auto-generated
+func (aux *auxLabel) scan(row scalable) error {
+ return row.Scan(
+ &aux.Kind,
+ &aux.ResourceID,
+ &aux.Name,
+ &aux.Value,
+ )
+}
+
+// encodes Queue to auxQueue
+//
+// This function is auto-generated
+func (aux *auxQueue) encode(res *systemType.Queue) (_ error) {
+ aux.ID = res.ID
+ aux.Consumer = res.Consumer
+ aux.Queue = res.Queue
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes Queue from auxQueue
+//
+// This function is auto-generated
+func (aux auxQueue) decode() (res *systemType.Queue, _ error) {
+ res = new(systemType.Queue)
+ res.ID = aux.ID
+ res.Consumer = aux.Consumer
+ res.Queue = aux.Queue
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxQueue fields
+//
+// This function is auto-generated
+func (aux *auxQueue) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Consumer,
+ &aux.Queue,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes QueueMessage to auxQueueMessage
+//
+// This function is auto-generated
+func (aux *auxQueueMessage) encode(res *systemType.QueueMessage) (_ error) {
+ aux.ID = res.ID
+ aux.Queue = res.Queue
+ aux.Payload = res.Payload
+ aux.Processed = res.Processed
+ aux.Created = res.Created
+ return
+}
+
+// decodes QueueMessage from auxQueueMessage
+//
+// This function is auto-generated
+func (aux auxQueueMessage) decode() (res *systemType.QueueMessage, _ error) {
+ res = new(systemType.QueueMessage)
+ res.ID = aux.ID
+ res.Queue = aux.Queue
+ res.Payload = aux.Payload
+ res.Processed = aux.Processed
+ res.Created = aux.Created
+ return
+}
+
+// scans row and fills auxQueueMessage fields
+//
+// This function is auto-generated
+func (aux *auxQueueMessage) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Queue,
+ &aux.Payload,
+ &aux.Processed,
+ &aux.Created,
+ )
+}
+
+// encodes RbacRule to auxRbacRule
+//
+// This function is auto-generated
+func (aux *auxRbacRule) encode(res *rbacType.Rule) (_ error) {
+ aux.RoleID = res.RoleID
+ aux.Resource = res.Resource
+ aux.Operation = res.Operation
+ aux.Access = res.Access
+ return
+}
+
+// decodes RbacRule from auxRbacRule
+//
+// This function is auto-generated
+func (aux auxRbacRule) decode() (res *rbacType.Rule, _ error) {
+ res = new(rbacType.Rule)
+ res.RoleID = aux.RoleID
+ res.Resource = aux.Resource
+ res.Operation = aux.Operation
+ res.Access = aux.Access
+ return
+}
+
+// scans row and fills auxRbacRule fields
+//
+// This function is auto-generated
+func (aux *auxRbacRule) scan(row scalable) error {
+ return row.Scan(
+ &aux.RoleID,
+ &aux.Resource,
+ &aux.Operation,
+ &aux.Access,
+ )
+}
+
+// encodes Reminder to auxReminder
+//
+// This function is auto-generated
+func (aux *auxReminder) encode(res *systemType.Reminder) (_ error) {
+ aux.ID = res.ID
+ aux.Resource = res.Resource
+ aux.Payload = res.Payload
+ aux.SnoozeCount = res.SnoozeCount
+ aux.AssignedTo = res.AssignedTo
+ aux.AssignedBy = res.AssignedBy
+ aux.AssignedAt = res.AssignedAt
+ aux.DismissedBy = res.DismissedBy
+ aux.DismissedAt = res.DismissedAt
+ aux.RemindAt = res.RemindAt
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ return
+}
+
+// decodes Reminder from auxReminder
+//
+// This function is auto-generated
+func (aux auxReminder) decode() (res *systemType.Reminder, _ error) {
+ res = new(systemType.Reminder)
+ res.ID = aux.ID
+ res.Resource = aux.Resource
+ res.Payload = aux.Payload
+ res.SnoozeCount = aux.SnoozeCount
+ res.AssignedTo = aux.AssignedTo
+ res.AssignedBy = aux.AssignedBy
+ res.AssignedAt = aux.AssignedAt
+ res.DismissedBy = aux.DismissedBy
+ res.DismissedAt = aux.DismissedAt
+ res.RemindAt = aux.RemindAt
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ return
+}
+
+// scans row and fills auxReminder fields
+//
+// This function is auto-generated
+func (aux *auxReminder) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Resource,
+ &aux.Payload,
+ &aux.SnoozeCount,
+ &aux.AssignedTo,
+ &aux.AssignedBy,
+ &aux.AssignedAt,
+ &aux.DismissedBy,
+ &aux.DismissedAt,
+ &aux.RemindAt,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ )
+}
+
+// encodes Report to auxReport
+//
+// This function is auto-generated
+func (aux *auxReport) encode(res *systemType.Report) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Meta = res.Meta
+ aux.Scenarios = res.Scenarios
+ aux.Sources = res.Sources
+ aux.Blocks = res.Blocks
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.OwnedBy = res.OwnedBy
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes Report from auxReport
+//
+// This function is auto-generated
+func (aux auxReport) decode() (res *systemType.Report, _ error) {
+ res = new(systemType.Report)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Meta = aux.Meta
+ res.Scenarios = aux.Scenarios
+ res.Sources = aux.Sources
+ res.Blocks = aux.Blocks
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.OwnedBy = aux.OwnedBy
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxReport fields
+//
+// This function is auto-generated
+func (aux *auxReport) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Meta,
+ &aux.Scenarios,
+ &aux.Sources,
+ &aux.Blocks,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.OwnedBy,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes ResourceActivity to auxResourceActivity
+//
+// This function is auto-generated
+func (aux *auxResourceActivity) encode(res *discoveryType.ResourceActivity) (_ error) {
+ aux.ID = res.ID
+ aux.Timestamp = res.Timestamp
+ aux.ResourceType = res.ResourceType
+ aux.ResourceAction = res.ResourceAction
+ aux.ResourceID = res.ResourceID
+ aux.Meta = res.Meta
+ return
+}
+
+// decodes ResourceActivity from auxResourceActivity
+//
+// This function is auto-generated
+func (aux auxResourceActivity) decode() (res *discoveryType.ResourceActivity, _ error) {
+ res = new(discoveryType.ResourceActivity)
+ res.ID = aux.ID
+ res.Timestamp = aux.Timestamp
+ res.ResourceType = aux.ResourceType
+ res.ResourceAction = aux.ResourceAction
+ res.ResourceID = aux.ResourceID
+ res.Meta = aux.Meta
+ return
+}
+
+// scans row and fills auxResourceActivity fields
+//
+// This function is auto-generated
+func (aux *auxResourceActivity) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Timestamp,
+ &aux.ResourceType,
+ &aux.ResourceAction,
+ &aux.ResourceID,
+ &aux.Meta,
+ )
+}
+
+// encodes ResourceTranslation to auxResourceTranslation
+//
+// This function is auto-generated
+func (aux *auxResourceTranslation) encode(res *systemType.ResourceTranslation) (_ error) {
+ aux.ID = res.ID
+ aux.Lang = res.Lang
+ aux.Resource = res.Resource
+ aux.K = res.K
+ aux.Message = res.Message
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.OwnedBy = res.OwnedBy
+ aux.CreatedBy = res.CreatedBy
+ aux.UpdatedBy = res.UpdatedBy
+ aux.DeletedBy = res.DeletedBy
+ return
+}
+
+// decodes ResourceTranslation from auxResourceTranslation
+//
+// This function is auto-generated
+func (aux auxResourceTranslation) decode() (res *systemType.ResourceTranslation, _ error) {
+ res = new(systemType.ResourceTranslation)
+ res.ID = aux.ID
+ res.Lang = aux.Lang
+ res.Resource = aux.Resource
+ res.K = aux.K
+ res.Message = aux.Message
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.OwnedBy = aux.OwnedBy
+ res.CreatedBy = aux.CreatedBy
+ res.UpdatedBy = aux.UpdatedBy
+ res.DeletedBy = aux.DeletedBy
+ return
+}
+
+// scans row and fills auxResourceTranslation fields
+//
+// This function is auto-generated
+func (aux *auxResourceTranslation) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Lang,
+ &aux.Resource,
+ &aux.K,
+ &aux.Message,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.OwnedBy,
+ &aux.CreatedBy,
+ &aux.UpdatedBy,
+ &aux.DeletedBy,
+ )
+}
+
+// encodes Role to auxRole
+//
+// This function is auto-generated
+func (aux *auxRole) encode(res *systemType.Role) (_ error) {
+ aux.ID = res.ID
+ aux.Name = res.Name
+ aux.Handle = res.Handle
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.ArchivedAt = res.ArchivedAt
+ return
+}
+
+// decodes Role from auxRole
+//
+// This function is auto-generated
+func (aux auxRole) decode() (res *systemType.Role, _ error) {
+ res = new(systemType.Role)
+ res.ID = aux.ID
+ res.Name = aux.Name
+ res.Handle = aux.Handle
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.ArchivedAt = aux.ArchivedAt
+ return
+}
+
+// scans row and fills auxRole fields
+//
+// This function is auto-generated
+func (aux *auxRole) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Name,
+ &aux.Handle,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.ArchivedAt,
+ )
+}
+
+// encodes RoleMember to auxRoleMember
+//
+// This function is auto-generated
+func (aux *auxRoleMember) encode(res *systemType.RoleMember) (_ error) {
+ aux.UserID = res.UserID
+ aux.RoleID = res.RoleID
+ return
+}
+
+// decodes RoleMember from auxRoleMember
+//
+// This function is auto-generated
+func (aux auxRoleMember) decode() (res *systemType.RoleMember, _ error) {
+ res = new(systemType.RoleMember)
+ res.UserID = aux.UserID
+ res.RoleID = aux.RoleID
+ return
+}
+
+// scans row and fills auxRoleMember fields
+//
+// This function is auto-generated
+func (aux *auxRoleMember) scan(row scalable) error {
+ return row.Scan(
+ &aux.UserID,
+ &aux.RoleID,
+ )
+}
+
+// encodes SettingValue to auxSettingValue
+//
+// This function is auto-generated
+func (aux *auxSettingValue) encode(res *systemType.SettingValue) (_ error) {
+ aux.Name = res.Name
+ aux.OwnedBy = res.OwnedBy
+ aux.Value = res.Value
+ aux.UpdatedBy = res.UpdatedBy
+ aux.UpdatedAt = res.UpdatedAt
+ return
+}
+
+// decodes SettingValue from auxSettingValue
+//
+// This function is auto-generated
+func (aux auxSettingValue) decode() (res *systemType.SettingValue, _ error) {
+ res = new(systemType.SettingValue)
+ res.Name = aux.Name
+ res.OwnedBy = aux.OwnedBy
+ res.Value = aux.Value
+ res.UpdatedBy = aux.UpdatedBy
+ res.UpdatedAt = aux.UpdatedAt
+ return
+}
+
+// scans row and fills auxSettingValue fields
+//
+// This function is auto-generated
+func (aux *auxSettingValue) scan(row scalable) error {
+ return row.Scan(
+ &aux.Name,
+ &aux.OwnedBy,
+ &aux.Value,
+ &aux.UpdatedBy,
+ &aux.UpdatedAt,
+ )
+}
+
+// encodes Template to auxTemplate
+//
+// This function is auto-generated
+func (aux *auxTemplate) encode(res *systemType.Template) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Language = res.Language
+ aux.Type = res.Type
+ aux.Partial = res.Partial
+ aux.Meta = res.Meta
+ aux.Template = res.Template
+ aux.OwnerID = res.OwnerID
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.LastUsedAt = res.LastUsedAt
+ return
+}
+
+// decodes Template from auxTemplate
+//
+// This function is auto-generated
+func (aux auxTemplate) decode() (res *systemType.Template, _ error) {
+ res = new(systemType.Template)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Language = aux.Language
+ res.Type = aux.Type
+ res.Partial = aux.Partial
+ res.Meta = aux.Meta
+ res.Template = aux.Template
+ res.OwnerID = aux.OwnerID
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.LastUsedAt = aux.LastUsedAt
+ return
+}
+
+// scans row and fills auxTemplate fields
+//
+// This function is auto-generated
+func (aux *auxTemplate) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Language,
+ &aux.Type,
+ &aux.Partial,
+ &aux.Meta,
+ &aux.Template,
+ &aux.OwnerID,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.LastUsedAt,
+ )
+}
+
+// encodes User to auxUser
+//
+// This function is auto-generated
+func (aux *auxUser) encode(res *systemType.User) (_ error) {
+ aux.ID = res.ID
+ aux.Handle = res.Handle
+ aux.Email = res.Email
+ aux.EmailConfirmed = res.EmailConfirmed
+ aux.Username = res.Username
+ aux.Name = res.Name
+ aux.Kind = res.Kind
+ aux.Meta = res.Meta
+ aux.CreatedAt = res.CreatedAt
+ aux.UpdatedAt = res.UpdatedAt
+ aux.DeletedAt = res.DeletedAt
+ aux.SuspendedAt = res.SuspendedAt
+ return
+}
+
+// decodes User from auxUser
+//
+// This function is auto-generated
+func (aux auxUser) decode() (res *systemType.User, _ error) {
+ res = new(systemType.User)
+ res.ID = aux.ID
+ res.Handle = aux.Handle
+ res.Email = aux.Email
+ res.EmailConfirmed = aux.EmailConfirmed
+ res.Username = aux.Username
+ res.Name = aux.Name
+ res.Kind = aux.Kind
+ res.Meta = aux.Meta
+ res.CreatedAt = aux.CreatedAt
+ res.UpdatedAt = aux.UpdatedAt
+ res.DeletedAt = aux.DeletedAt
+ res.SuspendedAt = aux.SuspendedAt
+ return
+}
+
+// scans row and fills auxUser fields
+//
+// This function is auto-generated
+func (aux *auxUser) scan(row scalable) error {
+ return row.Scan(
+ &aux.ID,
+ &aux.Handle,
+ &aux.Email,
+ &aux.EmailConfirmed,
+ &aux.Username,
+ &aux.Name,
+ &aux.Kind,
+ &aux.Meta,
+ &aux.CreatedAt,
+ &aux.UpdatedAt,
+ &aux.DeletedAt,
+ &aux.SuspendedAt,
+ )
+}
diff --git a/store/rdbms/rdbms_config.go b/store/adapters/rdbms/config.go
similarity index 63%
rename from store/rdbms/rdbms_config.go
rename to store/adapters/rdbms/config.go
index d51701d0e..f52f705ea 100644
--- a/store/rdbms/rdbms_config.go
+++ b/store/adapters/rdbms/config.go
@@ -8,37 +8,30 @@ import (
"strings"
"time"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/ql"
"github.com/cortezaproject/corteza-server/store"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/schema"
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
)
-// persistance layer
-//
-// all functions go under one struct
-// why? because it will be easier to initialize and pass around
-//
-// each domain will be in it's own file
-//
-// connection logic will be built in the persistence layer (making pkg/db obsolete)
-//
-
type (
txRetryOnErrHandler func(int, error) bool
- columnPreprocFn func(string) string
- triggerKey string
- rowScanner interface {
- Scan(...interface{}) error
+ Functions struct {
+ // returns lower case text
+ LOWER func(interface{}) exp.SQLFunctionExpression
+
+ // returns date part of the input (YYYY-MM-DD)
+ DATE func(interface{}) exp.SQLFunctionExpression
}
- TriggerHandlers map[triggerKey]interface{}
-
Config struct {
DriverName string
DataSourceName string
DBName string
+ Dialect goqu.DialectWrapper
+
// Forces debug mode on RDBMS driver
Debug bool
@@ -66,9 +59,6 @@ type (
// ConnTryMax maximum number of retrys for getting the connection
ConnTryMax int
- // PlaceholderFormat used by squirrel query generator
- PlaceholderFormat squirrel.PlaceholderFormat
-
// Disable transactions
TxDisabled bool
@@ -83,38 +73,16 @@ type (
// and false if we're safe to terminate it
TxRetryErrHandler txRetryOnErrHandler
- ColumnPreprocessors map[string]columnPreprocFn
-
ErrorHandler store.ErrorHandler
- // Different store backend implementation might handle upsert differently...
- UpsertBuilder func(*Config, string, store.Payload, ...string) (squirrel.InsertBuilder, error)
+ Functions Functions
- // TriggerHandlers handle various exceptions that cannot be handled generally within RDBMS package.
- // see triggerKey type and defined constants to see where the hooks are and how can they be called
- TriggerHandlers TriggerHandlers
+ // additional per-resource filters used when searching
+ // these filters can modify expression used for querying the database
+ Filters extendedFilters
- // UniqueConstraintCheck flag controls if unique constraints should be explicitly checked within
- // store or is this handled inside the storage
- //
- //
- UniqueConstraintCheck bool
-
- // FunctionHandler takes care of translation & transformation of (sql) functions
- // and their parameters
- //
- // Functions are used in filters and aggregations
- SqlFunctionHandler func(f ql.Function) (ql.ASTNode, error)
-
- // SqlSortHandler handles construction of sorting expression
- //
- // MySQL does not support NULLS FIRST/LAST and without it sorts nulls differently then Postgres/SQLite
- SqlSortHandler func(exp string, desc bool) string
-
- CastModuleFieldToColumnType func(ModuleFieldTypeDetector, string) (string, string, string, error)
-
- // ASTFormatter allows different SQL flavours to alater the default AST formatting flow.
- ASTFormatter ASTFormatterFn
+ // schema upgrade interface
+ Upgrader schema.Upgrader
}
)
@@ -122,32 +90,32 @@ var (
dsnMasker = regexp.MustCompile("(.)(?:.*)(.):(.)(?:.*)(.)@")
)
-// MaskedDSN replaces username & password from DSN string so it's usable for logging
+// MaskedDSN replaces username & password from DSN string dso it's usable for logging
func (c *Config) MaskedDSN() string {
return dsnMasker.ReplaceAllString(c.DataSourceName, "$1****$2:$3****$4@")
}
func (c *Config) SetDefaults() {
- if c.PlaceholderFormat == nil {
- c.PlaceholderFormat = squirrel.Question
- }
+ //if c.PlaceholderFormat == nil {
+ // c.PlaceholderFormat = squirrel.Question
+ //}
if c.TxMaxRetries == 0 {
c.TxMaxRetries = TxRetryHardLimit
}
- if c.TxRetryErrHandler == nil {
- // Default transaction retry handler
- c.TxRetryErrHandler = TxNoRetry
- }
-
- if c.ErrorHandler == nil {
- c.ErrorHandler = ErrHandlerFallthrough
- }
-
- if c.UpsertBuilder == nil {
- c.UpsertBuilder = UpsertBuilder
- }
+ //if c.TxRetryErrHandler == nil {
+ // // Default transaction retry handler
+ // c.TxRetryErrHandler = TxNoRetry
+ //}
+ //
+ //if c.ErrorHandler == nil {
+ // c.ErrorHandler = ErrHandlerFallthrough
+ //}
+ //
+ //if c.UpsertBuilder == nil {
+ // c.UpsertBuilder = UpsertBuilder
+ //}
// ** ** ** ** ** ** ** ** ** ** ** ** ** **
@@ -184,13 +152,29 @@ func (c *Config) SetDefaults() {
c.ConnTryMax = 99
}
- if c.TriggerHandlers == nil {
- c.TriggerHandlers = TriggerHandlers{}
- }
+ //if c.TriggerHandlers == nil {
+ // c.TriggerHandlers = TriggerHandlers{}
+ //}
+ //
+ //if c.SqlSortHandler == nil {
+ // c.SqlSortHandler = SqlSortHandler
+ //}
- if c.SqlSortHandler == nil {
- c.SqlSortHandler = SqlSortHandler
- }
+ //if c.Functions == nil {
+ // c.Functions = func(ident string, args ...interface{}) (*db.RawExpr, error) {
+ // switch strings.ToUpper(ident) {
+ // case "LOWER":
+ // if len(args) != 1 {
+ // return nil, errors.Internal("LOWER() function expects exactly 1 argument")
+ // }
+ // return db.Raw("LOWER(?)", args[0]), nil
+ // }
+ //
+ // return nil, errors.Internal("unknown function %q", ident)
+ // }
+ //}
+ c.Functions.SetDefaults()
+ c.Filters.SetDefaults()
}
// ParseExtra parses extra params (params starting with *)
@@ -276,3 +260,18 @@ func (c *Config) ParseExtra() (err error) {
return nil
}
+
+func (f *Functions) SetDefaults() {
+ if f.LOWER == nil {
+ f.LOWER = func(value interface{}) exp.SQLFunctionExpression {
+ return goqu.Func("LOWER", value)
+ }
+ }
+
+ if f.DATE == nil {
+ f.DATE = func(value interface{}) exp.SQLFunctionExpression {
+ return goqu.Func("DATE", value)
+ }
+ }
+
+}
diff --git a/store/adapters/rdbms/connect.go b/store/adapters/rdbms/connect.go
new file mode 100644
index 000000000..1eb553183
--- /dev/null
+++ b/store/adapters/rdbms/connect.go
@@ -0,0 +1,194 @@
+package rdbms
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "time"
+
+ "github.com/cortezaproject/corteza-server/pkg/healthcheck"
+ "github.com/cortezaproject/corteza-server/pkg/sentry"
+ "github.com/jmoiron/sqlx"
+ "go.uber.org/zap"
+)
+
+type (
+ //schemaUpgradeGenerator interface {
+ // TableExists(string) bool
+ // CreateTable(t *ddl.Table) string
+ // CreateIndexes(ii ...*ddl.Index) []string
+ //}
+
+ // Store - Corteza RDBMS persistence layer
+ //Store struct {
+ // config *Config
+ //
+ // // Schema upgrade generator converts internal upgrade config
+ // // to implementation specific SQL
+ // sug schemaUpgradeGenerator
+ //
+ // db dbLayer
+ //
+ // // Logger for connection
+ // logger *zap.Logger
+ //}
+
+ dbLayer interface {
+ sqlx.ExecerContext
+ SelectContext(context.Context, interface{}, string, ...interface{}) error
+ GetContext(context.Context, interface{}, string, ...interface{}) error
+ QueryRowContext(context.Context, string, ...interface{}) *sql.Row
+ QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
+ }
+
+ dbTransactionMaker interface {
+ BeginTxx(ctx context.Context, opts *sql.TxOptions) (*sqlx.Tx, error)
+ }
+)
+
+const (
+ // TxRetryHardLimit is the absolute maximum retries we'll allow
+ TxRetryHardLimit = 100
+
+ DefaultSliceCapacity = 1000
+
+ MinEnsureFetchLimit = 10
+ MaxRefetches = 100
+
+ MaxLimit = 1000
+)
+
+// Connect is called from the addapter's Connect function
+//
+// It is intentionally not compatible with store.ConnectorFn
+// and can not be used to register
+func Connect(ctx context.Context, cfg *Config) (s *Store, err error) {
+ return s, func() error {
+ if err = cfg.ParseExtra(); err != nil {
+ return err
+ }
+
+ cfg.SetDefaults()
+ s = &Store{
+ config: cfg,
+ }
+
+ return s.Connect(ctx)
+ }()
+}
+
+// WithTx spins up new store instance with transaction
+func (s *Store) withTx(tx dbLayer) *Store {
+ return &Store{
+ config: s.config,
+ //sug: s.sug,
+ db: tx,
+ }
+}
+
+func (s Store) DB() dbLayer {
+ return s.db
+}
+
+func (s *Store) Connect(ctx context.Context) error {
+ s.log(ctx).Debug("opening connection", zap.String("driver", s.config.DriverName), zap.String("dsn", s.config.MaskedDSN()))
+
+ db, err := sql.Open(s.config.DriverName, s.config.DataSourceName)
+ if err != nil {
+ return err
+ }
+
+ healthcheck.Defaults().Add(dbHealthcheck(db), "Store/RDBMS/"+s.config.DriverName)
+
+ dbx := sqlx.NewDb(db, s.config.DriverName)
+ s.log(ctx).Debug(
+ "setting connection parameters",
+ zap.Int("MaxOpenConns", s.config.MaxOpenConns),
+ zap.Duration("MaxLifetime", s.config.ConnMaxLifetime),
+ zap.Int("MaxIdleConns", s.config.MaxIdleConns),
+ )
+
+ dbx.SetMaxOpenConns(s.config.MaxOpenConns)
+ dbx.SetConnMaxLifetime(s.config.ConnMaxLifetime)
+ dbx.SetMaxIdleConns(s.config.MaxIdleConns)
+
+ if err = s.tryToConnect(ctx, dbx); err != nil {
+ return err
+ }
+
+ s.db = dbx
+ return err
+}
+
+func (s Store) tryToConnect(ctx context.Context, db *sqlx.DB) error {
+ var (
+ connErrCh = make(chan error, 1)
+ patience = time.Now().Add(s.config.ConnTryPatience)
+ )
+
+ go func() {
+ defer sentry.Recover()
+
+ var (
+ err error
+ try = 0
+
+ log = s.log(ctx).
+ // Make a small adjustment when
+ // collecting callers from the callstack for this
+ WithOptions(zap.AddCallerSkip(-2))
+ )
+
+ for {
+ try++
+
+ if s.config.ConnTryMax <= try {
+ connErrCh <- fmt.Errorf("could not connect in %d tries", try)
+ return
+ }
+
+ if err = db.PingContext(ctx); err != nil {
+
+ if time.Now().After(patience) {
+ // don't make too much fuss
+ // if we're in patience mode
+ log.Warn(
+ "could not connect to the database",
+ zap.Error(err),
+ zap.Int("try", try),
+ zap.Float64("delay", s.config.ConnTryBackoffDelay.Seconds()),
+ )
+ }
+
+ select {
+ case <-ctx.Done():
+ // Forced break
+ break
+ case <-time.After(s.config.ConnTryBackoffDelay):
+ // Wait before next try
+ continue
+ }
+ }
+
+ log.Debug("connected to the database")
+ break
+ }
+
+ connErrCh <- err
+ }()
+
+ to := s.config.ConnTryTimeout * time.Duration(s.config.ConnTryMax*2)
+ select {
+ case err := <-connErrCh:
+ return err
+ case <-time.After(to):
+ // Wait before next try
+ return fmt.Errorf("timedout after %.2fs", to.Seconds())
+ case <-ctx.Done():
+ return fmt.Errorf("connection cancelled")
+ }
+}
+
+func dbHealthcheck(db *sql.DB) func(ctx context.Context) error {
+ return db.PingContext
+}
diff --git a/store/rdbms/builders/cursor.go b/store/adapters/rdbms/cursor.go
similarity index 92%
rename from store/rdbms/builders/cursor.go
rename to store/adapters/rdbms/cursor.go
index 9d0b618b9..12e1de059 100644
--- a/store/rdbms/builders/cursor.go
+++ b/store/adapters/rdbms/cursor.go
@@ -1,8 +1,11 @@
-package builders
+package rdbms
import (
"fmt"
"reflect"
+
+ "github.com/cortezaproject/corteza-server/pkg/filter"
+ "github.com/doug-martin/goqu/v9"
)
type (
@@ -34,6 +37,15 @@ type (
cursorKeyMapper func(string) (KeyMap, error)
)
+func cursor(cursor *filter.PagingCursor) ([]goqu.Expression, error) {
+ sql, args, err := CursorCondition(cursor, nil).ToSql()
+ if err != nil {
+ return nil, err
+ }
+
+ return []goqu.Expression{goqu.Literal(sql, args...)}, nil
+}
+
// Builds a complex condition to filter rows before/after row that
// the paging cursor points to
func CursorCondition(pc pagingCursor, keyMapper cursorKeyMapper) *cursorCondition {
diff --git a/store/rdbms/builders/cursors_test.go b/store/adapters/rdbms/cursors_test.go
similarity index 99%
rename from store/rdbms/builders/cursors_test.go
rename to store/adapters/rdbms/cursors_test.go
index 26c995cf5..0565d0b4b 100644
--- a/store/rdbms/builders/cursors_test.go
+++ b/store/adapters/rdbms/cursors_test.go
@@ -1,9 +1,10 @@
-package builders
+package rdbms
import (
+ "testing"
+
"github.com/cortezaproject/corteza-server/pkg/filter"
"github.com/stretchr/testify/require"
- "testing"
)
func Test_buildCursorCond(t *testing.T) {
diff --git a/store/adapters/rdbms/custom_applications.go b/store/adapters/rdbms/custom_applications.go
new file mode 100644
index 000000000..65dda2f8d
--- /dev/null
+++ b/store/adapters/rdbms/custom_applications.go
@@ -0,0 +1,94 @@
+package rdbms
+
+import (
+ "context"
+
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+)
+
+func (s Store) ApplicationMetrics(ctx context.Context) (_ *systemType.ApplicationMetrics, err error) {
+ var (
+ aux = struct {
+ Total uint `db:"total"`
+ Deleted uint `db:"deleted"`
+ Valid uint `db:"valid"`
+ }{}
+
+ query = applicationSelectQuery(s.config.Dialect).
+ Select(timestampStatExpr("deleted")...)
+ )
+
+ if err = s.QueryOne(ctx, query, &aux); err != nil {
+ return nil, err
+ }
+
+ return &systemType.ApplicationMetrics{
+ Total: aux.Total,
+ Deleted: aux.Deleted,
+ Valid: aux.Valid,
+ }, nil
+}
+
+func (s Store) ReorderApplications(ctx context.Context, order []uint64) (err error) {
+ //var (
+ // apps systemType.ApplicationSet
+ // appMap = map[uint64]bool{}
+ // weight = 1
+ //
+ // f = systemType.ApplicationFilter{}
+ //)
+
+ //s.Query(ctx, applicationSelectQuery())
+ //if err = s.applicationCollection(ctx).Find().All(apps); err != nil {
+ // return
+ //}
+ //
+ //if apps, _, err = s.SearchApplications(ctx, f); err != nil {
+ // return
+ //}
+ //
+ //for _, app := range apps {
+ // appMap[app.ID] = true
+ //}
+ //
+ //// honor parameter first
+ //for _, id := range order {
+ // if appMap[id] {
+ // appMap[id] = false
+ //
+ // app := apps.FindByID(id)
+ // if app == nil {
+ // continue
+ // }
+ //
+ // app.Weight = weight
+ // weight++
+ // }
+ //}
+ //
+ //for id, update := range appMap {
+ // if !update {
+ // continue
+ // }
+ //
+ // app := apps.FindByID(id)
+ // if app == nil {
+ // continue
+ // }
+ //
+ // app.Weight = weight
+ // weight++
+ //}
+ //
+ //for _, app := range apps {
+ // err = s.applicationCollection(ctx).
+ // Find(db.Cond{"id": app.ID}).
+ // Update(app)
+ //
+ // if err != nil {
+ // return
+ // }
+ //}
+ //
+ return
+}
diff --git a/store/adapters/rdbms/custom_auth_oa2tokens.go b/store/adapters/rdbms/custom_auth_oa2tokens.go
new file mode 100644
index 000000000..8d91be65d
--- /dev/null
+++ b/store/adapters/rdbms/custom_auth_oa2tokens.go
@@ -0,0 +1,28 @@
+package rdbms
+
+import (
+ "context"
+ "time"
+
+ "github.com/doug-martin/goqu/v9"
+)
+
+func (s Store) DeleteExpiredAuthOA2Tokens(ctx context.Context) error {
+ return s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, goqu.C("expires_at").Lt(time.Now())))
+}
+
+func (s Store) DeleteAuthOA2TokenByCode(ctx context.Context, code string) error {
+ return s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, goqu.C("code").Eq(code)))
+}
+
+func (s Store) DeleteAuthOA2TokenByAccess(ctx context.Context, access string) error {
+ return s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, goqu.C("access").Eq(access)))
+}
+
+func (s Store) DeleteAuthOA2TokenByRefresh(ctx context.Context, refresh string) error {
+ return s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, goqu.C("refresh").Eq(refresh)))
+}
+
+func (s Store) DeleteAuthOA2TokenByUserID(ctx context.Context, userID uint64) error {
+ return s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, goqu.C("rel_user").Eq(userID)))
+}
diff --git a/store/adapters/rdbms/custom_auth_sessions.go b/store/adapters/rdbms/custom_auth_sessions.go
new file mode 100644
index 000000000..b043cdf79
--- /dev/null
+++ b/store/adapters/rdbms/custom_auth_sessions.go
@@ -0,0 +1,16 @@
+package rdbms
+
+import (
+ "context"
+ "time"
+
+ "github.com/doug-martin/goqu/v9"
+)
+
+func (s Store) DeleteExpiredAuthSessions(ctx context.Context) error {
+ return s.Exec(ctx, authSessionDeleteQuery(s.config.Dialect, goqu.C("expires_at").Lt(time.Now())))
+}
+
+func (s Store) DeleteAuthSessionsByUserID(ctx context.Context, userID uint64) error {
+ return s.Exec(ctx, authSessionDeleteQuery(s.config.Dialect, goqu.C("rel_user").Eq(userID)))
+}
diff --git a/store/adapters/rdbms/custom_compose_pages.go b/store/adapters/rdbms/custom_compose_pages.go
new file mode 100644
index 000000000..4d2bce036
--- /dev/null
+++ b/store/adapters/rdbms/custom_compose_pages.go
@@ -0,0 +1,10 @@
+package rdbms
+
+import (
+ "context"
+)
+
+func (s Store) ReorderComposePages(ctx context.Context, namespace_id uint64, parent_id uint64, page_ids []uint64) error {
+ //TODO implement me
+ panic("implement me")
+}
diff --git a/store/adapters/rdbms/custom_compose_records.go b/store/adapters/rdbms/custom_compose_records.go
new file mode 100644
index 000000000..f51ee46fa
--- /dev/null
+++ b/store/adapters/rdbms/custom_compose_records.go
@@ -0,0 +1,52 @@
+package rdbms
+
+import (
+ "context"
+
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ "github.com/cortezaproject/corteza-server/pkg/report"
+)
+
+func (s Store) ComposeRecordReport(ctx context.Context, mod *composeType.Module, metrics string, dimensions string, filters string) ([]map[string]interface{}, error) {
+ //TODO implement me
+ panic("implement me")
+}
+
+func (s Store) ComposeRecordDatasource(ctx context.Context, mod *composeType.Module, ld *report.LoadStepDefinition) (report.Datasource, error) {
+ //TODO implement me
+ panic("implement me")
+}
+
+func (s Store) PartialComposeRecordValueUpdate(ctx context.Context, mod *composeType.Module, values ...*composeType.RecordValue) error {
+ //TODO implement me
+ panic("implement me")
+}
+
+func (s Store) ComposeRecordValueRefLookup(ctx context.Context, m *composeType.Module, field string, ref uint64) (uint64, error) {
+ //q := s.composeRecordValuesSelectBuilder().
+ // Join(s.composeRecordTable("crd"), "crv.record_id = crd.id").
+ // Where(squirrel.Eq{
+ // "crv.name": field,
+ // "crv.ref": ref,
+ // "crv.deleted_at": nil,
+ // "crd.module_id": m.ID,
+ // "crd.deleted_at": nil,
+ // }).
+ // Column("record_id").
+ // Limit(1)
+ //
+ //row, err := s.QueryRow(ctx, q)
+ //if errors.Is(err, sql.ErrNoRows) {
+ // return 0, nil
+ //} else if err != nil {
+ // return 0, err
+ //}
+ //
+ //var recordID uint64
+ //if err = row.Scan(&recordID); err != nil {
+ // return 0, err
+ //}
+ //
+ //return recordID, nil
+ return 0, nil
+}
diff --git a/store/adapters/rdbms/custom_labels.go b/store/adapters/rdbms/custom_labels.go
new file mode 100644
index 000000000..52e91aa4c
--- /dev/null
+++ b/store/adapters/rdbms/custom_labels.go
@@ -0,0 +1,16 @@
+package rdbms
+
+import (
+ "context"
+
+ "github.com/doug-martin/goqu/v9"
+)
+
+func (s Store) DeleteExtraLabels(ctx context.Context, kind string, resourceId uint64, name ...string) error {
+ return s.Exec(ctx, labelDeleteQuery(
+ s.config.Dialect,
+ goqu.C("kind").Eq(kind),
+ goqu.C("rel_resource").Eq(resourceId),
+ goqu.C("name").NotIn(name),
+ ))
+}
diff --git a/store/adapters/rdbms/custom_metrics.go b/store/adapters/rdbms/custom_metrics.go
new file mode 100644
index 000000000..4341f747d
--- /dev/null
+++ b/store/adapters/rdbms/custom_metrics.go
@@ -0,0 +1,104 @@
+package rdbms
+
+import (
+ "context"
+ "database/sql"
+ "time"
+
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
+ sqlx "github.com/jmoiron/sqlx/types"
+)
+
+// A temporary alias for old type that was used handle JSON encoded data
+type rawJson = sqlx.JSONText
+
+// multiDailyMetrics simplifies fetching of multiple daily metrics
+//
+// This function is copied from old repository and adapted to work under store,
+// might be good to refactor it to fit into this store pattern a bit more
+func (s Store) multiDailyMetrics(ctx context.Context, tbl exp.IdentifierExpression, expr []goqu.Expression, fields []string, mm ...*[]uint) (err error) {
+ for m := 0; m < len(mm); m++ {
+ *mm[m], err = s.dailyMetrics(ctx, tbl, expr, fields[m])
+ if err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// dailyMetrics aids repositories on simple stat building queries
+//
+// Returns a slice of numbers (timestamp + value pairs)
+//
+// This function is copied from old repository and adapted to work under store,
+// might be good to refactor it to fit into this store pattern a bit more
+func (s Store) dailyMetrics(ctx context.Context, tbl exp.IdentifierExpression, expr []goqu.Expression, field string) ([]uint, error) {
+ const format = "2006-01-02"
+
+ var (
+ rval = make([]uint, 0)
+
+ d time.Time
+ ts string
+ c uint
+
+ rows *sql.Rows
+ )
+
+ return rval, func() (err error) {
+ daily := s.config.Functions.DATE(goqu.C(field))
+ query := s.config.Dialect.
+ Select(daily, goqu.COUNT(goqu.Star()).As("value")).
+ From(tbl).
+ Where(goqu.C(field).IsNotNull(), goqu.And(expr...)).
+ GroupBy(daily).
+ Order(exp.NewOrderedExpression(daily, exp.AscDir, exp.NoNullsSortType))
+
+ if rows, err = s.Query(ctx, query); err != nil {
+ return err
+ }
+
+ defer rows.Close()
+ for rows.Next() {
+ if err = rows.Scan(&ts, &c); err != nil {
+ return err
+ }
+
+ d = time.Time{}
+ if len(ts) >= len(format) {
+ if d, err = time.Parse(format, ts[0:len(format)]); err != nil {
+ return err
+ }
+ }
+
+ rval = append(rval, uint(d.Unix()), c)
+ }
+
+ return
+ }()
+}
+
+// Assembles select expression that calculates total + each given ts field + valid
+//
+func timestampStatExpr(fields ...string) []interface{} {
+ var (
+ valid = []goqu.Expression{}
+ ee = []interface{}{goqu.COUNT(goqu.Star()).As("total")}
+
+ sum = func(field string) goqu.Expression {
+ return goqu.COALESCE(
+ goqu.SUM(goqu.Case().When(goqu.C(field+"_at").IsNotNull(), 1).Else(0)),
+ goqu.L("0"),
+ ).As(field)
+ }
+ )
+
+ for _, field := range fields {
+ ee = append(ee, sum(field))
+ valid = append(valid, goqu.C(field+"_at").IsNull())
+ }
+
+ return append(ee, goqu.SUM(goqu.Case().When(goqu.And(valid...), 1).Else(0)).As("valid"))
+}
diff --git a/store/adapters/rdbms/custom_metrics_test.go b/store/adapters/rdbms/custom_metrics_test.go
new file mode 100644
index 000000000..cc8530682
--- /dev/null
+++ b/store/adapters/rdbms/custom_metrics_test.go
@@ -0,0 +1,37 @@
+package rdbms
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/doug-martin/goqu/v9"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_timestampStats(t *testing.T) {
+ tests := []struct {
+ fields []string
+ sql string
+ }{
+ {
+ fields: []string{"a"},
+ sql: `SELECT COUNT(*), SUM(CASE WHEN ("a_at" IS NOT NULL) THEN 1 ELSE 0 END) AS "a", SUM(CASE WHEN ("a_at" IS NULL) THEN 1 ELSE 0 END) AS "valid"`,
+ },
+ {
+ fields: []string{"a", "b"},
+ sql: `SELECT COUNT(*), SUM(CASE WHEN ("a_at" IS NOT NULL) THEN 1 ELSE 0 END) AS "a", SUM(CASE WHEN ("b_at" IS NOT NULL) THEN 1 ELSE 0 END) AS "b", SUM(CASE WHEN (("a_at" IS NULL) AND ("b_at" IS NULL)) THEN 1 ELSE 0 END) AS "valid"`,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(strings.Join(tt.fields, "+"), func(t *testing.T) {
+ var (
+ req = require.New(t)
+ ee = timestampStatExpr(tt.fields...)
+ sql, _, err = goqu.Select(ee...).ToSQL()
+ )
+
+ req.NoError(err)
+ req.Equal(tt.sql, sql)
+ })
+ }
+}
diff --git a/store/adapters/rdbms/custom_rbac.go b/store/adapters/rdbms/custom_rbac.go
new file mode 100644
index 000000000..6d909420c
--- /dev/null
+++ b/store/adapters/rdbms/custom_rbac.go
@@ -0,0 +1,17 @@
+package rdbms
+
+import (
+ "context"
+
+ "github.com/doug-martin/goqu/v9"
+)
+
+func (s Store) TransferRbacRules(ctx context.Context, src, dst uint64) (err error) {
+ var (
+ transfer = s.config.Dialect.Update(rbacRuleTable).
+ Set(goqu.Record{"rel_role": dst}).
+ Where(goqu.Ex{"rel_role": src})
+ )
+
+ return s.Exec(ctx, transfer)
+}
diff --git a/store/adapters/rdbms/custom_resource_translations.go b/store/adapters/rdbms/custom_resource_translations.go
new file mode 100644
index 000000000..db51e3ec2
--- /dev/null
+++ b/store/adapters/rdbms/custom_resource_translations.go
@@ -0,0 +1,13 @@
+package rdbms
+
+import (
+ "context"
+
+ "github.com/cortezaproject/corteza-server/pkg/locale"
+ "golang.org/x/text/language"
+)
+
+func (s Store) TransformResource(ctx context.Context, lang language.Tag) (map[string]map[string]*locale.ResourceTranslation, error) {
+ //TODO implement me
+ panic("implement me")
+}
diff --git a/store/adapters/rdbms/custom_roles.go b/store/adapters/rdbms/custom_roles.go
new file mode 100644
index 000000000..e4f909eaa
--- /dev/null
+++ b/store/adapters/rdbms/custom_roles.go
@@ -0,0 +1,66 @@
+package rdbms
+
+import (
+ "context"
+
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "github.com/doug-martin/goqu/v9"
+)
+
+func (s Store) RoleMetrics(ctx context.Context) (m *systemType.RoleMetrics, err error) {
+ var (
+ aux = struct {
+ Total uint `db:"total"`
+ Deleted uint `db:"deleted"`
+ Valid uint `db:"valid"`
+ Archived uint `db:"archived"`
+ }{}
+
+ query = roleSelectQuery(s.config.Dialect).
+ Select(timestampStatExpr("deleted", "archived")...)
+ )
+
+ if err = s.QueryOne(ctx, query, &aux); err != nil {
+ return nil, err
+ }
+
+ m = &systemType.RoleMetrics{
+ Total: aux.Total,
+ Valid: aux.Valid,
+ Deleted: aux.Deleted,
+ Archived: aux.Archived,
+ }
+
+ // Fetch daily metrics for created, updated, deleted and suspended users
+ err = s.multiDailyMetrics(
+ ctx,
+ roleTable,
+ []goqu.Expression{},
+ []string{
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "archived_at",
+ },
+ &m.DailyCreated,
+ &m.DailyUpdated,
+ &m.DailyDeleted,
+ &m.DailyArchived,
+ )
+
+ if err != nil {
+ return nil, err
+ }
+
+ return
+}
+
+func (s Store) TransferRoleMembers(ctx context.Context, src, dst uint64) (err error) {
+ var (
+ transfer = s.config.Dialect.Update(roleMemberTable).
+ Set(goqu.Record{"rel_role": dst}).
+ Where(goqu.Ex{"rel_role": src})
+ )
+
+ return s.Exec(ctx, transfer)
+}
diff --git a/store/adapters/rdbms/custom_users.go b/store/adapters/rdbms/custom_users.go
new file mode 100644
index 000000000..8baee1634
--- /dev/null
+++ b/store/adapters/rdbms/custom_users.go
@@ -0,0 +1,81 @@
+package rdbms
+
+import (
+ "context"
+
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "github.com/doug-martin/goqu/v9"
+)
+
+func (s Store) CountUsers(ctx context.Context, f systemType.UserFilter) (c uint, _ error) {
+ var (
+ aux = struct {
+ Count uint `db:"count"`
+ }{}
+ expr, _, err = s.config.Filters.User(f)
+
+ query = s.config.Dialect.
+ From(userTable).
+ Select(goqu.COUNT(goqu.Star()).As("count"))
+ )
+
+ if err != nil {
+ return
+ }
+
+ if err = s.QueryOne(ctx, query.Where(expr...).Limit(1), &aux); err != nil {
+ return
+ }
+
+ return aux.Count, nil
+}
+
+func (s Store) UserMetrics(ctx context.Context) (m *systemType.UserMetrics, err error) {
+ var (
+ aux = struct {
+ Total uint `db:"total"`
+ Deleted uint `db:"deleted"`
+ Valid uint `db:"valid"`
+ Suspended uint `db:"suspended"`
+ }{}
+
+ query = userSelectQuery(s.config.Dialect).
+ Select(timestampStatExpr("deleted", "suspended")...)
+ )
+
+ if err = s.QueryOne(ctx, query, &aux); err != nil {
+ return nil, err
+ }
+
+ m = &systemType.UserMetrics{
+ Total: aux.Total,
+ Valid: aux.Valid,
+ Deleted: aux.Deleted,
+ Suspended: aux.Suspended,
+ }
+
+ // Fetch daily metrics for created, updated, deleted and suspended users
+ err = s.multiDailyMetrics(
+ ctx,
+ userTable,
+ []goqu.Expression{
+ goqu.C("kind").Eq(""),
+ },
+ []string{
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "suspended_at",
+ },
+ &m.DailyCreated,
+ &m.DailyUpdated,
+ &m.DailyDeleted,
+ &m.DailySuspended,
+ )
+
+ if err != nil {
+ return nil, err
+ }
+
+ return
+}
diff --git a/store/mysql/mysql.go b/store/adapters/rdbms/drivers/mysql/connect.go
similarity index 72%
rename from store/mysql/mysql.go
rename to store/adapters/rdbms/drivers/mysql/connect.go
index 2100d1e6a..810f659ae 100644
--- a/store/mysql/mysql.go
+++ b/store/adapters/rdbms/drivers/mysql/connect.go
@@ -3,23 +3,17 @@ package mysql
import (
"context"
"database/sql"
- "errors"
"fmt"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/ql"
+ "strings"
+
+ "github.com/cortezaproject/corteza-server/pkg/errors"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/instrumentation"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/instrumentation"
+ "github.com/doug-martin/goqu/v9"
+ _ "github.com/doug-martin/goqu/v9/dialect/mysql"
"github.com/go-sql-driver/mysql"
"github.com/ngrok/sqlmw"
- "go.uber.org/zap"
- "strings"
-)
-
-type (
- Store struct {
- *rdbms.Store
- }
)
func init() {
@@ -27,41 +21,42 @@ func init() {
sql.Register("mysql+debug", sqlmw.Driver(new(mysql.MySQLDriver), instrumentation.Debug()))
}
-func Connect(ctx context.Context, dsn string) (store.Storer, error) {
+func Connect(ctx context.Context, dsn string) (_ store.Storer, err error) {
var (
- err error
cfg *rdbms.Config
-
- s = new(Store)
+ s *rdbms.Store
)
if cfg, err = ProcDataSourceName(dsn); err != nil {
- return nil, err
+ return
}
- cfg.PlaceholderFormat = squirrel.Question
+ //cfg.PlaceholderFormat = squirrel.Question
cfg.TxRetryErrHandler = txRetryErrHandler
cfg.ErrorHandler = errorHandler
- cfg.UpsertBuilder = UpsertBuilder
- cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
- cfg.SqlSortHandler = SqlSortHandler
+ //cfg.UpsertBuilder = UpsertBuilder
+ //cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
+ //cfg.SqlSortHandler = SqlSortHandler
- if s.Store, err = rdbms.Connect(ctx, cfg); err != nil {
- return nil, err
+ if s, err = rdbms.Connect(ctx, cfg); err != nil {
+ return
}
// See https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_ansi
// for details
- s.DB().ExecContext(ctx, "SET SESSION sql_mode = 'ANSI'")
+ if _, err = s.DB().ExecContext(ctx, "SET SESSION sql_mode = 'ANSI'"); err != nil {
+ return
+ }
- ql.QueryEncoder = &QueryEncoder{}
+ //ql.QueryEncoder = &QueryEncoder{}
+ cfg.Upgrader = NewUpgrader(s)
return s, nil
}
-func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
- return (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s))
-}
+//func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
+// return (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s))
+//}
// ProcDataSourceName validates given DSN and ensures
// params are present and correct
@@ -83,7 +78,9 @@ func ProcDataSourceName(in string) (*rdbms.Config, error) {
var (
endOfSchema = strings.Index(in, schemeDel)
- c = &rdbms.Config{}
+ c = &rdbms.Config{
+ Dialect: goqu.Dialect("mysql"),
+ }
)
if endOfSchema > 0 && (in[:endOfSchema] == validScheme || strings.HasPrefix(in[:endOfSchema], validScheme+"+")) {
diff --git a/store/mysql/mysql_test.go b/store/adapters/rdbms/drivers/mysql/connect_test.go
similarity index 89%
rename from store/mysql/mysql_test.go
rename to store/adapters/rdbms/drivers/mysql/connect_test.go
index b6b1bc001..abda8ef1e 100644
--- a/store/mysql/mysql_test.go
+++ b/store/adapters/rdbms/drivers/mysql/connect_test.go
@@ -1,9 +1,10 @@
package mysql
import (
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/stretchr/testify/require"
"testing"
+
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/stretchr/testify/require"
)
func TestProcDataSourceName(t *testing.T) {
diff --git a/store/mysql/upgrade.go b/store/adapters/rdbms/drivers/mysql/upgrade.go
similarity index 77%
rename from store/mysql/upgrade.go
rename to store/adapters/rdbms/drivers/mysql/upgrade.go
index 8a1c6c49d..ed51de451 100644
--- a/store/mysql/upgrade.go
+++ b/store/adapters/rdbms/drivers/mysql/upgrade.go
@@ -8,39 +8,43 @@ import (
"database/sql"
"fmt"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/schema"
_ "github.com/go-sql-driver/mysql"
"go.uber.org/zap"
)
type (
upgrader struct {
- s *Store
- log *zap.Logger
- ddl *ddl.Generator
+ log *zap.Logger
+ s *rdbms.Store
+ dialect *schema.CommonDialect
}
)
// NewUpgrader returns MySQL schema upgrader
-func NewUpgrader(log *zap.Logger, store *Store) *upgrader {
- var u = &upgrader{store, log, ddl.NewGenerator(log)}
+func NewUpgrader(store *rdbms.Store) *upgrader {
+ var g = &upgrader{
+ log: zap.NewNop(),
+ s: store,
+ dialect: schema.NewCommonDialect(),
+ }
// All modifications we need for the DDL generator
// to properly support MySQL dialect:
- u.ddl.AddTemplate("create-table-suffix", "ENGINE=InnoDB DEFAULT CHARSET=utf8")
+ g.dialect.AddTemplate("create-table-suffix", "ENGINE=InnoDB DEFAULT CHARSET=utf8")
// Sadly, MySQL does not support partial indexes
//
// To work around this, we'll ignore partial indexes
// and solve this on application level
- u.ddl.AddTemplate(
+ g.dialect.AddTemplate(
"create-index",
`{{ if not .Condition }}CREATE {{ if .Unique }}UNIQUE {{ end }}INDEX {{ template "index-name" . }} ON {{ .Table }} {{ template "index-fields" .Fields }}{{ else }}SELECT 1 -- dummy sql, just to prevent "empty query" errors...{{ end }}`,
)
- u.ddl.AddTemplate("if-not-exists-clause", "")
- u.ddl.AddTemplate("index-fields", `
+ g.dialect.AddTemplate("if-not-exists-clause", "")
+ g.dialect.AddTemplate("index-fields", `
({{ range $n, $f := . -}}
{{ if $n }}, {{ end }}
{{- if .Expr}}({{ end }}
@@ -52,28 +56,32 @@ func NewUpgrader(log *zap.Logger, store *Store) *upgrader {
`)
// Cover mysql exceptions
- u.ddl.AddTemplateFunc("columnType", func(ct *ddl.ColumnType) string {
+ g.dialect.AddTemplateFunc("columnType", func(ct *schema.ColumnType) string {
switch ct.Type {
- case ddl.ColumnTypeIdentifier:
+ case schema.ColumnTypeIdentifier:
return "BIGINT UNSIGNED"
- case ddl.ColumnTypeText:
+ case schema.ColumnTypeText:
if y, has := ct.Flags["mysqlLongText"].(bool); has && y {
return "LONGTEXT"
}
return "TEXT"
- case ddl.ColumnTypeBinary:
+ case schema.ColumnTypeBinary:
return "BLOB"
- case ddl.ColumnTypeTimestamp:
+ case schema.ColumnTypeTimestamp:
return "DATETIME"
- case ddl.ColumnTypeBoolean:
+ case schema.ColumnTypeBoolean:
return "TINYINT(1)"
default:
- return ddl.GenColumnType(ct)
+ return schema.GenColumnType(ct)
}
})
- return u
+ return g
+}
+
+func (u *upgrader) SetLogger(l *zap.Logger) {
+ u.log = l
}
// Before runs before all tables are upgraded
@@ -129,31 +137,31 @@ func (u upgrader) Before(ctx context.Context) error {
}
}
- return rdbms.GenericUpgrades(u.log, u).Before(ctx)
+ return schema.CommonUpgrades(u.log, u).Before(ctx)
}
// After runs after all tables are upgraded
func (u upgrader) After(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).After(ctx)
+ return schema.CommonUpgrades(u.log, u).After(ctx)
}
// CreateTable is triggered for every table defined in the rdbms package
//
// It checks if table is missing and creates it, otherwise
// it runs
-func (u upgrader) CreateTable(ctx context.Context, t *ddl.Table) (err error) {
+func (u upgrader) CreateTable(ctx context.Context, t *schema.Table) (err error) {
var exists bool
if exists, err = u.TableExists(ctx, t.Name); err != nil {
return
}
if !exists {
- if err = u.Exec(ctx, u.ddl.CreateTable(t)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateTable(t)); err != nil {
return err
}
for _, i := range t.Indexes {
- if err = u.Exec(ctx, u.ddl.CreateIndex(i)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateIndex(i)); err != nil {
return fmt.Errorf("could not create index %s on table %s: %w", i.Name, i.Table, err)
}
}
@@ -187,8 +195,8 @@ func (u upgrader) Exec(ctx context.Context, sql string, aa ...interface{}) error
}
// upgradeTable applies any necessary changes connected to that specific table
-func (u upgrader) upgradeTable(ctx context.Context, t *ddl.Table) error {
- g := rdbms.GenericUpgrades(u.log, u)
+func (u upgrader) upgradeTable(ctx context.Context, t *schema.Table) error {
+ g := schema.CommonUpgrades(u.log, u)
switch t.Name {
default:
@@ -207,14 +215,14 @@ func (u upgrader) TableExists(ctx context.Context, table string) (bool, error) {
return true, nil
}
-func (u upgrader) TableSchema(ctx context.Context, table string) (ddl.Columns, error) {
+func (u upgrader) TableSchema(ctx context.Context, table string) (schema.Columns, error) {
return nil, fmt.Errorf("pending implementation")
}
// AddColumn adds column to table
-func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column) (added bool, err error) {
+func (u upgrader) AddColumn(ctx context.Context, table string, col *schema.Column) (added bool, err error) {
err = func() error {
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -223,11 +231,11 @@ func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column)
return nil
}
- if col.Type.Type == ddl.ColumnTypeText || col.Type.Type == ddl.ColumnTypeJson {
+ if col.Type.Type == schema.ColumnTypeText || col.Type.Type == schema.ColumnTypeJson {
col.DefaultValue = ""
}
- if err = u.Exec(ctx, u.ddl.AddColumn(table, col)); err != nil {
+ if err = u.Exec(ctx, u.dialect.AddColumn(table, col)); err != nil {
return err
}
@@ -245,7 +253,7 @@ func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column)
// DropColumn drops column from table
func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped bool, err error) {
err = func() error {
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -254,7 +262,7 @@ func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped
return nil
}
- if err = u.Exec(ctx, u.ddl.DropColumn(table, column)); err != nil {
+ if err = u.Exec(ctx, u.dialect.DropColumn(table, column)); err != nil {
return err
}
@@ -276,7 +284,7 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
return nil
}
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -296,7 +304,7 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
}
- if err = u.Exec(ctx, u.ddl.RenameColumn(table, oldName, newName)); err != nil {
+ if err = u.Exec(ctx, u.dialect.RenameColumn(table, oldName, newName)); err != nil {
return err
}
@@ -311,20 +319,20 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
return
}
-func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *ddl.Index) (added bool, err error) {
- if err = u.Exec(ctx, u.ddl.AddPrimaryKey(table, ind)); err != nil {
+func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *schema.Index) (added bool, err error) {
+ if err = u.Exec(ctx, u.dialect.AddPrimaryKey(table, ind)); err != nil {
return false, fmt.Errorf("could not add primary key to table %s: %w", table, err)
}
return true, nil
}
-func (u upgrader) CreateIndex(ctx context.Context, ind *ddl.Index) (added bool, err error) {
+func (u upgrader) CreateIndex(ctx context.Context, ind *schema.Index) (added bool, err error) {
if added, err = u.hasIndex(ctx, ind.Table, ind.Name); added || err != nil {
return
}
- if err = u.Exec(ctx, u.ddl.CreateIndex(ind)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateIndex(ind)); err != nil {
return false, fmt.Errorf("could not create index on table %s: %w", ind.Table, err)
}
@@ -340,7 +348,7 @@ func (u upgrader) hasIndex(ctx context.Context, table, name string) (has bool, e
}
// loads and returns all tables columns
-func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns, err error) {
+func (u upgrader) getColumns(ctx context.Context, table string) (out schema.Columns, err error) {
type (
col struct {
Name string `db:"COLUMN_NAME"`
@@ -364,11 +372,11 @@ func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns
return nil, err
}
- out = make([]*ddl.Column, len(cols))
+ out = make([]*schema.Column, len(cols))
for i := range cols {
- out[i] = &ddl.Column{
+ out[i] = &schema.Column{
Name: cols[i].Name,
- //Type: ddl.ColumnType{},
+ //Type: schema.ColumnType{},
IsNull: cols[i].IsNullable,
//DefaultValue: "",
}
diff --git a/store/postgres/postgres.go b/store/adapters/rdbms/drivers/postgres/connect.go
similarity index 56%
rename from store/postgres/postgres.go
rename to store/adapters/rdbms/drivers/postgres/connect.go
index 5419ed7ed..a6f48a739 100644
--- a/store/postgres/postgres.go
+++ b/store/adapters/rdbms/drivers/postgres/connect.go
@@ -3,24 +3,16 @@ package postgres
import (
"context"
"database/sql"
- "fmt"
"net/url"
"strings"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/ql"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/instrumentation"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/instrumentation"
+ "github.com/doug-martin/goqu/v9"
+ _ "github.com/doug-martin/goqu/v9/dialect/postgres"
"github.com/lib/pq"
"github.com/ngrok/sqlmw"
- "go.uber.org/zap"
-)
-
-type (
- Store struct {
- *rdbms.Store
- }
)
func init() {
@@ -28,40 +20,41 @@ func init() {
sql.Register("postgres+debug", sqlmw.Driver(new(pq.Driver), instrumentation.Debug()))
}
-func Connect(ctx context.Context, dsn string) (store.Storer, error) {
+func Connect(ctx context.Context, dsn string) (_ store.Storer, err error) {
var (
- err error
cfg *rdbms.Config
-
- s = new(Store)
+ s *rdbms.Store
)
if cfg, err = ProcDataSourceName(dsn); err != nil {
- return nil, err
+ return
}
- cfg.PlaceholderFormat = squirrel.Dollar
+ //cfg.PlaceholderFormat = squirrel.Dollar
cfg.ErrorHandler = errorHandler
- cfg.SqlFunctionHandler = sqlFunctionHandler
- cfg.ASTFormatter = sqlASTFormatter
- cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
+ //cfg.SqlFunctionHandler = sqlFunctionHandler
+ //cfg.ASTFormatter = sqlASTFormatter
+ //cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
- if s.Store, err = rdbms.Connect(ctx, cfg); err != nil {
- return nil, err
+ if s, err = rdbms.Connect(ctx, cfg); err != nil {
+ return
}
- ql.QueryEncoder = &QueryEncoder{}
+ // s.Filters
+ cfg.Upgrader = NewUpgrader(s)
+
+ //ql.QueryEncoder = &QueryEncoder{}
return s, nil
}
-func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
- if err = (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s)); err != nil {
- return fmt.Errorf("cannot upgrade postgresql schema: %w", err)
- }
-
- return nil
-}
+//func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
+// if err = (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s)); err != nil {
+// return fmt.Errorf("cannot upgrade postgresql schema: %w", err)
+// }
+//
+// return nil
+//}
// ProcDataSourceName validates given DSN and ensures
// params are present and correct
@@ -87,6 +80,7 @@ func ProcDataSourceName(dsn string) (c *rdbms.Config, err error) {
DriverName: scheme,
DataSourceName: u.String(),
DBName: strings.Trim(u.Path, "/"),
+ Dialect: goqu.Dialect("postgres"),
}, nil
}
diff --git a/store/postgres/upgrade.go b/store/adapters/rdbms/drivers/postgres/upgrade.go
similarity index 73%
rename from store/postgres/upgrade.go
rename to store/adapters/rdbms/drivers/postgres/upgrade.go
index 0e804b491..3abb5d7d2 100644
--- a/store/postgres/upgrade.go
+++ b/store/adapters/rdbms/drivers/postgres/upgrade.go
@@ -7,57 +7,68 @@ import (
"context"
"fmt"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/schema"
"go.uber.org/zap"
)
type (
upgrader struct {
- s *Store
- log *zap.Logger
- ddl *ddl.Generator
+ log *zap.Logger
+ s *rdbms.Store
+ dialect *schema.CommonDialect
}
)
+var (
+ _ schema.Upgrader = &upgrader{}
+)
+
// NewUpgrader returns PostgreSQL schema upgrader
-func NewUpgrader(log *zap.Logger, store *Store) *upgrader {
- var g = &upgrader{store, log, ddl.NewGenerator(log)}
+func NewUpgrader(store *rdbms.Store) *upgrader {
+ var g = &upgrader{
+ log: zap.NewNop(),
+ s: store,
+ dialect: schema.NewCommonDialect(),
+ }
- // All modifications we need for the DDL generator
- // to properly support PostgreSQL dialect
+ // Modification to general DDL dialect to support Postgres requirements
+ g.dialect.AddTemplate("create-table-suffix", "WITHOUT OIDS")
- g.ddl.AddTemplate("create-table-suffix", "WITHOUT OIDS")
return g
}
+func (u *upgrader) SetLogger(l *zap.Logger) {
+ u.log = l
+}
+
// Before runs before all tables are upgraded
func (u upgrader) Before(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).Before(ctx)
+ return schema.CommonUpgrades(u.log, u).Before(ctx)
}
// After runs after all tables are upgraded
func (u upgrader) After(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).After(ctx)
+ return schema.CommonUpgrades(u.log, u).After(ctx)
}
// CreateTable is triggered for every table defined in the rdbms package
//
// It checks if table is missing and creates it, otherwise
// it runs
-func (u upgrader) CreateTable(ctx context.Context, t *ddl.Table) (err error) {
+func (u upgrader) CreateTable(ctx context.Context, t *schema.Table) (err error) {
var exists bool
if exists, err = u.TableExists(ctx, t.Name); err != nil {
return
}
if !exists {
- if err = u.Exec(ctx, u.ddl.CreateTable(t)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateTable(t)); err != nil {
return err
}
for _, i := range t.Indexes {
- if err = u.Exec(ctx, u.ddl.CreateIndex(i)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateIndex(i)); err != nil {
return fmt.Errorf("could not create index %s on table %s: %w", i.Name, i.Table, err)
}
}
@@ -74,8 +85,8 @@ func (u upgrader) Exec(ctx context.Context, sql string, aa ...interface{}) error
}
// upgradeTable applies any necessary changes connected to that specific table
-func (u upgrader) upgradeTable(ctx context.Context, t *ddl.Table) error {
- g := rdbms.GenericUpgrades(u.log, u)
+func (u upgrader) upgradeTable(ctx context.Context, t *schema.Table) error {
+ g := schema.CommonUpgrades(u.log, u)
switch t.Name {
default:
@@ -108,14 +119,14 @@ func (u upgrader) DropTable(ctx context.Context, table string) (dropped bool, er
return true, nil
}
-func (u upgrader) TableSchema(ctx context.Context, table string) (ddl.Columns, error) {
+func (u upgrader) TableSchema(ctx context.Context, table string) (schema.Columns, error) {
return nil, fmt.Errorf("pending implementation")
}
// AddColumn adds column to table
-func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column) (added bool, err error) {
+func (u upgrader) AddColumn(ctx context.Context, table string, col *schema.Column) (added bool, err error) {
err = func() error {
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -124,7 +135,7 @@ func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column)
return nil
}
- if err = u.Exec(ctx, u.ddl.AddColumn(table, col)); err != nil {
+ if err = u.Exec(ctx, u.dialect.AddColumn(table, col)); err != nil {
return err
}
@@ -142,7 +153,7 @@ func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column)
// DropColumn drops column from table
func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped bool, err error) {
err = func() error {
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -151,7 +162,7 @@ func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped
return nil
}
- if err = u.Exec(ctx, u.ddl.DropColumn(table, column)); err != nil {
+ if err = u.Exec(ctx, u.dialect.DropColumn(table, column)); err != nil {
return err
}
@@ -173,7 +184,7 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
return nil
}
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -193,7 +204,7 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
}
- if err = u.Exec(ctx, u.ddl.RenameColumn(table, oldName, newName)); err != nil {
+ if err = u.Exec(ctx, u.dialect.RenameColumn(table, oldName, newName)); err != nil {
return err
}
@@ -208,20 +219,20 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
return
}
-func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *ddl.Index) (added bool, err error) {
- if err = u.Exec(ctx, u.ddl.AddPrimaryKey(table, ind)); err != nil {
+func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *schema.Index) (added bool, err error) {
+ if err = u.Exec(ctx, u.dialect.AddPrimaryKey(table, ind)); err != nil {
return false, fmt.Errorf("could not add primary key to table %s: %w", table, err)
}
return true, nil
}
-func (u upgrader) CreateIndex(ctx context.Context, ind *ddl.Index) (added bool, err error) {
+func (u upgrader) CreateIndex(ctx context.Context, ind *schema.Index) (added bool, err error) {
if added, err = u.hasIndex(ctx, ind.Table, ind.Name); added || err != nil {
return
}
- if err = u.Exec(ctx, u.ddl.CreateIndex(ind)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateIndex(ind)); err != nil {
return false, fmt.Errorf("could not create index on table %s: %w", ind.Table, err)
}
@@ -237,7 +248,7 @@ func (u upgrader) hasIndex(ctx context.Context, table, name string) (has bool, e
}
// loads and returns all tables columns
-func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns, err error) {
+func (u upgrader) getColumns(ctx context.Context, table string) (out schema.Columns, err error) {
type (
col struct {
Name string `db:"column_name"`
@@ -261,11 +272,11 @@ func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns
return nil, err
}
- out = make([]*ddl.Column, len(cols))
+ out = make([]*schema.Column, len(cols))
for i := range cols {
- out[i] = &ddl.Column{
+ out[i] = &schema.Column{
Name: cols[i].Name,
- //Type: ddl.ColumnType{},
+ //Type: schema.ColumnType{},
IsNull: cols[i].IsNullable,
//DefaultValue: "",
}
diff --git a/store/sqlite3/sqlite3.go b/store/adapters/rdbms/drivers/sqlite/connect.go
similarity index 69%
rename from store/sqlite3/sqlite3.go
rename to store/adapters/rdbms/drivers/sqlite/connect.go
index 346edc0ce..a4608840a 100644
--- a/store/sqlite3/sqlite3.go
+++ b/store/adapters/rdbms/drivers/sqlite/connect.go
@@ -1,4 +1,4 @@
-package sqlite3
+package sqlite
import (
"context"
@@ -7,20 +7,12 @@ import (
"fmt"
"strings"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/ql"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/instrumentation"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/instrumentation"
+ "github.com/doug-martin/goqu/v9"
"github.com/mattn/go-sqlite3"
"github.com/ngrok/sqlmw"
- "go.uber.org/zap"
-)
-
-type (
- Store struct {
- *rdbms.Store
- }
)
func init() {
@@ -28,38 +20,38 @@ func init() {
sql.Register("sqlite3+debug", sqlmw.Driver(new(sqlite3.SQLiteDriver), instrumentation.Debug()))
}
-func Connect(ctx context.Context, dsn string) (store.Storer, error) {
+func Connect(ctx context.Context, dsn string) (_ store.Storer, err error) {
var (
- err error
cfg *rdbms.Config
-
- s = new(Store)
+ s *rdbms.Store
)
if cfg, err = ProcDataSourceName(dsn); err != nil {
- return nil, err
+ return
}
- cfg.PlaceholderFormat = squirrel.Dollar
+ //cfg.PlaceholderFormat = squirrel.Dollar
cfg.TxRetryErrHandler = txRetryErrHandler
cfg.ErrorHandler = errorHandler
// Using transactions in SQLite causes table locking
// @todo there must be a better way to go around this
cfg.TxDisabled = true
- cfg.SqlFunctionHandler = sqlFunctionHandler
- cfg.ASTFormatter = sqlASTFormatter
- cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
+ //cfg.SqlFunctionHandler = sqlFunctionHandler
+ //cfg.ASTFormatter = sqlASTFormatter
+ //cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
// Set to zero
// Otherwise SQLite (in-memory) disconnects
// and all tables and data is lost
cfg.ConnMaxLifetime = 0
- if s.Store, err = rdbms.Connect(ctx, cfg); err != nil {
- return nil, err
+ if s, err = rdbms.Connect(ctx, cfg); err != nil {
+ return
}
- ql.QueryEncoder = &QueryEncoder{}
+ cfg.Upgrader = NewUpgrader(s)
+
+ //ql.QueryEncoder = &QueryEncoder{}
return s, nil
}
@@ -72,13 +64,13 @@ func ConnectInMemoryWithDebug(ctx context.Context) (s store.Storer, err error) {
return Connect(ctx, "sqlite3+debug://file::memory:?cache=shared&mode=memory")
}
-func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
- if err = (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s)); err != nil {
- return fmt.Errorf("cannot upgrade sqlite schema: %w", err)
- }
-
- return nil
-}
+//func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
+// if err = (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s)); err != nil {
+// return fmt.Errorf("cannot upgrade sqlite schema: %w", err)
+// }
+//
+// return nil
+//}
// ProcDataSourceName validates given DSN and ensures
// params are present and correct
@@ -90,7 +82,12 @@ func ProcDataSourceName(in string) (*rdbms.Config, error) {
var (
endOfSchema = strings.Index(in, schemeDel)
- c = &rdbms.Config{}
+
+ c = &rdbms.Config{
+ // note that we're not using vanilla SQLite
+ // see dialect.go
+ Dialect: goqu.Dialect("sqlite3"),
+ }
)
if endOfSchema > 0 && (in[:endOfSchema] == validScheme || strings.HasPrefix(in[:endOfSchema], validScheme+"+")) {
diff --git a/store/adapters/rdbms/drivers/sqlite/dialect.go b/store/adapters/rdbms/drivers/sqlite/dialect.go
new file mode 100644
index 000000000..25023b531
--- /dev/null
+++ b/store/adapters/rdbms/drivers/sqlite/dialect.go
@@ -0,0 +1,16 @@
+package sqlite
+
+import (
+ "github.com/doug-martin/goqu/v9"
+ dialect "github.com/doug-martin/goqu/v9/dialect/sqlite3"
+)
+
+func init() {
+ d := dialect.DialectOptions()
+
+ // https://github.com/doug-martin/goqu/pull/330
+ d.TruncateClause = []byte("DELETE FROM")
+
+ // Overriding vanila SQLite dialect
+ goqu.RegisterDialect("sqlite3", d)
+}
diff --git a/store/sqlite3/upgrade.go b/store/adapters/rdbms/drivers/sqlite/upgrade.go
similarity index 71%
rename from store/sqlite3/upgrade.go
rename to store/adapters/rdbms/drivers/sqlite/upgrade.go
index a6e7e89b9..3fda5540e 100644
--- a/store/sqlite3/upgrade.go
+++ b/store/adapters/rdbms/drivers/sqlite/upgrade.go
@@ -1,6 +1,6 @@
-package sqlite3
+package sqlite
-// PostgreSQL specific prefixes, sql
+// SQLite specific prefixes, sql
// templates, functions and other helpers
import (
@@ -8,67 +8,75 @@ import (
"database/sql"
"fmt"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/schema"
"go.uber.org/zap"
)
type (
upgrader struct {
- s *Store
- log *zap.Logger
- ddl *ddl.Generator
+ log *zap.Logger
+ s *rdbms.Store
+ dialect *schema.CommonDialect
}
)
// NewUpgrader returns SQLite schema upgrader
-func NewUpgrader(log *zap.Logger, store *Store) *upgrader {
- var g = &upgrader{store, log, ddl.NewGenerator(log)}
- // All modifications we need for the DDL generator
- // to properly support SQLite dialect
+func NewUpgrader(store *rdbms.Store) *upgrader {
+ var g = &upgrader{
+ log: zap.NewNop(),
+ s: store,
+ dialect: schema.NewCommonDialect(),
+ }
+
+ // Modification to general DDL dialect to support Postgres requirements
// Cover mysql exceptions
- g.ddl.AddTemplateFunc("columnType", func(ct *ddl.ColumnType) string {
+ g.dialect.AddTemplateFunc("columnType", func(ct *schema.ColumnType) string {
switch ct.Type {
- case ddl.ColumnTypeTimestamp:
+ case schema.ColumnTypeTimestamp:
return "TIMESTAMP"
- case ddl.ColumnTypeBinary:
+ case schema.ColumnTypeBinary:
return "BLOB"
default:
- return ddl.GenColumnType(ct)
+ return schema.GenColumnType(ct)
}
})
return g
}
+func (u *upgrader) SetLogger(l *zap.Logger) {
+ u.log = l
+}
+
// Before runs before all tables are upgraded
func (u upgrader) Before(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).Before(ctx)
+ return schema.CommonUpgrades(u.log, u).Before(ctx)
}
// After runs after all tables are upgraded
func (u upgrader) After(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).After(ctx)
+ return schema.CommonUpgrades(u.log, u).After(ctx)
}
// CreateTable is triggered for every table defined in the rdbms package
//
// It checks if table is missing and creates it, otherwise
// it runs
-func (u upgrader) CreateTable(ctx context.Context, t *ddl.Table) (err error) {
+func (u upgrader) CreateTable(ctx context.Context, t *schema.Table) (err error) {
var exists bool
if exists, err = u.TableExists(ctx, t.Name); err != nil {
return
}
if !exists {
- if err = u.Exec(ctx, u.ddl.CreateTable(t)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateTable(t)); err != nil {
return err
}
for _, i := range t.Indexes {
- if err = u.Exec(ctx, u.ddl.CreateIndex(i)); err != nil {
+ if err = u.Exec(ctx, u.dialect.CreateIndex(i)); err != nil {
return fmt.Errorf("could not create index %s on table %s: %w", i.Name, i.Table, err)
}
}
@@ -85,8 +93,8 @@ func (u upgrader) Exec(ctx context.Context, sql string, aa ...interface{}) error
}
// upgradeTable applies any necessary changes connected to that specific table
-func (u upgrader) upgradeTable(ctx context.Context, t *ddl.Table) error {
- g := rdbms.GenericUpgrades(u.log, u)
+func (u upgrader) upgradeTable(ctx context.Context, t *schema.Table) error {
+ g := schema.CommonUpgrades(u.log, u)
switch t.Name {
default:
@@ -119,14 +127,14 @@ func (u upgrader) DropTable(ctx context.Context, table string) (dropped bool, er
return true, nil
}
-func (u upgrader) TableSchema(ctx context.Context, table string) (ddl.Columns, error) {
+func (u upgrader) TableSchema(ctx context.Context, table string) (schema.Columns, error) {
return nil, fmt.Errorf("pending implementation")
}
// AddColumn adds column to table
-func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column) (added bool, err error) {
+func (u upgrader) AddColumn(ctx context.Context, table string, col *schema.Column) (added bool, err error) {
err = func() error {
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -135,7 +143,7 @@ func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column)
return nil
}
- if err = u.Exec(ctx, u.ddl.AddColumn(table, col)); err != nil {
+ if err = u.Exec(ctx, u.dialect.AddColumn(table, col)); err != nil {
return err
}
@@ -153,7 +161,7 @@ func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column)
// DropColumn drops column from table
func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped bool, err error) {
err = func() error {
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -162,7 +170,7 @@ func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped
return nil
}
- if err = u.Exec(ctx, u.ddl.DropColumn(table, column)); err != nil {
+ if err = u.Exec(ctx, u.dialect.DropColumn(table, column)); err != nil {
return err
}
@@ -184,7 +192,7 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
return nil
}
- var columns ddl.Columns
+ var columns schema.Columns
if columns, err = u.getColumns(ctx, table); err != nil {
return err
}
@@ -204,7 +212,7 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
}
- if err = u.Exec(ctx, u.ddl.RenameColumn(table, oldName, newName)); err != nil {
+ if err = u.Exec(ctx, u.dialect.RenameColumn(table, oldName, newName)); err != nil {
return err
}
@@ -219,12 +227,12 @@ func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName stri
return
}
-func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *ddl.Index) (added bool, err error) {
+func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *schema.Index) (added bool, err error) {
return false, fmt.Errorf("adding primary keys on sqlite tables is not implemented")
}
-func (u upgrader) CreateIndex(ctx context.Context, ind *ddl.Index) (added bool, err error) {
- if err = u.Exec(ctx, u.ddl.CreateIndex(ind)); err != nil {
+func (u upgrader) CreateIndex(ctx context.Context, ind *schema.Index) (added bool, err error) {
+ if err = u.Exec(ctx, u.dialect.CreateIndex(ind)); err != nil {
return false, fmt.Errorf("could not create index on table %s: %w", ind.Table, err)
}
@@ -232,7 +240,7 @@ func (u upgrader) CreateIndex(ctx context.Context, ind *ddl.Index) (added bool,
}
// loads and returns all tables columns
-func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns, err error) {
+func (u upgrader) getColumns(ctx context.Context, table string) (out schema.Columns, err error) {
type (
col struct {
CID int `db:"cid"`
@@ -253,13 +261,11 @@ func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns
return nil, err
}
- out = make([]*ddl.Column, len(cols))
+ out = make([]*schema.Column, len(cols))
for i := range cols {
- out[i] = &ddl.Column{
- Name: cols[i].Name,
- //Type: ddl.ColumnType{},
+ out[i] = &schema.Column{
+ Name: cols[i].Name,
IsNull: !cols[i].NotNull,
- //DefaultValue: "",
}
}
diff --git a/store/adapters/rdbms/filter.go b/store/adapters/rdbms/filter.go
new file mode 100644
index 000000000..fc79c9076
--- /dev/null
+++ b/store/adapters/rdbms/filter.go
@@ -0,0 +1,306 @@
+package rdbms
+
+import (
+ "fmt"
+ "strings"
+ "time"
+
+ automationType "github.com/cortezaproject/corteza-server/automation/types"
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ "github.com/cortezaproject/corteza-server/federation/types"
+ "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ discoveryType "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ "github.com/cortezaproject/corteza-server/pkg/filter"
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
+)
+
+func (f *extendedFilters) SetDefaults() {
+ f.Actionlog = func(f actionlog.Filter) (ee []goqu.Expression, _ actionlog.Filter, err error) {
+ if ee, f, err = ActionlogFilter(f); err != nil {
+ return
+ }
+
+ // make sure we always sort ID, descending
+ if f.Sorting, err = filter.NewSorting("id DESC"); err != nil {
+ return
+ }
+
+ if f.BeforeActionID > 0 {
+ ee = append(ee, goqu.C("id").Lt(f.BeforeActionID))
+ }
+
+ if f.FromTimestamp != nil {
+ ee = append(ee, goqu.C("ts").Gte(f.FromTimestamp))
+ }
+
+ if f.ToTimestamp != nil {
+ ee = append(ee, goqu.C("ts").Lte(f.FromTimestamp))
+ }
+
+ if f.Limit == 0 || f.Limit > MaxLimit {
+ f.Limit = MaxLimit
+ }
+
+ return ee, f, err
+ }
+
+ f.Application = func(f systemType.ApplicationFilter) (ee []goqu.Expression, _ systemType.ApplicationFilter, err error) {
+ if ee, f, err = ApplicationFilter(f); err != nil {
+ return
+ }
+
+ if len(f.FlaggedIDs) > 0 {
+ ee = append(ee, goqu.C("id").In(f.FlaggedIDs))
+ }
+
+ return ee, f, err
+ }
+
+ f.AutomationSession = func(f automationType.SessionFilter) (ee []goqu.Expression, _ automationType.SessionFilter, err error) {
+ if ee, f, err = AutomationSessionFilter(f); err != nil {
+ return
+ }
+
+ if len(f.Status) > 0 {
+ ee = append(ee, goqu.C("status").In(f.Status))
+ }
+
+ return ee, f, err
+ }
+
+ f.ComposeAttachment = func(f composeType.AttachmentFilter) (ee []goqu.Expression, _ composeType.AttachmentFilter, err error) {
+ if ee, f, err = ComposeAttachmentFilter(f); err != nil {
+ return
+ }
+
+ switch f.Kind {
+ case composeType.PageAttachment:
+ // @todo implement filtering by page
+ if f.PageID > 0 {
+ err = fmt.Errorf("filtering by pageID not implemented")
+ return
+ }
+
+ case composeType.RecordAttachment:
+ panic("@todo pending implementation")
+ //query = query.
+ // Join("compose_record_value AS v ON (v.ref = a.id)")
+ //
+ //if f.ModuleID > 0 {
+ // query = query.
+ // Join("compose_record AS r ON (r.id = v.record_id)").
+ // Where(squirrel.Eq{"r.module_id": f.ModuleID})
+ //}
+ //
+ //if f.RecordID > 0 {
+ // query = query.Where(squirrel.Eq{"v.record_id": f.RecordID})
+ //}
+ //
+ //if f.FieldName != "" {
+ // query = query.Where(squirrel.Eq{"v.name": f.FieldName})
+ //}
+
+ default:
+ err = fmt.Errorf("unsupported kind value")
+ return
+ }
+
+ if f.Filter != "" {
+ err = fmt.Errorf("filtering by filter not implemented")
+ return
+ }
+
+ return ee, f, nil
+ }
+
+ f.ComposePage = func(f composeType.PageFilter) (ee []goqu.Expression, _ composeType.PageFilter, err error) {
+ if ee, f, err = ComposePageFilter(f); err != nil {
+ return
+ }
+
+ if f.ParentID > 0 {
+ ee = append(ee, goqu.C("self_id").Eq(f.ParentID))
+ } else if f.Root {
+ ee = append(ee, goqu.C("self_id").Eq(0))
+ }
+
+ return ee, f, nil
+ }
+
+ f.Reminder = func(f systemType.ReminderFilter) (ee []goqu.Expression, _ systemType.ReminderFilter, err error) {
+ if ee, f, err = ReminderFilter(f); err != nil {
+ return
+ }
+
+ if f.ExcludeDismissed {
+ ee = append(ee, goqu.C("dismissed_at").IsNull())
+ }
+
+ if !f.IncludeDeleted {
+ ee = append(ee, goqu.C("deleted_at").IsNull())
+ }
+
+ if f.ScheduledOnly {
+ ee = append(ee, goqu.C("remind_at").IsNotNull())
+ }
+
+ if f.Resource != "" {
+ ee = append(ee, goqu.C("resource").Like(f.Resource+"%"))
+ }
+
+ if f.ScheduledFrom != nil {
+ ee = append(ee, goqu.C("remind_at").Gte(f.ScheduledFrom.Format(time.RFC3339)))
+ }
+ if f.ScheduledUntil != nil {
+ ee = append(ee, goqu.C("remind_at").Lte(f.ScheduledUntil.Format(time.RFC3339)))
+ }
+
+ return ee, f, nil
+ }
+
+ f.ResourceTranslation = func(f systemType.ResourceTranslationFilter) (ee []goqu.Expression, _ systemType.ResourceTranslationFilter, err error) {
+ if ee, f, err = ResourceTranslationFilter(f); err != nil {
+ return
+ }
+
+ if f.ResourceType != "" {
+ ee = append(ee, goqu.C("resource").Like(f.ResourceType+"%"))
+ }
+
+ return ee, f, nil
+ }
+
+ f.Role = func(f systemType.RoleFilter) (ee []goqu.Expression, _ systemType.RoleFilter, err error) {
+ if ee, f, err = RoleFilter(f); err != nil {
+ return
+ }
+
+ if f.MemberID > 0 {
+ memberships := goqu.
+ Select("rel_role").
+ From(roleMemberTable).
+ Where(goqu.C("rel_user").In(f.MemberID))
+
+ ee = append(ee, goqu.C("id").In(memberships))
+ }
+
+ return ee, f, nil
+ }
+
+ f.User = func(f systemType.UserFilter) (ee []goqu.Expression, _ systemType.UserFilter, err error) {
+ if ee, f, err = UserFilter(f); err != nil {
+ return
+ }
+
+ if !f.AllKinds {
+ ee = append(ee, goqu.C("kind").Eq(f.Kind))
+ }
+
+ if len(f.RoleID) > 0 {
+ members := goqu.
+ Select("rel_user").
+ From(roleMemberTable).
+ Where(goqu.C("rel_role").In(f.RoleID))
+
+ ee = append(ee, goqu.C("id").In(members))
+ }
+
+ return ee, f, nil
+ }
+
+ f.FederationExposedModule = func(f types.ExposedModuleFilter) (ee []goqu.Expression, _ types.ExposedModuleFilter, err error) {
+ if ee, f, err = FederationExposedModuleFilter(f); err != nil {
+ return
+ }
+
+ if f.LastSync > 0 {
+ t := time.Unix(int64(f.LastSync), 0)
+
+ if !t.IsZero() {
+ ts := t.UTC().Format(time.RFC3339)
+ ee = append(ee, goqu.Or(
+ goqu.C("updated_at").Gte(ts),
+ goqu.C("created_at").Gte(ts),
+ ))
+ }
+ }
+
+ return ee, f, nil
+ }
+
+ f.ResourceActivity = func(f discoveryType.ResourceActivityFilter) (ee []goqu.Expression, _ discoveryType.ResourceActivityFilter, err error) {
+ if ee, f, err = ResourceActivityFilter(f); err != nil {
+ return
+ }
+
+ // Always sort by ID descending
+ //query = query.OrderBy("id DESC")
+
+ if f.FromTimestamp != nil {
+ ee = append(ee, goqu.C("ts").Gte(f.ToTimestamp))
+ }
+
+ if f.ToTimestamp != nil {
+ ee = append(ee, goqu.C("ts").Lte(f.ToTimestamp))
+ }
+
+ if f.Limit == 0 || f.Limit > MaxLimit {
+ f.Limit = MaxLimit
+ }
+
+ return ee, f, err
+ }
+}
+
+func order(sort filter.SortExprSet, sortables map[string]string) (oo []exp.OrderedExpression, err error) {
+ var (
+ has bool
+ )
+
+ for _, s := range sort {
+ if s.Column, has = sortables[strings.ToLower(s.Column)]; !has {
+ return nil, fmt.Errorf("column %q is not sortable", s.Column)
+ }
+
+ if s.Descending {
+ oo = append(oo, exp.NewOrderedExpression(goqu.I(s.Column), exp.DescSortDir, exp.NoNullsSortType))
+ } else {
+ oo = append(oo, exp.NewOrderedExpression(goqu.I(s.Column), exp.AscDir, exp.NoNullsSortType))
+ }
+ }
+
+ return
+}
+
+func stateNilComparison(lit string, fs filter.State) goqu.Expression {
+ switch fs {
+ case filter.StateExclusive:
+ // only not-null values
+ return goqu.Literal(lit).IsNotNull()
+
+ case filter.StateInclusive:
+ // no filter
+ return nil
+
+ default:
+ // exclude all non-null values
+ return goqu.Literal(lit).IsNull()
+ }
+}
+
+func stateFalseComparison(lit string, fs filter.State) goqu.Expression {
+ switch fs {
+ case filter.StateExcluded:
+ // only true
+ return goqu.Literal(lit).IsTrue()
+
+ case filter.StateExclusive:
+ // only false
+ return goqu.Literal(lit).IsFalse()
+
+ default:
+ return nil
+ }
+}
diff --git a/store/adapters/rdbms/filters.gen.go b/store/adapters/rdbms/filters.gen.go
new file mode 100644
index 000000000..6d43d51cc
--- /dev/null
+++ b/store/adapters/rdbms/filters.gen.go
@@ -0,0 +1,1179 @@
+package rdbms
+
+// This file is auto-generated.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+
+import (
+ "strings"
+
+ automationType "github.com/cortezaproject/corteza-server/automation/types"
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ federationType "github.com/cortezaproject/corteza-server/federation/types"
+ actionlogType "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ discoveryType "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ flagType "github.com/cortezaproject/corteza-server/pkg/flag/types"
+ labelsType "github.com/cortezaproject/corteza-server/pkg/label/types"
+ rbacType "github.com/cortezaproject/corteza-server/pkg/rbac"
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "github.com/doug-martin/goqu/v9"
+)
+
+type (
+ // extendedFilters allows special per-resource
+ // filters to be attached to store
+ //
+ // when optional filter is set, generated filter function is NOT called automatically
+ // (but can be called from the optional filter)
+ extendedFilters struct {
+ // Filter extensions for search/query functions
+
+ // optional actionlog filter function called after the generated function
+ Actionlog func(actionlogType.Filter) ([]goqu.Expression, actionlogType.Filter, error)
+
+ // optional apigwFilter filter function called after the generated function
+ ApigwFilter func(systemType.ApigwFilterFilter) ([]goqu.Expression, systemType.ApigwFilterFilter, error)
+
+ // optional apigwRoute filter function called after the generated function
+ ApigwRoute func(systemType.ApigwRouteFilter) ([]goqu.Expression, systemType.ApigwRouteFilter, error)
+
+ // optional application filter function called after the generated function
+ Application func(systemType.ApplicationFilter) ([]goqu.Expression, systemType.ApplicationFilter, error)
+
+ // optional attachment filter function called after the generated function
+ Attachment func(systemType.AttachmentFilter) ([]goqu.Expression, systemType.AttachmentFilter, error)
+
+ // optional authClient filter function called after the generated function
+ AuthClient func(systemType.AuthClientFilter) ([]goqu.Expression, systemType.AuthClientFilter, error)
+
+ // optional authConfirmedClient filter function called after the generated function
+ AuthConfirmedClient func(systemType.AuthConfirmedClientFilter) ([]goqu.Expression, systemType.AuthConfirmedClientFilter, error)
+
+ // optional authOa2token filter function called after the generated function
+ AuthOa2token func(systemType.AuthOa2tokenFilter) ([]goqu.Expression, systemType.AuthOa2tokenFilter, error)
+
+ // optional authSession filter function called after the generated function
+ AuthSession func(systemType.AuthSessionFilter) ([]goqu.Expression, systemType.AuthSessionFilter, error)
+
+ // optional automationSession filter function called after the generated function
+ AutomationSession func(automationType.SessionFilter) ([]goqu.Expression, automationType.SessionFilter, error)
+
+ // optional automationTrigger filter function called after the generated function
+ AutomationTrigger func(automationType.TriggerFilter) ([]goqu.Expression, automationType.TriggerFilter, error)
+
+ // optional automationWorkflow filter function called after the generated function
+ AutomationWorkflow func(automationType.WorkflowFilter) ([]goqu.Expression, automationType.WorkflowFilter, error)
+
+ // optional composeAttachment filter function called after the generated function
+ ComposeAttachment func(composeType.AttachmentFilter) ([]goqu.Expression, composeType.AttachmentFilter, error)
+
+ // optional composeChart filter function called after the generated function
+ ComposeChart func(composeType.ChartFilter) ([]goqu.Expression, composeType.ChartFilter, error)
+
+ // optional composeModule filter function called after the generated function
+ ComposeModule func(composeType.ModuleFilter) ([]goqu.Expression, composeType.ModuleFilter, error)
+
+ // optional composeModuleField filter function called after the generated function
+ ComposeModuleField func(composeType.ModuleFieldFilter) ([]goqu.Expression, composeType.ModuleFieldFilter, error)
+
+ // optional composeNamespace filter function called after the generated function
+ ComposeNamespace func(composeType.NamespaceFilter) ([]goqu.Expression, composeType.NamespaceFilter, error)
+
+ // optional composePage filter function called after the generated function
+ ComposePage func(composeType.PageFilter) ([]goqu.Expression, composeType.PageFilter, error)
+
+ // optional composeRecord filter function called after the generated function
+ ComposeRecord func(composeType.RecordFilter) ([]goqu.Expression, composeType.RecordFilter, error)
+
+ // optional composeRecordValue filter function called after the generated function
+ ComposeRecordValue func(composeType.RecordValueFilter) ([]goqu.Expression, composeType.RecordValueFilter, error)
+
+ // optional credential filter function called after the generated function
+ Credential func(systemType.CredentialFilter) ([]goqu.Expression, systemType.CredentialFilter, error)
+
+ // optional federationExposedModule filter function called after the generated function
+ FederationExposedModule func(federationType.ExposedModuleFilter) ([]goqu.Expression, federationType.ExposedModuleFilter, error)
+
+ // optional federationModuleMapping filter function called after the generated function
+ FederationModuleMapping func(federationType.ModuleMappingFilter) ([]goqu.Expression, federationType.ModuleMappingFilter, error)
+
+ // optional federationNode filter function called after the generated function
+ FederationNode func(federationType.NodeFilter) ([]goqu.Expression, federationType.NodeFilter, error)
+
+ // optional federationNodeSync filter function called after the generated function
+ FederationNodeSync func(federationType.NodeSyncFilter) ([]goqu.Expression, federationType.NodeSyncFilter, error)
+
+ // optional federationSharedModule filter function called after the generated function
+ FederationSharedModule func(federationType.SharedModuleFilter) ([]goqu.Expression, federationType.SharedModuleFilter, error)
+
+ // optional flag filter function called after the generated function
+ Flag func(flagType.FlagFilter) ([]goqu.Expression, flagType.FlagFilter, error)
+
+ // optional label filter function called after the generated function
+ Label func(labelsType.LabelFilter) ([]goqu.Expression, labelsType.LabelFilter, error)
+
+ // optional queue filter function called after the generated function
+ Queue func(systemType.QueueFilter) ([]goqu.Expression, systemType.QueueFilter, error)
+
+ // optional queueMessage filter function called after the generated function
+ QueueMessage func(systemType.QueueMessageFilter) ([]goqu.Expression, systemType.QueueMessageFilter, error)
+
+ // optional rbacRule filter function called after the generated function
+ RbacRule func(rbacType.RuleFilter) ([]goqu.Expression, rbacType.RuleFilter, error)
+
+ // optional reminder filter function called after the generated function
+ Reminder func(systemType.ReminderFilter) ([]goqu.Expression, systemType.ReminderFilter, error)
+
+ // optional report filter function called after the generated function
+ Report func(systemType.ReportFilter) ([]goqu.Expression, systemType.ReportFilter, error)
+
+ // optional resourceActivity filter function called after the generated function
+ ResourceActivity func(discoveryType.ResourceActivityFilter) ([]goqu.Expression, discoveryType.ResourceActivityFilter, error)
+
+ // optional resourceTranslation filter function called after the generated function
+ ResourceTranslation func(systemType.ResourceTranslationFilter) ([]goqu.Expression, systemType.ResourceTranslationFilter, error)
+
+ // optional role filter function called after the generated function
+ Role func(systemType.RoleFilter) ([]goqu.Expression, systemType.RoleFilter, error)
+
+ // optional roleMember filter function called after the generated function
+ RoleMember func(systemType.RoleMemberFilter) ([]goqu.Expression, systemType.RoleMemberFilter, error)
+
+ // optional settingValue filter function called after the generated function
+ SettingValue func(systemType.SettingsFilter) ([]goqu.Expression, systemType.SettingsFilter, error)
+
+ // optional template filter function called after the generated function
+ Template func(systemType.TemplateFilter) ([]goqu.Expression, systemType.TemplateFilter, error)
+
+ // optional user filter function called after the generated function
+ User func(systemType.UserFilter) ([]goqu.Expression, systemType.UserFilter, error)
+ }
+)
+
+// ActionlogFilter returns logical expressions
+//
+// This function is called from Store.QueryActionlogs() and can be extended
+// by setting Store.Filters.Actionlog. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ActionlogFilter(f actionlogType.Filter) (ee []goqu.Expression, _ actionlogType.Filter, err error) {
+
+ if val := strings.TrimSpace(f.Action); len(val) > 0 {
+ ee = append(ee, goqu.C("action").Eq(f.Action))
+ }
+
+ if val := strings.TrimSpace(f.Resource); len(val) > 0 {
+ ee = append(ee, goqu.C("resource").Eq(f.Resource))
+ }
+
+ if val := strings.TrimSpace(f.Origin); len(val) > 0 {
+ ee = append(ee, goqu.C("origin").Eq(f.Origin))
+ }
+
+ if len(f.ActorID) > 0 {
+ ee = append(ee, goqu.C("actor_id").In(f.ActorID))
+ }
+
+ return ee, f, err
+}
+
+// ApigwFilterFilter returns logical expressions
+//
+// This function is called from Store.QueryApigwFilters() and can be extended
+// by setting Store.Filters.ApigwFilter. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ApigwFilterFilter(f systemType.ApigwFilterFilter) (ee []goqu.Expression, _ systemType.ApigwFilterFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if expr := stateFalseComparison("enabled", f.Disabled); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if f.RouteID > 0 {
+ ee = append(ee, goqu.C("route_id").Eq(f.RouteID))
+ }
+
+ return ee, f, err
+}
+
+// ApigwRouteFilter returns logical expressions
+//
+// This function is called from Store.QueryApigwRoutes() and can be extended
+// by setting Store.Filters.ApigwRoute. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ApigwRouteFilter(f systemType.ApigwRouteFilter) (ee []goqu.Expression, _ systemType.ApigwRouteFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if expr := stateFalseComparison("enabled", f.Disabled); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Route); len(val) > 0 {
+ ee = append(ee, goqu.C("route").Eq(f.Route))
+ }
+
+ if val := strings.TrimSpace(f.Group); len(val) > 0 {
+ ee = append(ee, goqu.C("group").Eq(f.Group))
+ }
+
+ return ee, f, err
+}
+
+// ApplicationFilter returns logical expressions
+//
+// This function is called from Store.QueryApplications() and can be extended
+// by setting Store.Filters.Application. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ApplicationFilter(f systemType.ApplicationFilter) (ee []goqu.Expression, _ systemType.ApplicationFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Name); len(val) > 0 {
+ ee = append(ee, goqu.C("name").Eq(f.Name))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// AttachmentFilter returns logical expressions
+//
+// This function is called from Store.QueryAttachments() and can be extended
+// by setting Store.Filters.Attachment. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AttachmentFilter(f systemType.AttachmentFilter) (ee []goqu.Expression, _ systemType.AttachmentFilter, err error) {
+
+ if val := strings.TrimSpace(f.Kind); len(val) > 0 {
+ ee = append(ee, goqu.C("kind").Eq(f.Kind))
+ }
+
+ return ee, f, err
+}
+
+// AuthClientFilter returns logical expressions
+//
+// This function is called from Store.QueryAuthClients() and can be extended
+// by setting Store.Filters.AuthClient. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AuthClientFilter(f systemType.AuthClientFilter) (ee []goqu.Expression, _ systemType.AuthClientFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ return ee, f, err
+}
+
+// AuthConfirmedClientFilter returns logical expressions
+//
+// This function is called from Store.QueryAuthConfirmedClients() and can be extended
+// by setting Store.Filters.AuthConfirmedClient. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AuthConfirmedClientFilter(f systemType.AuthConfirmedClientFilter) (ee []goqu.Expression, _ systemType.AuthConfirmedClientFilter, err error) {
+
+ if f.UserID > 0 {
+ ee = append(ee, goqu.C("rel_client").Eq(f.UserID))
+ }
+
+ return ee, f, err
+}
+
+// AuthOa2tokenFilter returns logical expressions
+//
+// This function is called from Store.QueryAuthOa2tokens() and can be extended
+// by setting Store.Filters.AuthOa2token. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AuthOa2tokenFilter(f systemType.AuthOa2tokenFilter) (ee []goqu.Expression, _ systemType.AuthOa2tokenFilter, err error) {
+
+ if f.UserID > 0 {
+ ee = append(ee, goqu.C("user_id").Eq(f.UserID))
+ }
+
+ return ee, f, err
+}
+
+// AuthSessionFilter returns logical expressions
+//
+// This function is called from Store.QueryAuthSessions() and can be extended
+// by setting Store.Filters.AuthSession. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AuthSessionFilter(f systemType.AuthSessionFilter) (ee []goqu.Expression, _ systemType.AuthSessionFilter, err error) {
+
+ if f.UserID > 0 {
+ ee = append(ee, goqu.C("user_id").Eq(f.UserID))
+ }
+
+ return ee, f, err
+}
+
+// AutomationSessionFilter returns logical expressions
+//
+// This function is called from Store.QueryAutomationSessions() and can be extended
+// by setting Store.Filters.AutomationSession. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AutomationSessionFilter(f automationType.SessionFilter) (ee []goqu.Expression, _ automationType.SessionFilter, err error) {
+
+ if expr := stateNilComparison("completed_at", f.Completed); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ // @todo codegen warning: filtering by Status ([]uint) not supported,
+ // see rdbms.go.tpl and add an exception
+
+ if len(f.WorkflowID) > 0 {
+ ee = append(ee, goqu.C("rel_workflow").In(f.WorkflowID))
+ }
+
+ if val := strings.TrimSpace(f.EventType); len(val) > 0 {
+ ee = append(ee, goqu.C("event_type").Eq(f.EventType))
+ }
+
+ if val := strings.TrimSpace(f.ResourceType); len(val) > 0 {
+ ee = append(ee, goqu.C("resource_type").Eq(f.ResourceType))
+ }
+
+ if len(f.CreatedBy) > 0 {
+ ee = append(ee, goqu.C("created_by").In(f.CreatedBy))
+ }
+
+ return ee, f, err
+}
+
+// AutomationTriggerFilter returns logical expressions
+//
+// This function is called from Store.QueryAutomationTriggers() and can be extended
+// by setting Store.Filters.AutomationTrigger. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AutomationTriggerFilter(f automationType.TriggerFilter) (ee []goqu.Expression, _ automationType.TriggerFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if expr := stateFalseComparison("enabled", f.Disabled); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.TriggerID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.TriggerID))
+ }
+
+ if len(f.WorkflowID) > 0 {
+ ee = append(ee, goqu.C("rel_workflow").In(f.WorkflowID))
+ }
+
+ if val := strings.TrimSpace(f.EventType); len(val) > 0 {
+ ee = append(ee, goqu.C("event_type").Eq(f.EventType))
+ }
+
+ if val := strings.TrimSpace(f.ResourceType); len(val) > 0 {
+ ee = append(ee, goqu.C("resource_type").Eq(f.ResourceType))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ return ee, f, err
+}
+
+// AutomationWorkflowFilter returns logical expressions
+//
+// This function is called from Store.QueryAutomationWorkflows() and can be extended
+// by setting Store.Filters.AutomationWorkflow. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func AutomationWorkflowFilter(f automationType.WorkflowFilter) (ee []goqu.Expression, _ automationType.WorkflowFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if expr := stateFalseComparison("enabled", f.Disabled); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// ComposeAttachmentFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeAttachments() and can be extended
+// by setting Store.Filters.ComposeAttachment. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeAttachmentFilter(f composeType.AttachmentFilter) (ee []goqu.Expression, _ composeType.AttachmentFilter, err error) {
+
+ if val := strings.TrimSpace(f.Kind); len(val) > 0 {
+ ee = append(ee, goqu.C("kind").Eq(f.Kind))
+ }
+
+ if f.NamespaceID > 0 {
+ ee = append(ee, goqu.C("namespace_id").Eq(f.NamespaceID))
+ }
+
+ return ee, f, err
+}
+
+// ComposeChartFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeCharts() and can be extended
+// by setting Store.Filters.ComposeChart. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeChartFilter(f composeType.ChartFilter) (ee []goqu.Expression, _ composeType.ChartFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if len(f.ChartID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.ChartID))
+ }
+
+ if f.NamespaceID > 0 {
+ ee = append(ee, goqu.C("rel_namespace").Eq(f.NamespaceID))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// ComposeModuleFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeModules() and can be extended
+// by setting Store.Filters.ComposeModule. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeModuleFilter(f composeType.ModuleFilter) (ee []goqu.Expression, _ composeType.ModuleFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if len(f.ModuleID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.ModuleID))
+ }
+
+ if f.NamespaceID > 0 {
+ ee = append(ee, goqu.C("rel_namespace").Eq(f.NamespaceID))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// ComposeModuleFieldFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeModuleFields() and can be extended
+// by setting Store.Filters.ComposeModuleField. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeModuleFieldFilter(f composeType.ModuleFieldFilter) (ee []goqu.Expression, _ composeType.ModuleFieldFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ return ee, f, err
+}
+
+// ComposeNamespaceFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeNamespaces() and can be extended
+// by setting Store.Filters.ComposeNamespace. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeNamespaceFilter(f composeType.NamespaceFilter) (ee []goqu.Expression, _ composeType.NamespaceFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.NamespaceID) > 0 {
+ ee = append(ee, goqu.C("namespace_id").In(f.NamespaceID))
+ }
+
+ if val := strings.TrimSpace(f.Name); len(val) > 0 {
+ ee = append(ee, goqu.C("name").Eq(f.Name))
+ }
+
+ if val := strings.TrimSpace(f.Slug); len(val) > 0 {
+ ee = append(ee, goqu.C("slug").Eq(f.Slug))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ goqu.C("slug").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// ComposePageFilter returns logical expressions
+//
+// This function is called from Store.QueryComposePages() and can be extended
+// by setting Store.Filters.ComposePage. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposePageFilter(f composeType.PageFilter) (ee []goqu.Expression, _ composeType.PageFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if f.NamespaceID > 0 {
+ ee = append(ee, goqu.C("rel_namespace").Eq(f.NamespaceID))
+ }
+
+ if f.ModuleID > 0 {
+ ee = append(ee, goqu.C("rel_module").Eq(f.ModuleID))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ goqu.C("title").ILike("%"+f.Query+"%"),
+ goqu.C("description").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// ComposeRecordFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeRecords() and can be extended
+// by setting Store.Filters.ComposeRecord. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeRecordFilter(f composeType.RecordFilter) (ee []goqu.Expression, _ composeType.RecordFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ return ee, f, err
+}
+
+// ComposeRecordValueFilter returns logical expressions
+//
+// This function is called from Store.QueryComposeRecordValues() and can be extended
+// by setting Store.Filters.ComposeRecordValue. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ComposeRecordValueFilter(f composeType.RecordValueFilter) (ee []goqu.Expression, _ composeType.RecordValueFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.RecordID) > 0 {
+ ee = append(ee, goqu.C("record_id").In(f.RecordID))
+ }
+
+ return ee, f, err
+}
+
+// CredentialFilter returns logical expressions
+//
+// This function is called from Store.QueryCredentials() and can be extended
+// by setting Store.Filters.Credential. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func CredentialFilter(f systemType.CredentialFilter) (ee []goqu.Expression, _ systemType.CredentialFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if f.OwnerID > 0 {
+ ee = append(ee, goqu.C("rel_owner").Eq(f.OwnerID))
+ }
+
+ if val := strings.TrimSpace(f.Kind); len(val) > 0 {
+ ee = append(ee, goqu.C("kind").Eq(f.Kind))
+ }
+
+ if val := strings.TrimSpace(f.Credentials); len(val) > 0 {
+ ee = append(ee, goqu.C("credentials").Eq(f.Credentials))
+ }
+
+ return ee, f, err
+}
+
+// FederationExposedModuleFilter returns logical expressions
+//
+// This function is called from Store.QueryFederationExposedModules() and can be extended
+// by setting Store.Filters.FederationExposedModule. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func FederationExposedModuleFilter(f federationType.ExposedModuleFilter) (ee []goqu.Expression, _ federationType.ExposedModuleFilter, err error) {
+
+ if f.ComposeModuleID > 0 {
+ ee = append(ee, goqu.C("rel_compose_module").Eq(f.ComposeModuleID))
+ }
+
+ if f.ComposeNamespaceID > 0 {
+ ee = append(ee, goqu.C("rel_compose_namespace").Eq(f.ComposeNamespaceID))
+ }
+
+ if f.NodeID > 0 {
+ ee = append(ee, goqu.C("rel_node").Eq(f.NodeID))
+ }
+
+ return ee, f, err
+}
+
+// FederationModuleMappingFilter returns logical expressions
+//
+// This function is called from Store.QueryFederationModuleMappings() and can be extended
+// by setting Store.Filters.FederationModuleMapping. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func FederationModuleMappingFilter(f federationType.ModuleMappingFilter) (ee []goqu.Expression, _ federationType.ModuleMappingFilter, err error) {
+
+ if f.ComposeModuleID > 0 {
+ ee = append(ee, goqu.C("rel_compose_module").Eq(f.ComposeModuleID))
+ }
+
+ if f.ComposeNamespaceID > 0 {
+ ee = append(ee, goqu.C("rel_compose_namespace").Eq(f.ComposeNamespaceID))
+ }
+
+ if f.FederationModuleID > 0 {
+ ee = append(ee, goqu.C("rel_federation_module").Eq(f.FederationModuleID))
+ }
+
+ return ee, f, err
+}
+
+// FederationNodeFilter returns logical expressions
+//
+// This function is called from Store.QueryFederationNodes() and can be extended
+// by setting Store.Filters.FederationNode. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func FederationNodeFilter(f federationType.NodeFilter) (ee []goqu.Expression, _ federationType.NodeFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ goqu.C("base_url").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// FederationNodeSyncFilter returns logical expressions
+//
+// This function is called from Store.QueryFederationNodeSyncs() and can be extended
+// by setting Store.Filters.FederationNodeSync. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func FederationNodeSyncFilter(f federationType.NodeSyncFilter) (ee []goqu.Expression, _ federationType.NodeSyncFilter, err error) {
+
+ if f.NodeID > 0 {
+ ee = append(ee, goqu.C("rel_node").Eq(f.NodeID))
+ }
+
+ if f.ModuleID > 0 {
+ ee = append(ee, goqu.C("rel_module").Eq(f.ModuleID))
+ }
+
+ if val := strings.TrimSpace(f.SyncStatus); len(val) > 0 {
+ ee = append(ee, goqu.C("sync_status").Eq(f.SyncStatus))
+ }
+
+ if val := strings.TrimSpace(f.SyncType); len(val) > 0 {
+ ee = append(ee, goqu.C("sync_type").Eq(f.SyncType))
+ }
+
+ return ee, f, err
+}
+
+// FederationSharedModuleFilter returns logical expressions
+//
+// This function is called from Store.QueryFederationSharedModules() and can be extended
+// by setting Store.Filters.FederationSharedModule. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func FederationSharedModuleFilter(f federationType.SharedModuleFilter) (ee []goqu.Expression, _ federationType.SharedModuleFilter, err error) {
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if f.NodeID > 0 {
+ ee = append(ee, goqu.C("ref_node").Eq(f.NodeID))
+ }
+
+ if val := strings.TrimSpace(f.Name); len(val) > 0 {
+ ee = append(ee, goqu.C("name").Eq(f.Name))
+ }
+
+ if f.ExternalFederationModuleID > 0 {
+ ee = append(ee, goqu.C("xref_module").Eq(f.ExternalFederationModuleID))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// FlagFilter returns logical expressions
+//
+// This function is called from Store.QueryFlags() and can be extended
+// by setting Store.Filters.Flag. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func FlagFilter(f flagType.FlagFilter) (ee []goqu.Expression, _ flagType.FlagFilter, err error) {
+
+ return ee, f, err
+}
+
+// LabelFilter returns logical expressions
+//
+// This function is called from Store.QueryLabels() and can be extended
+// by setting Store.Filters.Label. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func LabelFilter(f labelsType.LabelFilter) (ee []goqu.Expression, _ labelsType.LabelFilter, err error) {
+
+ return ee, f, err
+}
+
+// QueueFilter returns logical expressions
+//
+// This function is called from Store.QueryQueues() and can be extended
+// by setting Store.Filters.Queue. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func QueueFilter(f systemType.QueueFilter) (ee []goqu.Expression, _ systemType.QueueFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Queue); len(val) > 0 {
+ ee = append(ee, goqu.C("queue").Eq(f.Queue))
+ }
+
+ return ee, f, err
+}
+
+// QueueMessageFilter returns logical expressions
+//
+// This function is called from Store.QueryQueueMessages() and can be extended
+// by setting Store.Filters.QueueMessage. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func QueueMessageFilter(f systemType.QueueMessageFilter) (ee []goqu.Expression, _ systemType.QueueMessageFilter, err error) {
+
+ if expr := stateNilComparison("processed", f.Processed); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Queue); len(val) > 0 {
+ ee = append(ee, goqu.C("queue").Eq(f.Queue))
+ }
+
+ return ee, f, err
+}
+
+// RbacRuleFilter returns logical expressions
+//
+// This function is called from Store.QueryRbacRules() and can be extended
+// by setting Store.Filters.RbacRule. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func RbacRuleFilter(f rbacType.RuleFilter) (ee []goqu.Expression, _ rbacType.RuleFilter, err error) {
+
+ return ee, f, err
+}
+
+// ReminderFilter returns logical expressions
+//
+// This function is called from Store.QueryReminders() and can be extended
+// by setting Store.Filters.Reminder. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ReminderFilter(f systemType.ReminderFilter) (ee []goqu.Expression, _ systemType.ReminderFilter, err error) {
+
+ if len(f.ReminderID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.ReminderID))
+ }
+
+ if f.AssignedTo > 0 {
+ ee = append(ee, goqu.C("assigned_to").Eq(f.AssignedTo))
+ }
+
+ return ee, f, err
+}
+
+// ReportFilter returns logical expressions
+//
+// This function is called from Store.QueryReports() and can be extended
+// by setting Store.Filters.Report. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ReportFilter(f systemType.ReportFilter) (ee []goqu.Expression, _ systemType.ReportFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if len(f.ReportID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.ReportID))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ return ee, f, err
+}
+
+// ResourceActivityFilter returns logical expressions
+//
+// This function is called from Store.QueryResourceActivitys() and can be extended
+// by setting Store.Filters.ResourceActivity. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ResourceActivityFilter(f discoveryType.ResourceActivityFilter) (ee []goqu.Expression, _ discoveryType.ResourceActivityFilter, err error) {
+
+ return ee, f, err
+}
+
+// ResourceTranslationFilter returns logical expressions
+//
+// This function is called from Store.QueryResourceTranslations() and can be extended
+// by setting Store.Filters.ResourceTranslation. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func ResourceTranslationFilter(f systemType.ResourceTranslationFilter) (ee []goqu.Expression, _ systemType.ResourceTranslationFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if val := strings.TrimSpace(f.Resource); len(val) > 0 {
+ ee = append(ee, goqu.C("resource").Eq(f.Resource))
+ }
+
+ if val := strings.TrimSpace(f.Lang); len(val) > 0 {
+ ee = append(ee, goqu.C("lang").Eq(f.Lang))
+ }
+
+ if len(f.TranslationID) > 0 {
+ ee = append(ee, goqu.C("translation_id").In(f.TranslationID))
+ }
+
+ return ee, f, err
+}
+
+// RoleFilter returns logical expressions
+//
+// This function is called from Store.QueryRoles() and can be extended
+// by setting Store.Filters.Role. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func RoleFilter(f systemType.RoleFilter) (ee []goqu.Expression, _ systemType.RoleFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if expr := stateNilComparison("archived_at", f.Archived); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.RoleID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.RoleID))
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
+
+// RoleMemberFilter returns logical expressions
+//
+// This function is called from Store.QueryRoleMembers() and can be extended
+// by setting Store.Filters.RoleMember. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func RoleMemberFilter(f systemType.RoleMemberFilter) (ee []goqu.Expression, _ systemType.RoleMemberFilter, err error) {
+
+ if f.UserID > 0 {
+ ee = append(ee, goqu.C("rel_user").Eq(f.UserID))
+ }
+
+ if f.RoleID > 0 {
+ ee = append(ee, goqu.C("rel_role").Eq(f.RoleID))
+ }
+
+ return ee, f, err
+}
+
+// SettingValueFilter returns logical expressions
+//
+// This function is called from Store.QuerySettingValues() and can be extended
+// by setting Store.Filters.SettingValue. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func SettingValueFilter(f systemType.SettingsFilter) (ee []goqu.Expression, _ systemType.SettingsFilter, err error) {
+
+ if f.OwnedBy > 0 {
+ ee = append(ee, goqu.C("rel_owner").Eq(f.OwnedBy))
+ }
+
+ return ee, f, err
+}
+
+// TemplateFilter returns logical expressions
+//
+// This function is called from Store.QueryTemplates() and can be extended
+// by setting Store.Filters.Template. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func TemplateFilter(f systemType.TemplateFilter) (ee []goqu.Expression, _ systemType.TemplateFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.TemplateID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.TemplateID))
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if f.Partial {
+ ee = append(ee, goqu.C("partial").IsTrue())
+ }
+
+ if val := strings.TrimSpace(f.Type); len(val) > 0 {
+ ee = append(ee, goqu.C("type").Eq(f.Type))
+ }
+
+ if f.OwnerID > 0 {
+ ee = append(ee, goqu.C("rel_owner").Eq(f.OwnerID))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ return ee, f, err
+}
+
+// UserFilter returns logical expressions
+//
+// This function is called from Store.QueryUsers() and can be extended
+// by setting Store.Filters.User. Extension is called after all expressions
+// are generated and can choose to ignore or alter them.
+//
+// This function is auto-generated
+func UserFilter(f systemType.UserFilter) (ee []goqu.Expression, _ systemType.UserFilter, err error) {
+
+ if expr := stateNilComparison("deleted_at", f.Deleted); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if expr := stateNilComparison("suspended_at", f.Suspended); expr != nil {
+ ee = append(ee, expr)
+ }
+
+ if len(f.UserID) > 0 {
+ ee = append(ee, goqu.C("id").In(f.UserID))
+ }
+
+ if val := strings.TrimSpace(f.Email); len(val) > 0 {
+ ee = append(ee, goqu.C("email").Eq(f.Email))
+ }
+
+ if val := strings.TrimSpace(f.Username); len(val) > 0 {
+ ee = append(ee, goqu.C("username").Eq(f.Username))
+ }
+
+ if val := strings.TrimSpace(f.Handle); len(val) > 0 {
+ ee = append(ee, goqu.C("handle").Eq(f.Handle))
+ }
+
+ if len(f.LabeledIDs) > 0 {
+ ee = append(ee, goqu.I("id").In(f.LabeledIDs))
+ }
+
+ if f.Query != "" {
+ ee = append(ee, goqu.Or(
+ goqu.C("email").ILike("%"+f.Query+"%"),
+ goqu.C("username").ILike("%"+f.Query+"%"),
+ goqu.C("handle").ILike("%"+f.Query+"%"),
+ goqu.C("name").ILike("%"+f.Query+"%"),
+ ))
+ }
+
+ return ee, f, err
+}
diff --git a/store/rdbms/instrumentation/README.adoc b/store/adapters/rdbms/instrumentation/README.adoc
similarity index 100%
rename from store/rdbms/instrumentation/README.adoc
rename to store/adapters/rdbms/instrumentation/README.adoc
diff --git a/store/rdbms/instrumentation/debug.go b/store/adapters/rdbms/instrumentation/debug.go
similarity index 100%
rename from store/rdbms/instrumentation/debug.go
rename to store/adapters/rdbms/instrumentation/debug.go
diff --git a/store/rdbms/log.go b/store/adapters/rdbms/log.go
similarity index 83%
rename from store/rdbms/log.go
rename to store/adapters/rdbms/log.go
index 6365807d0..c01f4597a 100644
--- a/store/rdbms/log.go
+++ b/store/adapters/rdbms/log.go
@@ -9,7 +9,7 @@ import (
// log() returns named logger with caller skip and stacktrace set to Fatal
//
-// It check the given context logger
+// It checks the given context for logger before falling back to one set on the store
func (s Store) log(ctx context.Context) *zap.Logger {
return logger.ContextValue(ctx, s.logger).
Named("store.rdbms").
diff --git a/store/adapters/rdbms/queries.gen.go b/store/adapters/rdbms/queries.gen.go
new file mode 100644
index 000000000..87f657a35
--- /dev/null
+++ b/store/adapters/rdbms/queries.gen.go
@@ -0,0 +1,4312 @@
+package rdbms
+
+// This file is auto-generated.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+
+import (
+ automationType "github.com/cortezaproject/corteza-server/automation/types"
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ federationType "github.com/cortezaproject/corteza-server/federation/types"
+ actionlogType "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ discoveryType "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ flagType "github.com/cortezaproject/corteza-server/pkg/flag/types"
+ labelsType "github.com/cortezaproject/corteza-server/pkg/label/types"
+ rbacType "github.com/cortezaproject/corteza-server/pkg/rbac"
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "github.com/doug-martin/goqu/v9"
+)
+
+var (
+ // actionlogTable represents actionlogs store table
+ //
+ // This value is auto-generated
+ actionlogTable = goqu.T("actionlog")
+
+ // actionlogSelectQuery assembles select query for fetching actionlogs
+ //
+ // This function is auto-generated
+ actionlogSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "ts",
+ "request_origin",
+ "request_id",
+ "actor_ip_addr",
+ "actor_id",
+ "resource",
+ "action",
+ "error",
+ "severity",
+ "description",
+ "meta",
+ ).From(actionlogTable)
+ }
+
+ // actionlogInsertQuery assembles query inserting actionlogs
+ //
+ // This function is auto-generated
+ actionlogInsertQuery = func(d goqu.DialectWrapper, res *actionlogType.Action) *goqu.InsertDataset {
+ return d.Insert(actionlogTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "ts": res.Timestamp,
+ "request_origin": res.RequestOrigin,
+ "request_id": res.RequestID,
+ "actor_ip_addr": res.ActorIPAddr,
+ "actor_id": res.ActorID,
+ "resource": res.Resource,
+ "action": res.Action,
+ "error": res.Error,
+ "severity": res.Severity,
+ "description": res.Description,
+ "meta": res.Meta,
+ })
+ }
+
+ // actionlogUpsertQuery assembles (insert+on-conflict) query for replacing actionlogs
+ //
+ // This function is auto-generated
+ actionlogUpsertQuery = func(d goqu.DialectWrapper, res *actionlogType.Action) *goqu.InsertDataset {
+ var target = `,id`
+
+ return actionlogInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "ts": res.Timestamp,
+ "request_origin": res.RequestOrigin,
+ "request_id": res.RequestID,
+ "actor_ip_addr": res.ActorIPAddr,
+ "actor_id": res.ActorID,
+ "resource": res.Resource,
+ "action": res.Action,
+ "error": res.Error,
+ "severity": res.Severity,
+ "description": res.Description,
+ "meta": res.Meta,
+ },
+ ),
+ )
+ }
+
+ // actionlogUpdateQuery assembles query for updating actionlogs
+ //
+ // This function is auto-generated
+ actionlogUpdateQuery = func(d goqu.DialectWrapper, res *actionlogType.Action) *goqu.UpdateDataset {
+ return d.Update(actionlogTable).
+ Set(goqu.Record{
+ "ts": res.Timestamp,
+ "request_origin": res.RequestOrigin,
+ "request_id": res.RequestID,
+ "actor_ip_addr": res.ActorIPAddr,
+ "actor_id": res.ActorID,
+ "resource": res.Resource,
+ "action": res.Action,
+ "error": res.Error,
+ "severity": res.Severity,
+ "description": res.Description,
+ "meta": res.Meta,
+ }).
+ Where(actionlogPrimaryKeys(res))
+ }
+
+ // actionlogDeleteQuery assembles delete query for removing actionlogs
+ //
+ // This function is auto-generated
+ actionlogDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(actionlogTable).Where(ee...)
+ }
+
+ // actionlogDeleteQuery assembles delete query for removing actionlogs
+ //
+ // This function is auto-generated
+ actionlogTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(actionlogTable)
+ }
+
+ // actionlogPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ actionlogPrimaryKeys = func(res *actionlogType.Action) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // apigwFilterTable represents apigwFilters store table
+ //
+ // This value is auto-generated
+ apigwFilterTable = goqu.T("apigw_filters")
+
+ // apigwFilterSelectQuery assembles select query for fetching apigwFilters
+ //
+ // This function is auto-generated
+ apigwFilterSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "route",
+ "weight",
+ "ref",
+ "kind",
+ "enabled",
+ "params",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(apigwFilterTable)
+ }
+
+ // apigwFilterInsertQuery assembles query inserting apigwFilters
+ //
+ // This function is auto-generated
+ apigwFilterInsertQuery = func(d goqu.DialectWrapper, res *systemType.ApigwFilter) *goqu.InsertDataset {
+ return d.Insert(apigwFilterTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "route": res.Route,
+ "weight": res.Weight,
+ "ref": res.Ref,
+ "kind": res.Kind,
+ "enabled": res.Enabled,
+ "params": res.Params,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // apigwFilterUpsertQuery assembles (insert+on-conflict) query for replacing apigwFilters
+ //
+ // This function is auto-generated
+ apigwFilterUpsertQuery = func(d goqu.DialectWrapper, res *systemType.ApigwFilter) *goqu.InsertDataset {
+ var target = `,id`
+
+ return apigwFilterInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "route": res.Route,
+ "weight": res.Weight,
+ "ref": res.Ref,
+ "kind": res.Kind,
+ "enabled": res.Enabled,
+ "params": res.Params,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // apigwFilterUpdateQuery assembles query for updating apigwFilters
+ //
+ // This function is auto-generated
+ apigwFilterUpdateQuery = func(d goqu.DialectWrapper, res *systemType.ApigwFilter) *goqu.UpdateDataset {
+ return d.Update(apigwFilterTable).
+ Set(goqu.Record{
+ "route": res.Route,
+ "weight": res.Weight,
+ "ref": res.Ref,
+ "kind": res.Kind,
+ "enabled": res.Enabled,
+ "params": res.Params,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(apigwFilterPrimaryKeys(res))
+ }
+
+ // apigwFilterDeleteQuery assembles delete query for removing apigwFilters
+ //
+ // This function is auto-generated
+ apigwFilterDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(apigwFilterTable).Where(ee...)
+ }
+
+ // apigwFilterDeleteQuery assembles delete query for removing apigwFilters
+ //
+ // This function is auto-generated
+ apigwFilterTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(apigwFilterTable)
+ }
+
+ // apigwFilterPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ apigwFilterPrimaryKeys = func(res *systemType.ApigwFilter) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // apigwRouteTable represents apigwRoutes store table
+ //
+ // This value is auto-generated
+ apigwRouteTable = goqu.T("apigw_routes")
+
+ // apigwRouteSelectQuery assembles select query for fetching apigwRoutes
+ //
+ // This function is auto-generated
+ apigwRouteSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "endpoint",
+ "method",
+ "enabled",
+ "group",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(apigwRouteTable)
+ }
+
+ // apigwRouteInsertQuery assembles query inserting apigwRoutes
+ //
+ // This function is auto-generated
+ apigwRouteInsertQuery = func(d goqu.DialectWrapper, res *systemType.ApigwRoute) *goqu.InsertDataset {
+ return d.Insert(apigwRouteTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "endpoint": res.Endpoint,
+ "method": res.Method,
+ "enabled": res.Enabled,
+ "group": res.Group,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // apigwRouteUpsertQuery assembles (insert+on-conflict) query for replacing apigwRoutes
+ //
+ // This function is auto-generated
+ apigwRouteUpsertQuery = func(d goqu.DialectWrapper, res *systemType.ApigwRoute) *goqu.InsertDataset {
+ var target = `,id`
+
+ return apigwRouteInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "endpoint": res.Endpoint,
+ "method": res.Method,
+ "enabled": res.Enabled,
+ "group": res.Group,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // apigwRouteUpdateQuery assembles query for updating apigwRoutes
+ //
+ // This function is auto-generated
+ apigwRouteUpdateQuery = func(d goqu.DialectWrapper, res *systemType.ApigwRoute) *goqu.UpdateDataset {
+ return d.Update(apigwRouteTable).
+ Set(goqu.Record{
+ "endpoint": res.Endpoint,
+ "method": res.Method,
+ "enabled": res.Enabled,
+ "group": res.Group,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(apigwRoutePrimaryKeys(res))
+ }
+
+ // apigwRouteDeleteQuery assembles delete query for removing apigwRoutes
+ //
+ // This function is auto-generated
+ apigwRouteDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(apigwRouteTable).Where(ee...)
+ }
+
+ // apigwRouteDeleteQuery assembles delete query for removing apigwRoutes
+ //
+ // This function is auto-generated
+ apigwRouteTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(apigwRouteTable)
+ }
+
+ // apigwRoutePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ apigwRoutePrimaryKeys = func(res *systemType.ApigwRoute) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // applicationTable represents applications store table
+ //
+ // This value is auto-generated
+ applicationTable = goqu.T("applications")
+
+ // applicationSelectQuery assembles select query for fetching applications
+ //
+ // This function is auto-generated
+ applicationSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "name",
+ "rel_owner",
+ "enabled",
+ "weight",
+ "unify",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(applicationTable)
+ }
+
+ // applicationInsertQuery assembles query inserting applications
+ //
+ // This function is auto-generated
+ applicationInsertQuery = func(d goqu.DialectWrapper, res *systemType.Application) *goqu.InsertDataset {
+ return d.Insert(applicationTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "name": res.Name,
+ "rel_owner": res.OwnerID,
+ "enabled": res.Enabled,
+ "weight": res.Weight,
+ "unify": res.Unify,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // applicationUpsertQuery assembles (insert+on-conflict) query for replacing applications
+ //
+ // This function is auto-generated
+ applicationUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Application) *goqu.InsertDataset {
+ var target = `,id`
+
+ return applicationInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "name": res.Name,
+ "rel_owner": res.OwnerID,
+ "enabled": res.Enabled,
+ "weight": res.Weight,
+ "unify": res.Unify,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // applicationUpdateQuery assembles query for updating applications
+ //
+ // This function is auto-generated
+ applicationUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Application) *goqu.UpdateDataset {
+ return d.Update(applicationTable).
+ Set(goqu.Record{
+ "name": res.Name,
+ "rel_owner": res.OwnerID,
+ "enabled": res.Enabled,
+ "weight": res.Weight,
+ "unify": res.Unify,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(applicationPrimaryKeys(res))
+ }
+
+ // applicationDeleteQuery assembles delete query for removing applications
+ //
+ // This function is auto-generated
+ applicationDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(applicationTable).Where(ee...)
+ }
+
+ // applicationDeleteQuery assembles delete query for removing applications
+ //
+ // This function is auto-generated
+ applicationTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(applicationTable)
+ }
+
+ // applicationPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ applicationPrimaryKeys = func(res *systemType.Application) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // attachmentTable represents attachments store table
+ //
+ // This value is auto-generated
+ attachmentTable = goqu.T("attachments")
+
+ // attachmentSelectQuery assembles select query for fetching attachments
+ //
+ // This function is auto-generated
+ attachmentSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "rel_owner",
+ "kind",
+ "url",
+ "preview_url",
+ "name",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(attachmentTable)
+ }
+
+ // attachmentInsertQuery assembles query inserting attachments
+ //
+ // This function is auto-generated
+ attachmentInsertQuery = func(d goqu.DialectWrapper, res *systemType.Attachment) *goqu.InsertDataset {
+ return d.Insert(attachmentTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "rel_owner": res.OwnerID,
+ "kind": res.Kind,
+ "url": res.Url,
+ "preview_url": res.PreviewUrl,
+ "name": res.Name,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // attachmentUpsertQuery assembles (insert+on-conflict) query for replacing attachments
+ //
+ // This function is auto-generated
+ attachmentUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Attachment) *goqu.InsertDataset {
+ var target = `,id`
+
+ return attachmentInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "rel_owner": res.OwnerID,
+ "kind": res.Kind,
+ "url": res.Url,
+ "preview_url": res.PreviewUrl,
+ "name": res.Name,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // attachmentUpdateQuery assembles query for updating attachments
+ //
+ // This function is auto-generated
+ attachmentUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Attachment) *goqu.UpdateDataset {
+ return d.Update(attachmentTable).
+ Set(goqu.Record{
+ "rel_owner": res.OwnerID,
+ "kind": res.Kind,
+ "url": res.Url,
+ "preview_url": res.PreviewUrl,
+ "name": res.Name,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(attachmentPrimaryKeys(res))
+ }
+
+ // attachmentDeleteQuery assembles delete query for removing attachments
+ //
+ // This function is auto-generated
+ attachmentDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(attachmentTable).Where(ee...)
+ }
+
+ // attachmentDeleteQuery assembles delete query for removing attachments
+ //
+ // This function is auto-generated
+ attachmentTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(attachmentTable)
+ }
+
+ // attachmentPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ attachmentPrimaryKeys = func(res *systemType.Attachment) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // authClientTable represents authClients store table
+ //
+ // This value is auto-generated
+ authClientTable = goqu.T("auth_clients")
+
+ // authClientSelectQuery assembles select query for fetching authClients
+ //
+ // This function is auto-generated
+ authClientSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "meta",
+ "secret",
+ "scope",
+ "valid_grant",
+ "redirect_uri",
+ "trusted",
+ "enabled",
+ "valid_from",
+ "expires_at",
+ "security",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "owned_by",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(authClientTable)
+ }
+
+ // authClientInsertQuery assembles query inserting authClients
+ //
+ // This function is auto-generated
+ authClientInsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthClient) *goqu.InsertDataset {
+ return d.Insert(authClientTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "secret": res.Secret,
+ "scope": res.Scope,
+ "valid_grant": res.ValidGrant,
+ "redirect_uri": res.RedirectURI,
+ "trusted": res.Trusted,
+ "enabled": res.Enabled,
+ "valid_from": res.ValidFrom,
+ "expires_at": res.ExpiresAt,
+ "security": res.Security,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // authClientUpsertQuery assembles (insert+on-conflict) query for replacing authClients
+ //
+ // This function is auto-generated
+ authClientUpsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthClient) *goqu.InsertDataset {
+ var target = `,id`
+
+ return authClientInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "secret": res.Secret,
+ "scope": res.Scope,
+ "valid_grant": res.ValidGrant,
+ "redirect_uri": res.RedirectURI,
+ "trusted": res.Trusted,
+ "enabled": res.Enabled,
+ "valid_from": res.ValidFrom,
+ "expires_at": res.ExpiresAt,
+ "security": res.Security,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // authClientUpdateQuery assembles query for updating authClients
+ //
+ // This function is auto-generated
+ authClientUpdateQuery = func(d goqu.DialectWrapper, res *systemType.AuthClient) *goqu.UpdateDataset {
+ return d.Update(authClientTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "secret": res.Secret,
+ "scope": res.Scope,
+ "valid_grant": res.ValidGrant,
+ "redirect_uri": res.RedirectURI,
+ "trusted": res.Trusted,
+ "enabled": res.Enabled,
+ "valid_from": res.ValidFrom,
+ "expires_at": res.ExpiresAt,
+ "security": res.Security,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(authClientPrimaryKeys(res))
+ }
+
+ // authClientDeleteQuery assembles delete query for removing authClients
+ //
+ // This function is auto-generated
+ authClientDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(authClientTable).Where(ee...)
+ }
+
+ // authClientDeleteQuery assembles delete query for removing authClients
+ //
+ // This function is auto-generated
+ authClientTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(authClientTable)
+ }
+
+ // authClientPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ authClientPrimaryKeys = func(res *systemType.AuthClient) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // authConfirmedClientTable represents authConfirmedClients store table
+ //
+ // This value is auto-generated
+ authConfirmedClientTable = goqu.T("auth_confirmed_clients")
+
+ // authConfirmedClientSelectQuery assembles select query for fetching authConfirmedClients
+ //
+ // This function is auto-generated
+ authConfirmedClientSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "rel_user",
+ "rel_client",
+ "confirmed_at",
+ ).From(authConfirmedClientTable)
+ }
+
+ // authConfirmedClientInsertQuery assembles query inserting authConfirmedClients
+ //
+ // This function is auto-generated
+ authConfirmedClientInsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthConfirmedClient) *goqu.InsertDataset {
+ return d.Insert(authConfirmedClientTable).
+ Rows(goqu.Record{
+ "rel_user": res.UserID,
+ "rel_client": res.ClientID,
+ "confirmed_at": res.ConfirmedAt,
+ })
+ }
+
+ // authConfirmedClientUpsertQuery assembles (insert+on-conflict) query for replacing authConfirmedClients
+ //
+ // This function is auto-generated
+ authConfirmedClientUpsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthConfirmedClient) *goqu.InsertDataset {
+ var target = `,rel_user,rel_client`
+
+ return authConfirmedClientInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "confirmed_at": res.ConfirmedAt,
+ },
+ ),
+ )
+ }
+
+ // authConfirmedClientUpdateQuery assembles query for updating authConfirmedClients
+ //
+ // This function is auto-generated
+ authConfirmedClientUpdateQuery = func(d goqu.DialectWrapper, res *systemType.AuthConfirmedClient) *goqu.UpdateDataset {
+ return d.Update(authConfirmedClientTable).
+ Set(goqu.Record{
+ "confirmed_at": res.ConfirmedAt,
+ }).
+ Where(authConfirmedClientPrimaryKeys(res))
+ }
+
+ // authConfirmedClientDeleteQuery assembles delete query for removing authConfirmedClients
+ //
+ // This function is auto-generated
+ authConfirmedClientDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(authConfirmedClientTable).Where(ee...)
+ }
+
+ // authConfirmedClientDeleteQuery assembles delete query for removing authConfirmedClients
+ //
+ // This function is auto-generated
+ authConfirmedClientTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(authConfirmedClientTable)
+ }
+
+ // authConfirmedClientPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ authConfirmedClientPrimaryKeys = func(res *systemType.AuthConfirmedClient) goqu.Ex {
+ return goqu.Ex{
+ "rel_user": res.UserID,
+ "rel_client": res.ClientID,
+ }
+ }
+
+ // authOa2tokenTable represents authOa2tokens store table
+ //
+ // This value is auto-generated
+ authOa2tokenTable = goqu.T("auth_oa2tokens")
+
+ // authOa2tokenSelectQuery assembles select query for fetching authOa2tokens
+ //
+ // This function is auto-generated
+ authOa2tokenSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "code",
+ "access",
+ "refresh",
+ "expires_at",
+ "created_at",
+ "data",
+ "rel_client",
+ "rel_user",
+ "remote_addr",
+ "user_agent",
+ ).From(authOa2tokenTable)
+ }
+
+ // authOa2tokenInsertQuery assembles query inserting authOa2tokens
+ //
+ // This function is auto-generated
+ authOa2tokenInsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthOa2token) *goqu.InsertDataset {
+ return d.Insert(authOa2tokenTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "code": res.Code,
+ "access": res.Access,
+ "refresh": res.Refresh,
+ "expires_at": res.ExpiresAt,
+ "created_at": res.CreatedAt,
+ "data": res.Data,
+ "rel_client": res.ClientID,
+ "rel_user": res.UserID,
+ "remote_addr": res.RemoteAddr,
+ "user_agent": res.UserAgent,
+ })
+ }
+
+ // authOa2tokenUpsertQuery assembles (insert+on-conflict) query for replacing authOa2tokens
+ //
+ // This function is auto-generated
+ authOa2tokenUpsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthOa2token) *goqu.InsertDataset {
+ var target = `,id`
+
+ return authOa2tokenInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "code": res.Code,
+ "access": res.Access,
+ "refresh": res.Refresh,
+ "expires_at": res.ExpiresAt,
+ "created_at": res.CreatedAt,
+ "data": res.Data,
+ "rel_client": res.ClientID,
+ "rel_user": res.UserID,
+ "remote_addr": res.RemoteAddr,
+ "user_agent": res.UserAgent,
+ },
+ ),
+ )
+ }
+
+ // authOa2tokenUpdateQuery assembles query for updating authOa2tokens
+ //
+ // This function is auto-generated
+ authOa2tokenUpdateQuery = func(d goqu.DialectWrapper, res *systemType.AuthOa2token) *goqu.UpdateDataset {
+ return d.Update(authOa2tokenTable).
+ Set(goqu.Record{
+ "code": res.Code,
+ "access": res.Access,
+ "refresh": res.Refresh,
+ "expires_at": res.ExpiresAt,
+ "created_at": res.CreatedAt,
+ "data": res.Data,
+ "rel_client": res.ClientID,
+ "rel_user": res.UserID,
+ "remote_addr": res.RemoteAddr,
+ "user_agent": res.UserAgent,
+ }).
+ Where(authOa2tokenPrimaryKeys(res))
+ }
+
+ // authOa2tokenDeleteQuery assembles delete query for removing authOa2tokens
+ //
+ // This function is auto-generated
+ authOa2tokenDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(authOa2tokenTable).Where(ee...)
+ }
+
+ // authOa2tokenDeleteQuery assembles delete query for removing authOa2tokens
+ //
+ // This function is auto-generated
+ authOa2tokenTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(authOa2tokenTable)
+ }
+
+ // authOa2tokenPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ authOa2tokenPrimaryKeys = func(res *systemType.AuthOa2token) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // authSessionTable represents authSessions store table
+ //
+ // This value is auto-generated
+ authSessionTable = goqu.T("auth_sessions")
+
+ // authSessionSelectQuery assembles select query for fetching authSessions
+ //
+ // This function is auto-generated
+ authSessionSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "data",
+ "rel_user",
+ "expires_at",
+ "created_at",
+ "remote_addr",
+ "user_agent",
+ ).From(authSessionTable)
+ }
+
+ // authSessionInsertQuery assembles query inserting authSessions
+ //
+ // This function is auto-generated
+ authSessionInsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthSession) *goqu.InsertDataset {
+ return d.Insert(authSessionTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "data": res.Data,
+ "rel_user": res.UserID,
+ "expires_at": res.ExpiresAt,
+ "created_at": res.CreatedAt,
+ "remote_addr": res.RemoteAddr,
+ "user_agent": res.UserAgent,
+ })
+ }
+
+ // authSessionUpsertQuery assembles (insert+on-conflict) query for replacing authSessions
+ //
+ // This function is auto-generated
+ authSessionUpsertQuery = func(d goqu.DialectWrapper, res *systemType.AuthSession) *goqu.InsertDataset {
+ var target = `,id`
+
+ return authSessionInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "data": res.Data,
+ "rel_user": res.UserID,
+ "expires_at": res.ExpiresAt,
+ "created_at": res.CreatedAt,
+ "remote_addr": res.RemoteAddr,
+ "user_agent": res.UserAgent,
+ },
+ ),
+ )
+ }
+
+ // authSessionUpdateQuery assembles query for updating authSessions
+ //
+ // This function is auto-generated
+ authSessionUpdateQuery = func(d goqu.DialectWrapper, res *systemType.AuthSession) *goqu.UpdateDataset {
+ return d.Update(authSessionTable).
+ Set(goqu.Record{
+ "data": res.Data,
+ "rel_user": res.UserID,
+ "expires_at": res.ExpiresAt,
+ "created_at": res.CreatedAt,
+ "remote_addr": res.RemoteAddr,
+ "user_agent": res.UserAgent,
+ }).
+ Where(authSessionPrimaryKeys(res))
+ }
+
+ // authSessionDeleteQuery assembles delete query for removing authSessions
+ //
+ // This function is auto-generated
+ authSessionDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(authSessionTable).Where(ee...)
+ }
+
+ // authSessionDeleteQuery assembles delete query for removing authSessions
+ //
+ // This function is auto-generated
+ authSessionTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(authSessionTable)
+ }
+
+ // authSessionPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ authSessionPrimaryKeys = func(res *systemType.AuthSession) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // automationSessionTable represents automationSessions store table
+ //
+ // This value is auto-generated
+ automationSessionTable = goqu.T("automation_sessions")
+
+ // automationSessionSelectQuery assembles select query for fetching automationSessions
+ //
+ // This function is auto-generated
+ automationSessionSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "rel_workflow",
+ "event_type",
+ "resource_type",
+ "status",
+ "input",
+ "output",
+ "stacktrace",
+ "created_by",
+ "created_at",
+ "purge_at",
+ "completed_at",
+ "suspended_at",
+ "error",
+ ).From(automationSessionTable)
+ }
+
+ // automationSessionInsertQuery assembles query inserting automationSessions
+ //
+ // This function is auto-generated
+ automationSessionInsertQuery = func(d goqu.DialectWrapper, res *automationType.Session) *goqu.InsertDataset {
+ return d.Insert(automationSessionTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "rel_workflow": res.WorkflowID,
+ "event_type": res.EventType,
+ "resource_type": res.ResourceType,
+ "status": res.Status,
+ "input": res.Input,
+ "output": res.Output,
+ "stacktrace": res.Stacktrace,
+ "created_by": res.CreatedBy,
+ "created_at": res.CreatedAt,
+ "purge_at": res.PurgeAt,
+ "completed_at": res.CompletedAt,
+ "suspended_at": res.SuspendedAt,
+ "error": res.Error,
+ })
+ }
+
+ // automationSessionUpsertQuery assembles (insert+on-conflict) query for replacing automationSessions
+ //
+ // This function is auto-generated
+ automationSessionUpsertQuery = func(d goqu.DialectWrapper, res *automationType.Session) *goqu.InsertDataset {
+ var target = `,id`
+
+ return automationSessionInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "rel_workflow": res.WorkflowID,
+ "event_type": res.EventType,
+ "resource_type": res.ResourceType,
+ "status": res.Status,
+ "input": res.Input,
+ "output": res.Output,
+ "stacktrace": res.Stacktrace,
+ "created_by": res.CreatedBy,
+ "created_at": res.CreatedAt,
+ "purge_at": res.PurgeAt,
+ "completed_at": res.CompletedAt,
+ "suspended_at": res.SuspendedAt,
+ "error": res.Error,
+ },
+ ),
+ )
+ }
+
+ // automationSessionUpdateQuery assembles query for updating automationSessions
+ //
+ // This function is auto-generated
+ automationSessionUpdateQuery = func(d goqu.DialectWrapper, res *automationType.Session) *goqu.UpdateDataset {
+ return d.Update(automationSessionTable).
+ Set(goqu.Record{
+ "rel_workflow": res.WorkflowID,
+ "event_type": res.EventType,
+ "resource_type": res.ResourceType,
+ "status": res.Status,
+ "input": res.Input,
+ "output": res.Output,
+ "stacktrace": res.Stacktrace,
+ "created_by": res.CreatedBy,
+ "created_at": res.CreatedAt,
+ "purge_at": res.PurgeAt,
+ "completed_at": res.CompletedAt,
+ "suspended_at": res.SuspendedAt,
+ "error": res.Error,
+ }).
+ Where(automationSessionPrimaryKeys(res))
+ }
+
+ // automationSessionDeleteQuery assembles delete query for removing automationSessions
+ //
+ // This function is auto-generated
+ automationSessionDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(automationSessionTable).Where(ee...)
+ }
+
+ // automationSessionDeleteQuery assembles delete query for removing automationSessions
+ //
+ // This function is auto-generated
+ automationSessionTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(automationSessionTable)
+ }
+
+ // automationSessionPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ automationSessionPrimaryKeys = func(res *automationType.Session) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // automationTriggerTable represents automationTriggers store table
+ //
+ // This value is auto-generated
+ automationTriggerTable = goqu.T("automation_triggers")
+
+ // automationTriggerSelectQuery assembles select query for fetching automationTriggers
+ //
+ // This function is auto-generated
+ automationTriggerSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "rel_workflow",
+ "rel_step",
+ "enabled",
+ "resource_type",
+ "event_type",
+ "meta",
+ "constraints",
+ "input",
+ "owned_by",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(automationTriggerTable)
+ }
+
+ // automationTriggerInsertQuery assembles query inserting automationTriggers
+ //
+ // This function is auto-generated
+ automationTriggerInsertQuery = func(d goqu.DialectWrapper, res *automationType.Trigger) *goqu.InsertDataset {
+ return d.Insert(automationTriggerTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "rel_workflow": res.WorkflowID,
+ "rel_step": res.StepID,
+ "enabled": res.Enabled,
+ "resource_type": res.ResourceType,
+ "event_type": res.EventType,
+ "meta": res.Meta,
+ "constraints": res.Constraints,
+ "input": res.Input,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // automationTriggerUpsertQuery assembles (insert+on-conflict) query for replacing automationTriggers
+ //
+ // This function is auto-generated
+ automationTriggerUpsertQuery = func(d goqu.DialectWrapper, res *automationType.Trigger) *goqu.InsertDataset {
+ var target = `,id`
+
+ return automationTriggerInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "rel_workflow": res.WorkflowID,
+ "rel_step": res.StepID,
+ "enabled": res.Enabled,
+ "resource_type": res.ResourceType,
+ "event_type": res.EventType,
+ "meta": res.Meta,
+ "constraints": res.Constraints,
+ "input": res.Input,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // automationTriggerUpdateQuery assembles query for updating automationTriggers
+ //
+ // This function is auto-generated
+ automationTriggerUpdateQuery = func(d goqu.DialectWrapper, res *automationType.Trigger) *goqu.UpdateDataset {
+ return d.Update(automationTriggerTable).
+ Set(goqu.Record{
+ "rel_workflow": res.WorkflowID,
+ "rel_step": res.StepID,
+ "enabled": res.Enabled,
+ "resource_type": res.ResourceType,
+ "event_type": res.EventType,
+ "meta": res.Meta,
+ "constraints": res.Constraints,
+ "input": res.Input,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(automationTriggerPrimaryKeys(res))
+ }
+
+ // automationTriggerDeleteQuery assembles delete query for removing automationTriggers
+ //
+ // This function is auto-generated
+ automationTriggerDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(automationTriggerTable).Where(ee...)
+ }
+
+ // automationTriggerDeleteQuery assembles delete query for removing automationTriggers
+ //
+ // This function is auto-generated
+ automationTriggerTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(automationTriggerTable)
+ }
+
+ // automationTriggerPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ automationTriggerPrimaryKeys = func(res *automationType.Trigger) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // automationWorkflowTable represents automationWorkflows store table
+ //
+ // This value is auto-generated
+ automationWorkflowTable = goqu.T("automation_workflows")
+
+ // automationWorkflowSelectQuery assembles select query for fetching automationWorkflows
+ //
+ // This function is auto-generated
+ automationWorkflowSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "meta",
+ "enabled",
+ "trace",
+ "keep_sessions",
+ "scope",
+ "steps",
+ "paths",
+ "issues",
+ "run_as",
+ "owned_by",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(automationWorkflowTable)
+ }
+
+ // automationWorkflowInsertQuery assembles query inserting automationWorkflows
+ //
+ // This function is auto-generated
+ automationWorkflowInsertQuery = func(d goqu.DialectWrapper, res *automationType.Workflow) *goqu.InsertDataset {
+ return d.Insert(automationWorkflowTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "enabled": res.Enabled,
+ "trace": res.Trace,
+ "keep_sessions": res.KeepSessions,
+ "scope": res.Scope,
+ "steps": res.Steps,
+ "paths": res.Paths,
+ "issues": res.Issues,
+ "run_as": res.RunAs,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // automationWorkflowUpsertQuery assembles (insert+on-conflict) query for replacing automationWorkflows
+ //
+ // This function is auto-generated
+ automationWorkflowUpsertQuery = func(d goqu.DialectWrapper, res *automationType.Workflow) *goqu.InsertDataset {
+ var target = `,id`
+
+ return automationWorkflowInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "enabled": res.Enabled,
+ "trace": res.Trace,
+ "keep_sessions": res.KeepSessions,
+ "scope": res.Scope,
+ "steps": res.Steps,
+ "paths": res.Paths,
+ "issues": res.Issues,
+ "run_as": res.RunAs,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // automationWorkflowUpdateQuery assembles query for updating automationWorkflows
+ //
+ // This function is auto-generated
+ automationWorkflowUpdateQuery = func(d goqu.DialectWrapper, res *automationType.Workflow) *goqu.UpdateDataset {
+ return d.Update(automationWorkflowTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "enabled": res.Enabled,
+ "trace": res.Trace,
+ "keep_sessions": res.KeepSessions,
+ "scope": res.Scope,
+ "steps": res.Steps,
+ "paths": res.Paths,
+ "issues": res.Issues,
+ "run_as": res.RunAs,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(automationWorkflowPrimaryKeys(res))
+ }
+
+ // automationWorkflowDeleteQuery assembles delete query for removing automationWorkflows
+ //
+ // This function is auto-generated
+ automationWorkflowDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(automationWorkflowTable).Where(ee...)
+ }
+
+ // automationWorkflowDeleteQuery assembles delete query for removing automationWorkflows
+ //
+ // This function is auto-generated
+ automationWorkflowTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(automationWorkflowTable)
+ }
+
+ // automationWorkflowPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ automationWorkflowPrimaryKeys = func(res *automationType.Workflow) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeAttachmentTable represents composeAttachments store table
+ //
+ // This value is auto-generated
+ composeAttachmentTable = goqu.T("compose_attachment")
+
+ // composeAttachmentSelectQuery assembles select query for fetching composeAttachments
+ //
+ // This function is auto-generated
+ composeAttachmentSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "rel_owner",
+ "rel_namespace",
+ "kind",
+ "url",
+ "preview_url",
+ "name",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(composeAttachmentTable)
+ }
+
+ // composeAttachmentInsertQuery assembles query inserting composeAttachments
+ //
+ // This function is auto-generated
+ composeAttachmentInsertQuery = func(d goqu.DialectWrapper, res *composeType.Attachment) *goqu.InsertDataset {
+ return d.Insert(composeAttachmentTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "rel_owner": res.OwnerID,
+ "rel_namespace": res.NamespaceID,
+ "kind": res.Kind,
+ "url": res.Url,
+ "preview_url": res.PreviewUrl,
+ "name": res.Name,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composeAttachmentUpsertQuery assembles (insert+on-conflict) query for replacing composeAttachments
+ //
+ // This function is auto-generated
+ composeAttachmentUpsertQuery = func(d goqu.DialectWrapper, res *composeType.Attachment) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composeAttachmentInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "rel_owner": res.OwnerID,
+ "rel_namespace": res.NamespaceID,
+ "kind": res.Kind,
+ "url": res.Url,
+ "preview_url": res.PreviewUrl,
+ "name": res.Name,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composeAttachmentUpdateQuery assembles query for updating composeAttachments
+ //
+ // This function is auto-generated
+ composeAttachmentUpdateQuery = func(d goqu.DialectWrapper, res *composeType.Attachment) *goqu.UpdateDataset {
+ return d.Update(composeAttachmentTable).
+ Set(goqu.Record{
+ "rel_owner": res.OwnerID,
+ "rel_namespace": res.NamespaceID,
+ "kind": res.Kind,
+ "url": res.Url,
+ "preview_url": res.PreviewUrl,
+ "name": res.Name,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composeAttachmentPrimaryKeys(res))
+ }
+
+ // composeAttachmentDeleteQuery assembles delete query for removing composeAttachments
+ //
+ // This function is auto-generated
+ composeAttachmentDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeAttachmentTable).Where(ee...)
+ }
+
+ // composeAttachmentDeleteQuery assembles delete query for removing composeAttachments
+ //
+ // This function is auto-generated
+ composeAttachmentTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeAttachmentTable)
+ }
+
+ // composeAttachmentPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeAttachmentPrimaryKeys = func(res *composeType.Attachment) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeChartTable represents composeCharts store table
+ //
+ // This value is auto-generated
+ composeChartTable = goqu.T("compose_chart")
+
+ // composeChartSelectQuery assembles select query for fetching composeCharts
+ //
+ // This function is auto-generated
+ composeChartSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "name",
+ "config",
+ "rel_namespace",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(composeChartTable)
+ }
+
+ // composeChartInsertQuery assembles query inserting composeCharts
+ //
+ // This function is auto-generated
+ composeChartInsertQuery = func(d goqu.DialectWrapper, res *composeType.Chart) *goqu.InsertDataset {
+ return d.Insert(composeChartTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "name": res.Name,
+ "config": res.Config,
+ "rel_namespace": res.NamespaceID,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composeChartUpsertQuery assembles (insert+on-conflict) query for replacing composeCharts
+ //
+ // This function is auto-generated
+ composeChartUpsertQuery = func(d goqu.DialectWrapper, res *composeType.Chart) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composeChartInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "name": res.Name,
+ "config": res.Config,
+ "rel_namespace": res.NamespaceID,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composeChartUpdateQuery assembles query for updating composeCharts
+ //
+ // This function is auto-generated
+ composeChartUpdateQuery = func(d goqu.DialectWrapper, res *composeType.Chart) *goqu.UpdateDataset {
+ return d.Update(composeChartTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "name": res.Name,
+ "config": res.Config,
+ "rel_namespace": res.NamespaceID,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composeChartPrimaryKeys(res))
+ }
+
+ // composeChartDeleteQuery assembles delete query for removing composeCharts
+ //
+ // This function is auto-generated
+ composeChartDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeChartTable).Where(ee...)
+ }
+
+ // composeChartDeleteQuery assembles delete query for removing composeCharts
+ //
+ // This function is auto-generated
+ composeChartTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeChartTable)
+ }
+
+ // composeChartPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeChartPrimaryKeys = func(res *composeType.Chart) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeModuleTable represents composeModules store table
+ //
+ // This value is auto-generated
+ composeModuleTable = goqu.T("compose_module")
+
+ // composeModuleSelectQuery assembles select query for fetching composeModules
+ //
+ // This function is auto-generated
+ composeModuleSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "meta",
+ "rel_namespace",
+ "name",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(composeModuleTable)
+ }
+
+ // composeModuleInsertQuery assembles query inserting composeModules
+ //
+ // This function is auto-generated
+ composeModuleInsertQuery = func(d goqu.DialectWrapper, res *composeType.Module) *goqu.InsertDataset {
+ return d.Insert(composeModuleTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "rel_namespace": res.NamespaceID,
+ "name": res.Name,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composeModuleUpsertQuery assembles (insert+on-conflict) query for replacing composeModules
+ //
+ // This function is auto-generated
+ composeModuleUpsertQuery = func(d goqu.DialectWrapper, res *composeType.Module) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composeModuleInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "rel_namespace": res.NamespaceID,
+ "name": res.Name,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composeModuleUpdateQuery assembles query for updating composeModules
+ //
+ // This function is auto-generated
+ composeModuleUpdateQuery = func(d goqu.DialectWrapper, res *composeType.Module) *goqu.UpdateDataset {
+ return d.Update(composeModuleTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "rel_namespace": res.NamespaceID,
+ "name": res.Name,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composeModulePrimaryKeys(res))
+ }
+
+ // composeModuleDeleteQuery assembles delete query for removing composeModules
+ //
+ // This function is auto-generated
+ composeModuleDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeModuleTable).Where(ee...)
+ }
+
+ // composeModuleDeleteQuery assembles delete query for removing composeModules
+ //
+ // This function is auto-generated
+ composeModuleTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeModuleTable)
+ }
+
+ // composeModulePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeModulePrimaryKeys = func(res *composeType.Module) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeModuleFieldTable represents composeModuleFields store table
+ //
+ // This value is auto-generated
+ composeModuleFieldTable = goqu.T("compose_module_field")
+
+ // composeModuleFieldSelectQuery assembles select query for fetching composeModuleFields
+ //
+ // This function is auto-generated
+ composeModuleFieldSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "rel_module",
+ "place",
+ "kind",
+ "name",
+ "label",
+ "options",
+ "is_private",
+ "is_required",
+ "is_visible",
+ "is_multi",
+ "default_value",
+ "expressions",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(composeModuleFieldTable)
+ }
+
+ // composeModuleFieldInsertQuery assembles query inserting composeModuleFields
+ //
+ // This function is auto-generated
+ composeModuleFieldInsertQuery = func(d goqu.DialectWrapper, res *composeType.ModuleField) *goqu.InsertDataset {
+ return d.Insert(composeModuleFieldTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "rel_module": res.ModuleID,
+ "place": res.Place,
+ "kind": res.Kind,
+ "name": res.Name,
+ "label": res.Label,
+ "options": res.Options,
+ "is_private": res.Private,
+ "is_required": res.Required,
+ "is_visible": res.Visible,
+ "is_multi": res.Multi,
+ "default_value": res.DefaultValue,
+ "expressions": res.Expressions,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composeModuleFieldUpsertQuery assembles (insert+on-conflict) query for replacing composeModuleFields
+ //
+ // This function is auto-generated
+ composeModuleFieldUpsertQuery = func(d goqu.DialectWrapper, res *composeType.ModuleField) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composeModuleFieldInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "rel_module": res.ModuleID,
+ "place": res.Place,
+ "kind": res.Kind,
+ "name": res.Name,
+ "label": res.Label,
+ "options": res.Options,
+ "is_private": res.Private,
+ "is_required": res.Required,
+ "is_visible": res.Visible,
+ "is_multi": res.Multi,
+ "default_value": res.DefaultValue,
+ "expressions": res.Expressions,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composeModuleFieldUpdateQuery assembles query for updating composeModuleFields
+ //
+ // This function is auto-generated
+ composeModuleFieldUpdateQuery = func(d goqu.DialectWrapper, res *composeType.ModuleField) *goqu.UpdateDataset {
+ return d.Update(composeModuleFieldTable).
+ Set(goqu.Record{
+ "rel_module": res.ModuleID,
+ "place": res.Place,
+ "kind": res.Kind,
+ "name": res.Name,
+ "label": res.Label,
+ "options": res.Options,
+ "is_private": res.Private,
+ "is_required": res.Required,
+ "is_visible": res.Visible,
+ "is_multi": res.Multi,
+ "default_value": res.DefaultValue,
+ "expressions": res.Expressions,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composeModuleFieldPrimaryKeys(res))
+ }
+
+ // composeModuleFieldDeleteQuery assembles delete query for removing composeModuleFields
+ //
+ // This function is auto-generated
+ composeModuleFieldDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeModuleFieldTable).Where(ee...)
+ }
+
+ // composeModuleFieldDeleteQuery assembles delete query for removing composeModuleFields
+ //
+ // This function is auto-generated
+ composeModuleFieldTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeModuleFieldTable)
+ }
+
+ // composeModuleFieldPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeModuleFieldPrimaryKeys = func(res *composeType.ModuleField) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeNamespaceTable represents composeNamespaces store table
+ //
+ // This value is auto-generated
+ composeNamespaceTable = goqu.T("compose_namespace")
+
+ // composeNamespaceSelectQuery assembles select query for fetching composeNamespaces
+ //
+ // This function is auto-generated
+ composeNamespaceSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "slug",
+ "enabled",
+ "meta",
+ "name",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(composeNamespaceTable)
+ }
+
+ // composeNamespaceInsertQuery assembles query inserting composeNamespaces
+ //
+ // This function is auto-generated
+ composeNamespaceInsertQuery = func(d goqu.DialectWrapper, res *composeType.Namespace) *goqu.InsertDataset {
+ return d.Insert(composeNamespaceTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "slug": res.Slug,
+ "enabled": res.Enabled,
+ "meta": res.Meta,
+ "name": res.Name,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composeNamespaceUpsertQuery assembles (insert+on-conflict) query for replacing composeNamespaces
+ //
+ // This function is auto-generated
+ composeNamespaceUpsertQuery = func(d goqu.DialectWrapper, res *composeType.Namespace) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composeNamespaceInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "slug": res.Slug,
+ "enabled": res.Enabled,
+ "meta": res.Meta,
+ "name": res.Name,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composeNamespaceUpdateQuery assembles query for updating composeNamespaces
+ //
+ // This function is auto-generated
+ composeNamespaceUpdateQuery = func(d goqu.DialectWrapper, res *composeType.Namespace) *goqu.UpdateDataset {
+ return d.Update(composeNamespaceTable).
+ Set(goqu.Record{
+ "slug": res.Slug,
+ "enabled": res.Enabled,
+ "meta": res.Meta,
+ "name": res.Name,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composeNamespacePrimaryKeys(res))
+ }
+
+ // composeNamespaceDeleteQuery assembles delete query for removing composeNamespaces
+ //
+ // This function is auto-generated
+ composeNamespaceDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeNamespaceTable).Where(ee...)
+ }
+
+ // composeNamespaceDeleteQuery assembles delete query for removing composeNamespaces
+ //
+ // This function is auto-generated
+ composeNamespaceTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeNamespaceTable)
+ }
+
+ // composeNamespacePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeNamespacePrimaryKeys = func(res *composeType.Namespace) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composePageTable represents composePages store table
+ //
+ // This value is auto-generated
+ composePageTable = goqu.T("compose_page")
+
+ // composePageSelectQuery assembles select query for fetching composePages
+ //
+ // This function is auto-generated
+ composePageSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "self_id",
+ "rel_module",
+ "rel_namespace",
+ "handle",
+ "config",
+ "blocks",
+ "visible",
+ "weight",
+ "title",
+ "description",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(composePageTable)
+ }
+
+ // composePageInsertQuery assembles query inserting composePages
+ //
+ // This function is auto-generated
+ composePageInsertQuery = func(d goqu.DialectWrapper, res *composeType.Page) *goqu.InsertDataset {
+ return d.Insert(composePageTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "self_id": res.SelfID,
+ "rel_module": res.ModuleID,
+ "rel_namespace": res.NamespaceID,
+ "handle": res.Handle,
+ "config": res.Config,
+ "blocks": res.Blocks,
+ "visible": res.Visible,
+ "weight": res.Weight,
+ "title": res.Title,
+ "description": res.Description,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composePageUpsertQuery assembles (insert+on-conflict) query for replacing composePages
+ //
+ // This function is auto-generated
+ composePageUpsertQuery = func(d goqu.DialectWrapper, res *composeType.Page) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composePageInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "self_id": res.SelfID,
+ "rel_module": res.ModuleID,
+ "rel_namespace": res.NamespaceID,
+ "handle": res.Handle,
+ "config": res.Config,
+ "blocks": res.Blocks,
+ "visible": res.Visible,
+ "weight": res.Weight,
+ "title": res.Title,
+ "description": res.Description,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composePageUpdateQuery assembles query for updating composePages
+ //
+ // This function is auto-generated
+ composePageUpdateQuery = func(d goqu.DialectWrapper, res *composeType.Page) *goqu.UpdateDataset {
+ return d.Update(composePageTable).
+ Set(goqu.Record{
+ "self_id": res.SelfID,
+ "rel_module": res.ModuleID,
+ "rel_namespace": res.NamespaceID,
+ "handle": res.Handle,
+ "config": res.Config,
+ "blocks": res.Blocks,
+ "visible": res.Visible,
+ "weight": res.Weight,
+ "title": res.Title,
+ "description": res.Description,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composePagePrimaryKeys(res))
+ }
+
+ // composePageDeleteQuery assembles delete query for removing composePages
+ //
+ // This function is auto-generated
+ composePageDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composePageTable).Where(ee...)
+ }
+
+ // composePageDeleteQuery assembles delete query for removing composePages
+ //
+ // This function is auto-generated
+ composePageTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composePageTable)
+ }
+
+ // composePagePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composePagePrimaryKeys = func(res *composeType.Page) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeRecordTable represents composeRecords store table
+ //
+ // This value is auto-generated
+ composeRecordTable = goqu.T("compose_record")
+
+ // composeRecordSelectQuery assembles select query for fetching composeRecords
+ //
+ // This function is auto-generated
+ composeRecordSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "module_id",
+ "rel_namespace",
+ "owned_by",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(composeRecordTable)
+ }
+
+ // composeRecordInsertQuery assembles query inserting composeRecords
+ //
+ // This function is auto-generated
+ composeRecordInsertQuery = func(d goqu.DialectWrapper, res *composeType.Record) *goqu.InsertDataset {
+ return d.Insert(composeRecordTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "module_id": res.ModuleID,
+ "rel_namespace": res.NamespaceID,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // composeRecordUpsertQuery assembles (insert+on-conflict) query for replacing composeRecords
+ //
+ // This function is auto-generated
+ composeRecordUpsertQuery = func(d goqu.DialectWrapper, res *composeType.Record) *goqu.InsertDataset {
+ var target = `,id`
+
+ return composeRecordInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "module_id": res.ModuleID,
+ "rel_namespace": res.NamespaceID,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // composeRecordUpdateQuery assembles query for updating composeRecords
+ //
+ // This function is auto-generated
+ composeRecordUpdateQuery = func(d goqu.DialectWrapper, res *composeType.Record) *goqu.UpdateDataset {
+ return d.Update(composeRecordTable).
+ Set(goqu.Record{
+ "module_id": res.ModuleID,
+ "rel_namespace": res.NamespaceID,
+ "owned_by": res.OwnedBy,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(composeRecordPrimaryKeys(res))
+ }
+
+ // composeRecordDeleteQuery assembles delete query for removing composeRecords
+ //
+ // This function is auto-generated
+ composeRecordDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeRecordTable).Where(ee...)
+ }
+
+ // composeRecordDeleteQuery assembles delete query for removing composeRecords
+ //
+ // This function is auto-generated
+ composeRecordTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeRecordTable)
+ }
+
+ // composeRecordPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeRecordPrimaryKeys = func(res *composeType.Record) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // composeRecordValueTable represents composeRecordValues store table
+ //
+ // This value is auto-generated
+ composeRecordValueTable = goqu.T("compose_record_value")
+
+ // composeRecordValueSelectQuery assembles select query for fetching composeRecordValues
+ //
+ // This function is auto-generated
+ composeRecordValueSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "record_id",
+ "name",
+ "place",
+ "ref",
+ "value",
+ "deleted_at",
+ ).From(composeRecordValueTable)
+ }
+
+ // composeRecordValueInsertQuery assembles query inserting composeRecordValues
+ //
+ // This function is auto-generated
+ composeRecordValueInsertQuery = func(d goqu.DialectWrapper, res *composeType.RecordValue) *goqu.InsertDataset {
+ return d.Insert(composeRecordValueTable).
+ Rows(goqu.Record{
+ "record_id": res.RecordID,
+ "name": res.Name,
+ "place": res.Place,
+ "ref": res.Ref,
+ "value": res.Value,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // composeRecordValueUpsertQuery assembles (insert+on-conflict) query for replacing composeRecordValues
+ //
+ // This function is auto-generated
+ composeRecordValueUpsertQuery = func(d goqu.DialectWrapper, res *composeType.RecordValue) *goqu.InsertDataset {
+ var target = `,record_id,name,place`
+
+ return composeRecordValueInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "ref": res.Ref,
+ "value": res.Value,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // composeRecordValueUpdateQuery assembles query for updating composeRecordValues
+ //
+ // This function is auto-generated
+ composeRecordValueUpdateQuery = func(d goqu.DialectWrapper, res *composeType.RecordValue) *goqu.UpdateDataset {
+ return d.Update(composeRecordValueTable).
+ Set(goqu.Record{
+ "ref": res.Ref,
+ "value": res.Value,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(composeRecordValuePrimaryKeys(res))
+ }
+
+ // composeRecordValueDeleteQuery assembles delete query for removing composeRecordValues
+ //
+ // This function is auto-generated
+ composeRecordValueDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(composeRecordValueTable).Where(ee...)
+ }
+
+ // composeRecordValueDeleteQuery assembles delete query for removing composeRecordValues
+ //
+ // This function is auto-generated
+ composeRecordValueTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(composeRecordValueTable)
+ }
+
+ // composeRecordValuePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ composeRecordValuePrimaryKeys = func(res *composeType.RecordValue) goqu.Ex {
+ return goqu.Ex{
+ "record_id": res.RecordID,
+ "name": res.Name,
+ "place": res.Place,
+ }
+ }
+
+ // credentialTable represents credentials store table
+ //
+ // This value is auto-generated
+ credentialTable = goqu.T("credentials")
+
+ // credentialSelectQuery assembles select query for fetching credentials
+ //
+ // This function is auto-generated
+ credentialSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "rel_owner",
+ "kind",
+ "label",
+ "credentials",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "last_used_at",
+ "expires_at",
+ ).From(credentialTable)
+ }
+
+ // credentialInsertQuery assembles query inserting credentials
+ //
+ // This function is auto-generated
+ credentialInsertQuery = func(d goqu.DialectWrapper, res *systemType.Credential) *goqu.InsertDataset {
+ return d.Insert(credentialTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "rel_owner": res.OwnerID,
+ "kind": res.Kind,
+ "label": res.Label,
+ "credentials": res.Credentials,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "last_used_at": res.LastUsedAt,
+ "expires_at": res.ExpiresAt,
+ })
+ }
+
+ // credentialUpsertQuery assembles (insert+on-conflict) query for replacing credentials
+ //
+ // This function is auto-generated
+ credentialUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Credential) *goqu.InsertDataset {
+ var target = `,id`
+
+ return credentialInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "rel_owner": res.OwnerID,
+ "kind": res.Kind,
+ "label": res.Label,
+ "credentials": res.Credentials,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "last_used_at": res.LastUsedAt,
+ "expires_at": res.ExpiresAt,
+ },
+ ),
+ )
+ }
+
+ // credentialUpdateQuery assembles query for updating credentials
+ //
+ // This function is auto-generated
+ credentialUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Credential) *goqu.UpdateDataset {
+ return d.Update(credentialTable).
+ Set(goqu.Record{
+ "rel_owner": res.OwnerID,
+ "kind": res.Kind,
+ "label": res.Label,
+ "credentials": res.Credentials,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "last_used_at": res.LastUsedAt,
+ "expires_at": res.ExpiresAt,
+ }).
+ Where(credentialPrimaryKeys(res))
+ }
+
+ // credentialDeleteQuery assembles delete query for removing credentials
+ //
+ // This function is auto-generated
+ credentialDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(credentialTable).Where(ee...)
+ }
+
+ // credentialDeleteQuery assembles delete query for removing credentials
+ //
+ // This function is auto-generated
+ credentialTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(credentialTable)
+ }
+
+ // credentialPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ credentialPrimaryKeys = func(res *systemType.Credential) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // federationExposedModuleTable represents federationExposedModules store table
+ //
+ // This value is auto-generated
+ federationExposedModuleTable = goqu.T("federation_exposed_module")
+
+ // federationExposedModuleSelectQuery assembles select query for fetching federationExposedModules
+ //
+ // This function is auto-generated
+ federationExposedModuleSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "name",
+ "node_id",
+ "compose_module_id",
+ "compose_namespace_id",
+ "fields",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(federationExposedModuleTable)
+ }
+
+ // federationExposedModuleInsertQuery assembles query inserting federationExposedModules
+ //
+ // This function is auto-generated
+ federationExposedModuleInsertQuery = func(d goqu.DialectWrapper, res *federationType.ExposedModule) *goqu.InsertDataset {
+ return d.Insert(federationExposedModuleTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "name": res.Name,
+ "node_id": res.NodeID,
+ "compose_module_id": res.ComposeModuleID,
+ "compose_namespace_id": res.ComposeNamespaceID,
+ "fields": res.Fields,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // federationExposedModuleUpsertQuery assembles (insert+on-conflict) query for replacing federationExposedModules
+ //
+ // This function is auto-generated
+ federationExposedModuleUpsertQuery = func(d goqu.DialectWrapper, res *federationType.ExposedModule) *goqu.InsertDataset {
+ var target = `,id`
+
+ return federationExposedModuleInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "name": res.Name,
+ "node_id": res.NodeID,
+ "compose_module_id": res.ComposeModuleID,
+ "compose_namespace_id": res.ComposeNamespaceID,
+ "fields": res.Fields,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // federationExposedModuleUpdateQuery assembles query for updating federationExposedModules
+ //
+ // This function is auto-generated
+ federationExposedModuleUpdateQuery = func(d goqu.DialectWrapper, res *federationType.ExposedModule) *goqu.UpdateDataset {
+ return d.Update(federationExposedModuleTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "name": res.Name,
+ "node_id": res.NodeID,
+ "compose_module_id": res.ComposeModuleID,
+ "compose_namespace_id": res.ComposeNamespaceID,
+ "fields": res.Fields,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(federationExposedModulePrimaryKeys(res))
+ }
+
+ // federationExposedModuleDeleteQuery assembles delete query for removing federationExposedModules
+ //
+ // This function is auto-generated
+ federationExposedModuleDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(federationExposedModuleTable).Where(ee...)
+ }
+
+ // federationExposedModuleDeleteQuery assembles delete query for removing federationExposedModules
+ //
+ // This function is auto-generated
+ federationExposedModuleTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(federationExposedModuleTable)
+ }
+
+ // federationExposedModulePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ federationExposedModulePrimaryKeys = func(res *federationType.ExposedModule) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // federationModuleMappingTable represents federationModuleMappings store table
+ //
+ // This value is auto-generated
+ federationModuleMappingTable = goqu.T("federation_module_mapping")
+
+ // federationModuleMappingSelectQuery assembles select query for fetching federationModuleMappings
+ //
+ // This function is auto-generated
+ federationModuleMappingSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "node_id",
+ "federation_module_id",
+ "compose_module_id",
+ "compose_namespace_id",
+ "field_mapping",
+ ).From(federationModuleMappingTable)
+ }
+
+ // federationModuleMappingInsertQuery assembles query inserting federationModuleMappings
+ //
+ // This function is auto-generated
+ federationModuleMappingInsertQuery = func(d goqu.DialectWrapper, res *federationType.ModuleMapping) *goqu.InsertDataset {
+ return d.Insert(federationModuleMappingTable).
+ Rows(goqu.Record{
+ "node_id": res.NodeID,
+ "federation_module_id": res.FederationModuleID,
+ "compose_module_id": res.ComposeModuleID,
+ "compose_namespace_id": res.ComposeNamespaceID,
+ "field_mapping": res.FieldMapping,
+ })
+ }
+
+ // federationModuleMappingUpsertQuery assembles (insert+on-conflict) query for replacing federationModuleMappings
+ //
+ // This function is auto-generated
+ federationModuleMappingUpsertQuery = func(d goqu.DialectWrapper, res *federationType.ModuleMapping) *goqu.InsertDataset {
+ var target = ``
+
+ return federationModuleMappingInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "node_id": res.NodeID,
+ "federation_module_id": res.FederationModuleID,
+ "compose_module_id": res.ComposeModuleID,
+ "compose_namespace_id": res.ComposeNamespaceID,
+ "field_mapping": res.FieldMapping,
+ },
+ ),
+ )
+ }
+
+ // federationModuleMappingUpdateQuery assembles query for updating federationModuleMappings
+ //
+ // This function is auto-generated
+ federationModuleMappingUpdateQuery = func(d goqu.DialectWrapper, res *federationType.ModuleMapping) *goqu.UpdateDataset {
+ return d.Update(federationModuleMappingTable).
+ Set(goqu.Record{
+ "node_id": res.NodeID,
+ "federation_module_id": res.FederationModuleID,
+ "compose_module_id": res.ComposeModuleID,
+ "compose_namespace_id": res.ComposeNamespaceID,
+ "field_mapping": res.FieldMapping,
+ }).
+ Where(federationModuleMappingPrimaryKeys(res))
+ }
+
+ // federationModuleMappingDeleteQuery assembles delete query for removing federationModuleMappings
+ //
+ // This function is auto-generated
+ federationModuleMappingDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(federationModuleMappingTable).Where(ee...)
+ }
+
+ // federationModuleMappingDeleteQuery assembles delete query for removing federationModuleMappings
+ //
+ // This function is auto-generated
+ federationModuleMappingTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(federationModuleMappingTable)
+ }
+
+ // federationModuleMappingPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ federationModuleMappingPrimaryKeys = func(res *federationType.ModuleMapping) goqu.Ex {
+ return goqu.Ex{}
+ }
+
+ // federationNodeTable represents federationNodes store table
+ //
+ // This value is auto-generated
+ federationNodeTable = goqu.T("federation_nodes")
+
+ // federationNodeSelectQuery assembles select query for fetching federationNodes
+ //
+ // This function is auto-generated
+ federationNodeSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "name",
+ "shared_node_id",
+ "base_url",
+ "status",
+ "contact",
+ "pair_token",
+ "auth_token",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(federationNodeTable)
+ }
+
+ // federationNodeInsertQuery assembles query inserting federationNodes
+ //
+ // This function is auto-generated
+ federationNodeInsertQuery = func(d goqu.DialectWrapper, res *federationType.Node) *goqu.InsertDataset {
+ return d.Insert(federationNodeTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "name": res.Name,
+ "shared_node_id": res.SharedNodeID,
+ "base_url": res.BaseURL,
+ "status": res.Status,
+ "contact": res.Contact,
+ "pair_token": res.PairToken,
+ "auth_token": res.AuthToken,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // federationNodeUpsertQuery assembles (insert+on-conflict) query for replacing federationNodes
+ //
+ // This function is auto-generated
+ federationNodeUpsertQuery = func(d goqu.DialectWrapper, res *federationType.Node) *goqu.InsertDataset {
+ var target = `,id`
+
+ return federationNodeInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "name": res.Name,
+ "shared_node_id": res.SharedNodeID,
+ "base_url": res.BaseURL,
+ "status": res.Status,
+ "contact": res.Contact,
+ "pair_token": res.PairToken,
+ "auth_token": res.AuthToken,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // federationNodeUpdateQuery assembles query for updating federationNodes
+ //
+ // This function is auto-generated
+ federationNodeUpdateQuery = func(d goqu.DialectWrapper, res *federationType.Node) *goqu.UpdateDataset {
+ return d.Update(federationNodeTable).
+ Set(goqu.Record{
+ "name": res.Name,
+ "shared_node_id": res.SharedNodeID,
+ "base_url": res.BaseURL,
+ "status": res.Status,
+ "contact": res.Contact,
+ "pair_token": res.PairToken,
+ "auth_token": res.AuthToken,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(federationNodePrimaryKeys(res))
+ }
+
+ // federationNodeDeleteQuery assembles delete query for removing federationNodes
+ //
+ // This function is auto-generated
+ federationNodeDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(federationNodeTable).Where(ee...)
+ }
+
+ // federationNodeDeleteQuery assembles delete query for removing federationNodes
+ //
+ // This function is auto-generated
+ federationNodeTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(federationNodeTable)
+ }
+
+ // federationNodePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ federationNodePrimaryKeys = func(res *federationType.Node) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // federationNodeSyncTable represents federationNodeSyncs store table
+ //
+ // This value is auto-generated
+ federationNodeSyncTable = goqu.T("federation_nodes_sync")
+
+ // federationNodeSyncSelectQuery assembles select query for fetching federationNodeSyncs
+ //
+ // This function is auto-generated
+ federationNodeSyncSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "node_id",
+ "module_id",
+ "sync_type",
+ "sync_status",
+ "time_of_action",
+ ).From(federationNodeSyncTable)
+ }
+
+ // federationNodeSyncInsertQuery assembles query inserting federationNodeSyncs
+ //
+ // This function is auto-generated
+ federationNodeSyncInsertQuery = func(d goqu.DialectWrapper, res *federationType.NodeSync) *goqu.InsertDataset {
+ return d.Insert(federationNodeSyncTable).
+ Rows(goqu.Record{
+ "node_id": res.NodeID,
+ "module_id": res.ModuleID,
+ "sync_type": res.SyncType,
+ "sync_status": res.SyncStatus,
+ "time_of_action": res.TimeOfAction,
+ })
+ }
+
+ // federationNodeSyncUpsertQuery assembles (insert+on-conflict) query for replacing federationNodeSyncs
+ //
+ // This function is auto-generated
+ federationNodeSyncUpsertQuery = func(d goqu.DialectWrapper, res *federationType.NodeSync) *goqu.InsertDataset {
+ var target = `,node_id`
+
+ return federationNodeSyncInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "module_id": res.ModuleID,
+ "sync_type": res.SyncType,
+ "sync_status": res.SyncStatus,
+ "time_of_action": res.TimeOfAction,
+ },
+ ),
+ )
+ }
+
+ // federationNodeSyncUpdateQuery assembles query for updating federationNodeSyncs
+ //
+ // This function is auto-generated
+ federationNodeSyncUpdateQuery = func(d goqu.DialectWrapper, res *federationType.NodeSync) *goqu.UpdateDataset {
+ return d.Update(federationNodeSyncTable).
+ Set(goqu.Record{
+ "module_id": res.ModuleID,
+ "sync_type": res.SyncType,
+ "sync_status": res.SyncStatus,
+ "time_of_action": res.TimeOfAction,
+ }).
+ Where(federationNodeSyncPrimaryKeys(res))
+ }
+
+ // federationNodeSyncDeleteQuery assembles delete query for removing federationNodeSyncs
+ //
+ // This function is auto-generated
+ federationNodeSyncDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(federationNodeSyncTable).Where(ee...)
+ }
+
+ // federationNodeSyncDeleteQuery assembles delete query for removing federationNodeSyncs
+ //
+ // This function is auto-generated
+ federationNodeSyncTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(federationNodeSyncTable)
+ }
+
+ // federationNodeSyncPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ federationNodeSyncPrimaryKeys = func(res *federationType.NodeSync) goqu.Ex {
+ return goqu.Ex{
+ "node_id": res.NodeID,
+ }
+ }
+
+ // federationSharedModuleTable represents federationSharedModules store table
+ //
+ // This value is auto-generated
+ federationSharedModuleTable = goqu.T("federation_shared_module")
+
+ // federationSharedModuleSelectQuery assembles select query for fetching federationSharedModules
+ //
+ // This function is auto-generated
+ federationSharedModuleSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "node_id",
+ "name",
+ "external_federation_module_id",
+ "fields",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(federationSharedModuleTable)
+ }
+
+ // federationSharedModuleInsertQuery assembles query inserting federationSharedModules
+ //
+ // This function is auto-generated
+ federationSharedModuleInsertQuery = func(d goqu.DialectWrapper, res *federationType.SharedModule) *goqu.InsertDataset {
+ return d.Insert(federationSharedModuleTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "node_id": res.NodeID,
+ "name": res.Name,
+ "external_federation_module_id": res.ExternalFederationModuleID,
+ "fields": res.Fields,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // federationSharedModuleUpsertQuery assembles (insert+on-conflict) query for replacing federationSharedModules
+ //
+ // This function is auto-generated
+ federationSharedModuleUpsertQuery = func(d goqu.DialectWrapper, res *federationType.SharedModule) *goqu.InsertDataset {
+ var target = `,id`
+
+ return federationSharedModuleInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "node_id": res.NodeID,
+ "name": res.Name,
+ "external_federation_module_id": res.ExternalFederationModuleID,
+ "fields": res.Fields,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // federationSharedModuleUpdateQuery assembles query for updating federationSharedModules
+ //
+ // This function is auto-generated
+ federationSharedModuleUpdateQuery = func(d goqu.DialectWrapper, res *federationType.SharedModule) *goqu.UpdateDataset {
+ return d.Update(federationSharedModuleTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "node_id": res.NodeID,
+ "name": res.Name,
+ "external_federation_module_id": res.ExternalFederationModuleID,
+ "fields": res.Fields,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(federationSharedModulePrimaryKeys(res))
+ }
+
+ // federationSharedModuleDeleteQuery assembles delete query for removing federationSharedModules
+ //
+ // This function is auto-generated
+ federationSharedModuleDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(federationSharedModuleTable).Where(ee...)
+ }
+
+ // federationSharedModuleDeleteQuery assembles delete query for removing federationSharedModules
+ //
+ // This function is auto-generated
+ federationSharedModuleTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(federationSharedModuleTable)
+ }
+
+ // federationSharedModulePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ federationSharedModulePrimaryKeys = func(res *federationType.SharedModule) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // flagTable represents flags store table
+ //
+ // This value is auto-generated
+ flagTable = goqu.T("flags")
+
+ // flagSelectQuery assembles select query for fetching flags
+ //
+ // This function is auto-generated
+ flagSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "kind",
+ "rel_resource",
+ "owned_by",
+ "name",
+ "active",
+ ).From(flagTable)
+ }
+
+ // flagInsertQuery assembles query inserting flags
+ //
+ // This function is auto-generated
+ flagInsertQuery = func(d goqu.DialectWrapper, res *flagType.Flag) *goqu.InsertDataset {
+ return d.Insert(flagTable).
+ Rows(goqu.Record{
+ "kind": res.Kind,
+ "rel_resource": res.ResourceID,
+ "owned_by": res.OwnedBy,
+ "name": res.Name,
+ "active": res.Active,
+ })
+ }
+
+ // flagUpsertQuery assembles (insert+on-conflict) query for replacing flags
+ //
+ // This function is auto-generated
+ flagUpsertQuery = func(d goqu.DialectWrapper, res *flagType.Flag) *goqu.InsertDataset {
+ var target = `,kind,rel_resource,owned_by,LOWER(name)`
+
+ return flagInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "active": res.Active,
+ },
+ ),
+ )
+ }
+
+ // flagUpdateQuery assembles query for updating flags
+ //
+ // This function is auto-generated
+ flagUpdateQuery = func(d goqu.DialectWrapper, res *flagType.Flag) *goqu.UpdateDataset {
+ return d.Update(flagTable).
+ Set(goqu.Record{
+ "active": res.Active,
+ }).
+ Where(flagPrimaryKeys(res))
+ }
+
+ // flagDeleteQuery assembles delete query for removing flags
+ //
+ // This function is auto-generated
+ flagDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(flagTable).Where(ee...)
+ }
+
+ // flagDeleteQuery assembles delete query for removing flags
+ //
+ // This function is auto-generated
+ flagTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(flagTable)
+ }
+
+ // flagPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ flagPrimaryKeys = func(res *flagType.Flag) goqu.Ex {
+ return goqu.Ex{
+ "kind": res.Kind,
+ "rel_resource": res.ResourceID,
+ "owned_by": res.OwnedBy,
+ "name": res.Name,
+ }
+ }
+
+ // labelTable represents labels store table
+ //
+ // This value is auto-generated
+ labelTable = goqu.T("labels")
+
+ // labelSelectQuery assembles select query for fetching labels
+ //
+ // This function is auto-generated
+ labelSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "kind",
+ "rel_resource",
+ "name",
+ "value",
+ ).From(labelTable)
+ }
+
+ // labelInsertQuery assembles query inserting labels
+ //
+ // This function is auto-generated
+ labelInsertQuery = func(d goqu.DialectWrapper, res *labelsType.Label) *goqu.InsertDataset {
+ return d.Insert(labelTable).
+ Rows(goqu.Record{
+ "kind": res.Kind,
+ "rel_resource": res.ResourceID,
+ "name": res.Name,
+ "value": res.Value,
+ })
+ }
+
+ // labelUpsertQuery assembles (insert+on-conflict) query for replacing labels
+ //
+ // This function is auto-generated
+ labelUpsertQuery = func(d goqu.DialectWrapper, res *labelsType.Label) *goqu.InsertDataset {
+ var target = `,kind,rel_resource,LOWER(name)`
+
+ return labelInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "value": res.Value,
+ },
+ ),
+ )
+ }
+
+ // labelUpdateQuery assembles query for updating labels
+ //
+ // This function is auto-generated
+ labelUpdateQuery = func(d goqu.DialectWrapper, res *labelsType.Label) *goqu.UpdateDataset {
+ return d.Update(labelTable).
+ Set(goqu.Record{
+ "value": res.Value,
+ }).
+ Where(labelPrimaryKeys(res))
+ }
+
+ // labelDeleteQuery assembles delete query for removing labels
+ //
+ // This function is auto-generated
+ labelDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(labelTable).Where(ee...)
+ }
+
+ // labelDeleteQuery assembles delete query for removing labels
+ //
+ // This function is auto-generated
+ labelTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(labelTable)
+ }
+
+ // labelPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ labelPrimaryKeys = func(res *labelsType.Label) goqu.Ex {
+ return goqu.Ex{
+ "kind": res.Kind,
+ "rel_resource": res.ResourceID,
+ "name": res.Name,
+ }
+ }
+
+ // queueTable represents queues store table
+ //
+ // This value is auto-generated
+ queueTable = goqu.T("queue_settings")
+
+ // queueSelectQuery assembles select query for fetching queues
+ //
+ // This function is auto-generated
+ queueSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "consumer",
+ "queue",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(queueTable)
+ }
+
+ // queueInsertQuery assembles query inserting queues
+ //
+ // This function is auto-generated
+ queueInsertQuery = func(d goqu.DialectWrapper, res *systemType.Queue) *goqu.InsertDataset {
+ return d.Insert(queueTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "consumer": res.Consumer,
+ "queue": res.Queue,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // queueUpsertQuery assembles (insert+on-conflict) query for replacing queues
+ //
+ // This function is auto-generated
+ queueUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Queue) *goqu.InsertDataset {
+ var target = `,id`
+
+ return queueInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "consumer": res.Consumer,
+ "queue": res.Queue,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // queueUpdateQuery assembles query for updating queues
+ //
+ // This function is auto-generated
+ queueUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Queue) *goqu.UpdateDataset {
+ return d.Update(queueTable).
+ Set(goqu.Record{
+ "consumer": res.Consumer,
+ "queue": res.Queue,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(queuePrimaryKeys(res))
+ }
+
+ // queueDeleteQuery assembles delete query for removing queues
+ //
+ // This function is auto-generated
+ queueDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(queueTable).Where(ee...)
+ }
+
+ // queueDeleteQuery assembles delete query for removing queues
+ //
+ // This function is auto-generated
+ queueTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(queueTable)
+ }
+
+ // queuePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ queuePrimaryKeys = func(res *systemType.Queue) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // queueMessageTable represents queueMessages store table
+ //
+ // This value is auto-generated
+ queueMessageTable = goqu.T("queue_messages")
+
+ // queueMessageSelectQuery assembles select query for fetching queueMessages
+ //
+ // This function is auto-generated
+ queueMessageSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "queue",
+ "payload",
+ "processed",
+ "created",
+ ).From(queueMessageTable)
+ }
+
+ // queueMessageInsertQuery assembles query inserting queueMessages
+ //
+ // This function is auto-generated
+ queueMessageInsertQuery = func(d goqu.DialectWrapper, res *systemType.QueueMessage) *goqu.InsertDataset {
+ return d.Insert(queueMessageTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "queue": res.Queue,
+ "payload": res.Payload,
+ "processed": res.Processed,
+ "created": res.Created,
+ })
+ }
+
+ // queueMessageUpsertQuery assembles (insert+on-conflict) query for replacing queueMessages
+ //
+ // This function is auto-generated
+ queueMessageUpsertQuery = func(d goqu.DialectWrapper, res *systemType.QueueMessage) *goqu.InsertDataset {
+ var target = `,id`
+
+ return queueMessageInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "queue": res.Queue,
+ "payload": res.Payload,
+ "processed": res.Processed,
+ "created": res.Created,
+ },
+ ),
+ )
+ }
+
+ // queueMessageUpdateQuery assembles query for updating queueMessages
+ //
+ // This function is auto-generated
+ queueMessageUpdateQuery = func(d goqu.DialectWrapper, res *systemType.QueueMessage) *goqu.UpdateDataset {
+ return d.Update(queueMessageTable).
+ Set(goqu.Record{
+ "queue": res.Queue,
+ "payload": res.Payload,
+ "processed": res.Processed,
+ "created": res.Created,
+ }).
+ Where(queueMessagePrimaryKeys(res))
+ }
+
+ // queueMessageDeleteQuery assembles delete query for removing queueMessages
+ //
+ // This function is auto-generated
+ queueMessageDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(queueMessageTable).Where(ee...)
+ }
+
+ // queueMessageDeleteQuery assembles delete query for removing queueMessages
+ //
+ // This function is auto-generated
+ queueMessageTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(queueMessageTable)
+ }
+
+ // queueMessagePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ queueMessagePrimaryKeys = func(res *systemType.QueueMessage) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // rbacRuleTable represents rbacRules store table
+ //
+ // This value is auto-generated
+ rbacRuleTable = goqu.T("rbac_rules")
+
+ // rbacRuleSelectQuery assembles select query for fetching rbacRules
+ //
+ // This function is auto-generated
+ rbacRuleSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "rel_role",
+ "resource",
+ "operation",
+ "access",
+ ).From(rbacRuleTable)
+ }
+
+ // rbacRuleInsertQuery assembles query inserting rbacRules
+ //
+ // This function is auto-generated
+ rbacRuleInsertQuery = func(d goqu.DialectWrapper, res *rbacType.Rule) *goqu.InsertDataset {
+ return d.Insert(rbacRuleTable).
+ Rows(goqu.Record{
+ "rel_role": res.RoleID,
+ "resource": res.Resource,
+ "operation": res.Operation,
+ "access": res.Access,
+ })
+ }
+
+ // rbacRuleUpsertQuery assembles (insert+on-conflict) query for replacing rbacRules
+ //
+ // This function is auto-generated
+ rbacRuleUpsertQuery = func(d goqu.DialectWrapper, res *rbacType.Rule) *goqu.InsertDataset {
+ var target = `,rel_role,resource,operation`
+
+ return rbacRuleInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "access": res.Access,
+ },
+ ),
+ )
+ }
+
+ // rbacRuleUpdateQuery assembles query for updating rbacRules
+ //
+ // This function is auto-generated
+ rbacRuleUpdateQuery = func(d goqu.DialectWrapper, res *rbacType.Rule) *goqu.UpdateDataset {
+ return d.Update(rbacRuleTable).
+ Set(goqu.Record{
+ "access": res.Access,
+ }).
+ Where(rbacRulePrimaryKeys(res))
+ }
+
+ // rbacRuleDeleteQuery assembles delete query for removing rbacRules
+ //
+ // This function is auto-generated
+ rbacRuleDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(rbacRuleTable).Where(ee...)
+ }
+
+ // rbacRuleDeleteQuery assembles delete query for removing rbacRules
+ //
+ // This function is auto-generated
+ rbacRuleTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(rbacRuleTable)
+ }
+
+ // rbacRulePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ rbacRulePrimaryKeys = func(res *rbacType.Rule) goqu.Ex {
+ return goqu.Ex{
+ "rel_role": res.RoleID,
+ "resource": res.Resource,
+ "operation": res.Operation,
+ }
+ }
+
+ // reminderTable represents reminders store table
+ //
+ // This value is auto-generated
+ reminderTable = goqu.T("reminders")
+
+ // reminderSelectQuery assembles select query for fetching reminders
+ //
+ // This function is auto-generated
+ reminderSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "resource",
+ "payload",
+ "snooze_count",
+ "assigned_to",
+ "assigned_by",
+ "assigned_at",
+ "dismissed_by",
+ "dismissed_at",
+ "remind_at",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ ).From(reminderTable)
+ }
+
+ // reminderInsertQuery assembles query inserting reminders
+ //
+ // This function is auto-generated
+ reminderInsertQuery = func(d goqu.DialectWrapper, res *systemType.Reminder) *goqu.InsertDataset {
+ return d.Insert(reminderTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "resource": res.Resource,
+ "payload": res.Payload,
+ "snooze_count": res.SnoozeCount,
+ "assigned_to": res.AssignedTo,
+ "assigned_by": res.AssignedBy,
+ "assigned_at": res.AssignedAt,
+ "dismissed_by": res.DismissedBy,
+ "dismissed_at": res.DismissedAt,
+ "remind_at": res.RemindAt,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ })
+ }
+
+ // reminderUpsertQuery assembles (insert+on-conflict) query for replacing reminders
+ //
+ // This function is auto-generated
+ reminderUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Reminder) *goqu.InsertDataset {
+ var target = `,id`
+
+ return reminderInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "resource": res.Resource,
+ "payload": res.Payload,
+ "snooze_count": res.SnoozeCount,
+ "assigned_to": res.AssignedTo,
+ "assigned_by": res.AssignedBy,
+ "assigned_at": res.AssignedAt,
+ "dismissed_by": res.DismissedBy,
+ "dismissed_at": res.DismissedAt,
+ "remind_at": res.RemindAt,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ },
+ ),
+ )
+ }
+
+ // reminderUpdateQuery assembles query for updating reminders
+ //
+ // This function is auto-generated
+ reminderUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Reminder) *goqu.UpdateDataset {
+ return d.Update(reminderTable).
+ Set(goqu.Record{
+ "resource": res.Resource,
+ "payload": res.Payload,
+ "snooze_count": res.SnoozeCount,
+ "assigned_to": res.AssignedTo,
+ "assigned_by": res.AssignedBy,
+ "assigned_at": res.AssignedAt,
+ "dismissed_by": res.DismissedBy,
+ "dismissed_at": res.DismissedAt,
+ "remind_at": res.RemindAt,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ }).
+ Where(reminderPrimaryKeys(res))
+ }
+
+ // reminderDeleteQuery assembles delete query for removing reminders
+ //
+ // This function is auto-generated
+ reminderDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(reminderTable).Where(ee...)
+ }
+
+ // reminderDeleteQuery assembles delete query for removing reminders
+ //
+ // This function is auto-generated
+ reminderTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(reminderTable)
+ }
+
+ // reminderPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ reminderPrimaryKeys = func(res *systemType.Reminder) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // reportTable represents reports store table
+ //
+ // This value is auto-generated
+ reportTable = goqu.T("reports")
+
+ // reportSelectQuery assembles select query for fetching reports
+ //
+ // This function is auto-generated
+ reportSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "meta",
+ "scenarios",
+ "sources",
+ "blocks",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "owned_by",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(reportTable)
+ }
+
+ // reportInsertQuery assembles query inserting reports
+ //
+ // This function is auto-generated
+ reportInsertQuery = func(d goqu.DialectWrapper, res *systemType.Report) *goqu.InsertDataset {
+ return d.Insert(reportTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "scenarios": res.Scenarios,
+ "sources": res.Sources,
+ "blocks": res.Blocks,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // reportUpsertQuery assembles (insert+on-conflict) query for replacing reports
+ //
+ // This function is auto-generated
+ reportUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Report) *goqu.InsertDataset {
+ var target = `,id`
+
+ return reportInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "scenarios": res.Scenarios,
+ "sources": res.Sources,
+ "blocks": res.Blocks,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // reportUpdateQuery assembles query for updating reports
+ //
+ // This function is auto-generated
+ reportUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Report) *goqu.UpdateDataset {
+ return d.Update(reportTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "scenarios": res.Scenarios,
+ "sources": res.Sources,
+ "blocks": res.Blocks,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(reportPrimaryKeys(res))
+ }
+
+ // reportDeleteQuery assembles delete query for removing reports
+ //
+ // This function is auto-generated
+ reportDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(reportTable).Where(ee...)
+ }
+
+ // reportDeleteQuery assembles delete query for removing reports
+ //
+ // This function is auto-generated
+ reportTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(reportTable)
+ }
+
+ // reportPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ reportPrimaryKeys = func(res *systemType.Report) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // resourceActivityTable represents resourceActivitys store table
+ //
+ // This value is auto-generated
+ resourceActivityTable = goqu.T("resource_activity_log")
+
+ // resourceActivitySelectQuery assembles select query for fetching resourceActivitys
+ //
+ // This function is auto-generated
+ resourceActivitySelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "ts",
+ "resource_type",
+ "resource_action",
+ "rel_resource",
+ "meta",
+ ).From(resourceActivityTable)
+ }
+
+ // resourceActivityInsertQuery assembles query inserting resourceActivitys
+ //
+ // This function is auto-generated
+ resourceActivityInsertQuery = func(d goqu.DialectWrapper, res *discoveryType.ResourceActivity) *goqu.InsertDataset {
+ return d.Insert(resourceActivityTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "ts": res.Timestamp,
+ "resource_type": res.ResourceType,
+ "resource_action": res.ResourceAction,
+ "rel_resource": res.ResourceID,
+ "meta": res.Meta,
+ })
+ }
+
+ // resourceActivityUpsertQuery assembles (insert+on-conflict) query for replacing resourceActivitys
+ //
+ // This function is auto-generated
+ resourceActivityUpsertQuery = func(d goqu.DialectWrapper, res *discoveryType.ResourceActivity) *goqu.InsertDataset {
+ var target = `,id`
+
+ return resourceActivityInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "ts": res.Timestamp,
+ "resource_type": res.ResourceType,
+ "resource_action": res.ResourceAction,
+ "rel_resource": res.ResourceID,
+ "meta": res.Meta,
+ },
+ ),
+ )
+ }
+
+ // resourceActivityUpdateQuery assembles query for updating resourceActivitys
+ //
+ // This function is auto-generated
+ resourceActivityUpdateQuery = func(d goqu.DialectWrapper, res *discoveryType.ResourceActivity) *goqu.UpdateDataset {
+ return d.Update(resourceActivityTable).
+ Set(goqu.Record{
+ "ts": res.Timestamp,
+ "resource_type": res.ResourceType,
+ "resource_action": res.ResourceAction,
+ "rel_resource": res.ResourceID,
+ "meta": res.Meta,
+ }).
+ Where(resourceActivityPrimaryKeys(res))
+ }
+
+ // resourceActivityDeleteQuery assembles delete query for removing resourceActivitys
+ //
+ // This function is auto-generated
+ resourceActivityDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(resourceActivityTable).Where(ee...)
+ }
+
+ // resourceActivityDeleteQuery assembles delete query for removing resourceActivitys
+ //
+ // This function is auto-generated
+ resourceActivityTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(resourceActivityTable)
+ }
+
+ // resourceActivityPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ resourceActivityPrimaryKeys = func(res *discoveryType.ResourceActivity) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // resourceTranslationTable represents resourceTranslations store table
+ //
+ // This value is auto-generated
+ resourceTranslationTable = goqu.T("resource_translations")
+
+ // resourceTranslationSelectQuery assembles select query for fetching resourceTranslations
+ //
+ // This function is auto-generated
+ resourceTranslationSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "lang",
+ "resource",
+ "k",
+ "message",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "owned_by",
+ "created_by",
+ "updated_by",
+ "deleted_by",
+ ).From(resourceTranslationTable)
+ }
+
+ // resourceTranslationInsertQuery assembles query inserting resourceTranslations
+ //
+ // This function is auto-generated
+ resourceTranslationInsertQuery = func(d goqu.DialectWrapper, res *systemType.ResourceTranslation) *goqu.InsertDataset {
+ return d.Insert(resourceTranslationTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "lang": res.Lang,
+ "resource": res.Resource,
+ "k": res.K,
+ "message": res.Message,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ })
+ }
+
+ // resourceTranslationUpsertQuery assembles (insert+on-conflict) query for replacing resourceTranslations
+ //
+ // This function is auto-generated
+ resourceTranslationUpsertQuery = func(d goqu.DialectWrapper, res *systemType.ResourceTranslation) *goqu.InsertDataset {
+ var target = `,id`
+
+ return resourceTranslationInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "lang": res.Lang,
+ "resource": res.Resource,
+ "k": res.K,
+ "message": res.Message,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ },
+ ),
+ )
+ }
+
+ // resourceTranslationUpdateQuery assembles query for updating resourceTranslations
+ //
+ // This function is auto-generated
+ resourceTranslationUpdateQuery = func(d goqu.DialectWrapper, res *systemType.ResourceTranslation) *goqu.UpdateDataset {
+ return d.Update(resourceTranslationTable).
+ Set(goqu.Record{
+ "lang": res.Lang,
+ "resource": res.Resource,
+ "k": res.K,
+ "message": res.Message,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "owned_by": res.OwnedBy,
+ "created_by": res.CreatedBy,
+ "updated_by": res.UpdatedBy,
+ "deleted_by": res.DeletedBy,
+ }).
+ Where(resourceTranslationPrimaryKeys(res))
+ }
+
+ // resourceTranslationDeleteQuery assembles delete query for removing resourceTranslations
+ //
+ // This function is auto-generated
+ resourceTranslationDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(resourceTranslationTable).Where(ee...)
+ }
+
+ // resourceTranslationDeleteQuery assembles delete query for removing resourceTranslations
+ //
+ // This function is auto-generated
+ resourceTranslationTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(resourceTranslationTable)
+ }
+
+ // resourceTranslationPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ resourceTranslationPrimaryKeys = func(res *systemType.ResourceTranslation) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // roleTable represents roles store table
+ //
+ // This value is auto-generated
+ roleTable = goqu.T("roles")
+
+ // roleSelectQuery assembles select query for fetching roles
+ //
+ // This function is auto-generated
+ roleSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "name",
+ "handle",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "archived_at",
+ ).From(roleTable)
+ }
+
+ // roleInsertQuery assembles query inserting roles
+ //
+ // This function is auto-generated
+ roleInsertQuery = func(d goqu.DialectWrapper, res *systemType.Role) *goqu.InsertDataset {
+ return d.Insert(roleTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "name": res.Name,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "archived_at": res.ArchivedAt,
+ })
+ }
+
+ // roleUpsertQuery assembles (insert+on-conflict) query for replacing roles
+ //
+ // This function is auto-generated
+ roleUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Role) *goqu.InsertDataset {
+ var target = `,id`
+
+ return roleInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "name": res.Name,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "archived_at": res.ArchivedAt,
+ },
+ ),
+ )
+ }
+
+ // roleUpdateQuery assembles query for updating roles
+ //
+ // This function is auto-generated
+ roleUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Role) *goqu.UpdateDataset {
+ return d.Update(roleTable).
+ Set(goqu.Record{
+ "name": res.Name,
+ "handle": res.Handle,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "archived_at": res.ArchivedAt,
+ }).
+ Where(rolePrimaryKeys(res))
+ }
+
+ // roleDeleteQuery assembles delete query for removing roles
+ //
+ // This function is auto-generated
+ roleDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(roleTable).Where(ee...)
+ }
+
+ // roleDeleteQuery assembles delete query for removing roles
+ //
+ // This function is auto-generated
+ roleTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(roleTable)
+ }
+
+ // rolePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ rolePrimaryKeys = func(res *systemType.Role) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // roleMemberTable represents roleMembers store table
+ //
+ // This value is auto-generated
+ roleMemberTable = goqu.T("role_members")
+
+ // roleMemberSelectQuery assembles select query for fetching roleMembers
+ //
+ // This function is auto-generated
+ roleMemberSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "rel_user",
+ "rel_role",
+ ).From(roleMemberTable)
+ }
+
+ // roleMemberInsertQuery assembles query inserting roleMembers
+ //
+ // This function is auto-generated
+ roleMemberInsertQuery = func(d goqu.DialectWrapper, res *systemType.RoleMember) *goqu.InsertDataset {
+ return d.Insert(roleMemberTable).
+ Rows(goqu.Record{
+ "rel_user": res.UserID,
+ "rel_role": res.RoleID,
+ })
+ }
+
+ // roleMemberUpsertQuery assembles (insert+on-conflict) query for replacing roleMembers
+ //
+ // This function is auto-generated
+ roleMemberUpsertQuery = func(d goqu.DialectWrapper, res *systemType.RoleMember) *goqu.InsertDataset {
+ var target = `,rel_user,rel_role`
+
+ return roleMemberInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{},
+ ),
+ )
+ }
+
+ // roleMemberUpdateQuery assembles query for updating roleMembers
+ //
+ // This function is auto-generated
+ roleMemberUpdateQuery = func(d goqu.DialectWrapper, res *systemType.RoleMember) *goqu.UpdateDataset {
+ return d.Update(roleMemberTable).
+ Set(goqu.Record{}).
+ Where(roleMemberPrimaryKeys(res))
+ }
+
+ // roleMemberDeleteQuery assembles delete query for removing roleMembers
+ //
+ // This function is auto-generated
+ roleMemberDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(roleMemberTable).Where(ee...)
+ }
+
+ // roleMemberDeleteQuery assembles delete query for removing roleMembers
+ //
+ // This function is auto-generated
+ roleMemberTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(roleMemberTable)
+ }
+
+ // roleMemberPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ roleMemberPrimaryKeys = func(res *systemType.RoleMember) goqu.Ex {
+ return goqu.Ex{
+ "rel_user": res.UserID,
+ "rel_role": res.RoleID,
+ }
+ }
+
+ // settingValueTable represents settingValues store table
+ //
+ // This value is auto-generated
+ settingValueTable = goqu.T("settings")
+
+ // settingValueSelectQuery assembles select query for fetching settingValues
+ //
+ // This function is auto-generated
+ settingValueSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "name",
+ "rel_owner",
+ "value",
+ "updated_by",
+ "updated_at",
+ ).From(settingValueTable)
+ }
+
+ // settingValueInsertQuery assembles query inserting settingValues
+ //
+ // This function is auto-generated
+ settingValueInsertQuery = func(d goqu.DialectWrapper, res *systemType.SettingValue) *goqu.InsertDataset {
+ return d.Insert(settingValueTable).
+ Rows(goqu.Record{
+ "name": res.Name,
+ "rel_owner": res.OwnedBy,
+ "value": res.Value,
+ "updated_by": res.UpdatedBy,
+ "updated_at": res.UpdatedAt,
+ })
+ }
+
+ // settingValueUpsertQuery assembles (insert+on-conflict) query for replacing settingValues
+ //
+ // This function is auto-generated
+ settingValueUpsertQuery = func(d goqu.DialectWrapper, res *systemType.SettingValue) *goqu.InsertDataset {
+ var target = `,LOWER(name),rel_owner`
+
+ return settingValueInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "value": res.Value,
+ "updated_by": res.UpdatedBy,
+ "updated_at": res.UpdatedAt,
+ },
+ ),
+ )
+ }
+
+ // settingValueUpdateQuery assembles query for updating settingValues
+ //
+ // This function is auto-generated
+ settingValueUpdateQuery = func(d goqu.DialectWrapper, res *systemType.SettingValue) *goqu.UpdateDataset {
+ return d.Update(settingValueTable).
+ Set(goqu.Record{
+ "value": res.Value,
+ "updated_by": res.UpdatedBy,
+ "updated_at": res.UpdatedAt,
+ }).
+ Where(settingValuePrimaryKeys(res))
+ }
+
+ // settingValueDeleteQuery assembles delete query for removing settingValues
+ //
+ // This function is auto-generated
+ settingValueDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(settingValueTable).Where(ee...)
+ }
+
+ // settingValueDeleteQuery assembles delete query for removing settingValues
+ //
+ // This function is auto-generated
+ settingValueTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(settingValueTable)
+ }
+
+ // settingValuePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ settingValuePrimaryKeys = func(res *systemType.SettingValue) goqu.Ex {
+ return goqu.Ex{
+ "name": res.Name,
+ "rel_owner": res.OwnedBy,
+ }
+ }
+
+ // templateTable represents templates store table
+ //
+ // This value is auto-generated
+ templateTable = goqu.T("templates")
+
+ // templateSelectQuery assembles select query for fetching templates
+ //
+ // This function is auto-generated
+ templateSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "language",
+ "type",
+ "partial",
+ "meta",
+ "template",
+ "rel_owner",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "last_used_at",
+ ).From(templateTable)
+ }
+
+ // templateInsertQuery assembles query inserting templates
+ //
+ // This function is auto-generated
+ templateInsertQuery = func(d goqu.DialectWrapper, res *systemType.Template) *goqu.InsertDataset {
+ return d.Insert(templateTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "language": res.Language,
+ "type": res.Type,
+ "partial": res.Partial,
+ "meta": res.Meta,
+ "template": res.Template,
+ "rel_owner": res.OwnerID,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "last_used_at": res.LastUsedAt,
+ })
+ }
+
+ // templateUpsertQuery assembles (insert+on-conflict) query for replacing templates
+ //
+ // This function is auto-generated
+ templateUpsertQuery = func(d goqu.DialectWrapper, res *systemType.Template) *goqu.InsertDataset {
+ var target = `,id`
+
+ return templateInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "language": res.Language,
+ "type": res.Type,
+ "partial": res.Partial,
+ "meta": res.Meta,
+ "template": res.Template,
+ "rel_owner": res.OwnerID,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "last_used_at": res.LastUsedAt,
+ },
+ ),
+ )
+ }
+
+ // templateUpdateQuery assembles query for updating templates
+ //
+ // This function is auto-generated
+ templateUpdateQuery = func(d goqu.DialectWrapper, res *systemType.Template) *goqu.UpdateDataset {
+ return d.Update(templateTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "language": res.Language,
+ "type": res.Type,
+ "partial": res.Partial,
+ "meta": res.Meta,
+ "template": res.Template,
+ "rel_owner": res.OwnerID,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "last_used_at": res.LastUsedAt,
+ }).
+ Where(templatePrimaryKeys(res))
+ }
+
+ // templateDeleteQuery assembles delete query for removing templates
+ //
+ // This function is auto-generated
+ templateDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(templateTable).Where(ee...)
+ }
+
+ // templateDeleteQuery assembles delete query for removing templates
+ //
+ // This function is auto-generated
+ templateTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(templateTable)
+ }
+
+ // templatePrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ templatePrimaryKeys = func(res *systemType.Template) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+
+ // userTable represents users store table
+ //
+ // This value is auto-generated
+ userTable = goqu.T("users")
+
+ // userSelectQuery assembles select query for fetching users
+ //
+ // This function is auto-generated
+ userSelectQuery = func(d goqu.DialectWrapper) *goqu.SelectDataset {
+ return d.Select(
+ "id",
+ "handle",
+ "email",
+ "email_confirmed",
+ "username",
+ "name",
+ "kind",
+ "meta",
+ "created_at",
+ "updated_at",
+ "deleted_at",
+ "suspended_at",
+ ).From(userTable)
+ }
+
+ // userInsertQuery assembles query inserting users
+ //
+ // This function is auto-generated
+ userInsertQuery = func(d goqu.DialectWrapper, res *systemType.User) *goqu.InsertDataset {
+ return d.Insert(userTable).
+ Rows(goqu.Record{
+ "id": res.ID,
+ "handle": res.Handle,
+ "email": res.Email,
+ "email_confirmed": res.EmailConfirmed,
+ "username": res.Username,
+ "name": res.Name,
+ "kind": res.Kind,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "suspended_at": res.SuspendedAt,
+ })
+ }
+
+ // userUpsertQuery assembles (insert+on-conflict) query for replacing users
+ //
+ // This function is auto-generated
+ userUpsertQuery = func(d goqu.DialectWrapper, res *systemType.User) *goqu.InsertDataset {
+ var target = `,id`
+
+ return userInsertQuery(d, res).
+ OnConflict(
+ goqu.DoUpdate(target[1:],
+ goqu.Record{
+ "handle": res.Handle,
+ "email": res.Email,
+ "email_confirmed": res.EmailConfirmed,
+ "username": res.Username,
+ "name": res.Name,
+ "kind": res.Kind,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "suspended_at": res.SuspendedAt,
+ },
+ ),
+ )
+ }
+
+ // userUpdateQuery assembles query for updating users
+ //
+ // This function is auto-generated
+ userUpdateQuery = func(d goqu.DialectWrapper, res *systemType.User) *goqu.UpdateDataset {
+ return d.Update(userTable).
+ Set(goqu.Record{
+ "handle": res.Handle,
+ "email": res.Email,
+ "email_confirmed": res.EmailConfirmed,
+ "username": res.Username,
+ "name": res.Name,
+ "kind": res.Kind,
+ "meta": res.Meta,
+ "created_at": res.CreatedAt,
+ "updated_at": res.UpdatedAt,
+ "deleted_at": res.DeletedAt,
+ "suspended_at": res.SuspendedAt,
+ }).
+ Where(userPrimaryKeys(res))
+ }
+
+ // userDeleteQuery assembles delete query for removing users
+ //
+ // This function is auto-generated
+ userDeleteQuery = func(d goqu.DialectWrapper, ee ...goqu.Expression) *goqu.DeleteDataset {
+ return d.Delete(userTable).Where(ee...)
+ }
+
+ // userDeleteQuery assembles delete query for removing users
+ //
+ // This function is auto-generated
+ userTruncateQuery = func(d goqu.DialectWrapper) *goqu.TruncateDataset {
+ return d.Truncate(userTable)
+ }
+
+ // userPrimaryKeys assembles set of conditions for all primary keys
+ //
+ // This function is auto-generated
+ userPrimaryKeys = func(res *systemType.User) goqu.Ex {
+ return goqu.Ex{
+ "id": res.ID,
+ }
+ }
+)
diff --git a/store/adapters/rdbms/rdbms.gen.go b/store/adapters/rdbms/rdbms.gen.go
new file mode 100644
index 000000000..48e8c6490
--- /dev/null
+++ b/store/adapters/rdbms/rdbms.gen.go
@@ -0,0 +1,17905 @@
+package rdbms
+
+// This file is auto-generated.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "strings"
+
+ automationType "github.com/cortezaproject/corteza-server/automation/types"
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ federationType "github.com/cortezaproject/corteza-server/federation/types"
+ actionlogType "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ discoveryType "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ "github.com/cortezaproject/corteza-server/pkg/errors"
+ "github.com/cortezaproject/corteza-server/pkg/filter"
+ flagType "github.com/cortezaproject/corteza-server/pkg/flag/types"
+ labelsType "github.com/cortezaproject/corteza-server/pkg/label/types"
+ rbacType "github.com/cortezaproject/corteza-server/pkg/rbac"
+ "github.com/cortezaproject/corteza-server/store"
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
+)
+
+var (
+ _ store.Actionlogs = &Store{}
+ _ store.ApigwFilters = &Store{}
+ _ store.ApigwRoutes = &Store{}
+ _ store.Applications = &Store{}
+ _ store.Attachments = &Store{}
+ _ store.AuthClients = &Store{}
+ _ store.AuthConfirmedClients = &Store{}
+ _ store.AuthOa2tokens = &Store{}
+ _ store.AuthSessions = &Store{}
+ _ store.AutomationSessions = &Store{}
+ _ store.AutomationTriggers = &Store{}
+ _ store.AutomationWorkflows = &Store{}
+ _ store.ComposeAttachments = &Store{}
+ _ store.ComposeCharts = &Store{}
+ _ store.ComposeModules = &Store{}
+ _ store.ComposeModuleFields = &Store{}
+ _ store.ComposeNamespaces = &Store{}
+ _ store.ComposePages = &Store{}
+ _ store.ComposeRecords = &Store{}
+ _ store.ComposeRecordValues = &Store{}
+ _ store.Credentials = &Store{}
+ _ store.FederationExposedModules = &Store{}
+ _ store.FederationModuleMappings = &Store{}
+ _ store.FederationNodes = &Store{}
+ _ store.FederationNodeSyncs = &Store{}
+ _ store.FederationSharedModules = &Store{}
+ _ store.Flags = &Store{}
+ _ store.Labels = &Store{}
+ _ store.Queues = &Store{}
+ _ store.QueueMessages = &Store{}
+ _ store.RbacRules = &Store{}
+ _ store.Reminders = &Store{}
+ _ store.Reports = &Store{}
+ _ store.ResourceActivitys = &Store{}
+ _ store.ResourceTranslations = &Store{}
+ _ store.Roles = &Store{}
+ _ store.RoleMembers = &Store{}
+ _ store.SettingValues = &Store{}
+ _ store.Templates = &Store{}
+ _ store.Users = &Store{}
+)
+
+// CreateActionlog creates one or more rows in actionlog collection
+//
+// This function is auto-generated
+func (s Store) CreateActionlog(ctx context.Context, rr ...*actionlogType.Action) (err error) {
+ for i := range rr {
+ if err = s.checkActionlogConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, actionlogInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateActionlog updates one or more existing entries in actionlog collection
+//
+// This function is auto-generated
+func (s Store) UpdateActionlog(ctx context.Context, rr ...*actionlogType.Action) (err error) {
+ for i := range rr {
+ if err = s.checkActionlogConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, actionlogUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertActionlog updates one or more existing entries in actionlog collection
+//
+// This function is auto-generated
+func (s Store) UpsertActionlog(ctx context.Context, rr ...*actionlogType.Action) (err error) {
+ for i := range rr {
+ if err = s.checkActionlogConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, actionlogUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteActionlog Deletes one or more entries from actionlog collection
+//
+// This function is auto-generated
+func (s Store) DeleteActionlog(ctx context.Context, rr ...*actionlogType.Action) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, actionlogDeleteQuery(s.config.Dialect, actionlogPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteActionlogByID deletes single entry from actionlog collection
+//
+// This function is auto-generated
+func (s Store) DeleteActionlogByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, actionlogDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateActionlogs Deletes all rows from the actionlog collection
+func (s Store) TruncateActionlogs(ctx context.Context) error {
+ return s.Exec(ctx, actionlogTruncateQuery(s.config.Dialect))
+}
+
+// SearchActionlogs returns (filtered) set of Actionlogs
+//
+// This function is auto-generated
+func (s Store) SearchActionlogs(ctx context.Context, f actionlogType.Filter) (set actionlogType.ActionSet, _ actionlogType.Filter, err error) {
+
+ set, _, err = s.QueryActionlogs(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryActionlogs queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryActionlogs(
+ ctx context.Context,
+ f actionlogType.Filter,
+) (_ []*actionlogType.Action, more bool, err error) {
+ var (
+ set = make([]*actionlogType.Action, 0, DefaultSliceCapacity)
+ res *actionlogType.Action
+ aux auxActionlog
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Actionlog != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Actionlog(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ActionlogFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Actionlog: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := actionlogSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableActionlogFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Actionlog: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Actionlog: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Actionlog: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Actionlog: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Actionlog: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Actionlog: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupActionlogByID searches for action log by ID
+//
+// This function is auto-generated
+func (s Store) LookupActionlogByID(ctx context.Context, id uint64) (_ *actionlogType.Action, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxActionlog)
+ lookup = actionlogSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableActionlogFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableActionlogFields() map[string]string {
+ return map[string]string{
+ "id": "id",
+ "timestamp": "timestamp",
+ }
+}
+
+// collectActionlogCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectActionlogCursorValues(res *actionlogType.Action, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "timestamp":
+ cur.Set(c.Column, res.Timestamp, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkActionlogConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkActionlogConstraints(ctx context.Context, res *actionlogType.Action) (err error) {
+ return nil
+}
+
+// CreateApigwFilter creates one or more rows in apigwFilter collection
+//
+// This function is auto-generated
+func (s Store) CreateApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) (err error) {
+ for i := range rr {
+ if err = s.checkApigwFilterConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, apigwFilterInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateApigwFilter updates one or more existing entries in apigwFilter collection
+//
+// This function is auto-generated
+func (s Store) UpdateApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) (err error) {
+ for i := range rr {
+ if err = s.checkApigwFilterConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, apigwFilterUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertApigwFilter updates one or more existing entries in apigwFilter collection
+//
+// This function is auto-generated
+func (s Store) UpsertApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) (err error) {
+ for i := range rr {
+ if err = s.checkApigwFilterConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, apigwFilterUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteApigwFilter Deletes one or more entries from apigwFilter collection
+//
+// This function is auto-generated
+func (s Store) DeleteApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, apigwFilterDeleteQuery(s.config.Dialect, apigwFilterPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteApigwFilterByID deletes single entry from apigwFilter collection
+//
+// This function is auto-generated
+func (s Store) DeleteApigwFilterByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, apigwFilterDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateApigwFilters Deletes all rows from the apigwFilter collection
+func (s Store) TruncateApigwFilters(ctx context.Context) error {
+ return s.Exec(ctx, apigwFilterTruncateQuery(s.config.Dialect))
+}
+
+// SearchApigwFilters returns (filtered) set of ApigwFilters
+//
+// This function is auto-generated
+func (s Store) SearchApigwFilters(ctx context.Context, f systemType.ApigwFilterFilter) (set systemType.ApigwFilterSet, _ systemType.ApigwFilterFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfApigwFilters fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfApigwFilters(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfApigwFilters collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfApigwFilters(
+ ctx context.Context,
+ filter systemType.ApigwFilterFilter,
+) (set []*systemType.ApigwFilter, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.ApigwFilter
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.ApigwFilterFilter
+ )
+
+ set = make([]*systemType.ApigwFilter, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryApigwFilters(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectApigwFilterCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectApigwFilterCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectApigwFilterCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryApigwFilters queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryApigwFilters(
+ ctx context.Context,
+ f systemType.ApigwFilterFilter,
+) (_ []*systemType.ApigwFilter, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.ApigwFilter, 0, DefaultSliceCapacity)
+ res *systemType.ApigwFilter
+ aux auxApigwFilter
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ApigwFilter != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ApigwFilter(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ApigwFilterFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ApigwFilter: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := apigwFilterSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableApigwFilterFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ApigwFilter: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ApigwFilter: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ApigwFilter: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ApigwFilter: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ApigwFilter: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ApigwFilter: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupApigwFilterByID searches for filter by ID
+//
+// This function is auto-generated
+func (s Store) LookupApigwFilterByID(ctx context.Context, id uint64) (_ *systemType.ApigwFilter, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxApigwFilter)
+ lookup = apigwFilterSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupApigwFilterByRoute searches for filter by route
+//
+// This function is auto-generated
+func (s Store) LookupApigwFilterByRoute(ctx context.Context, route uint64) (_ *systemType.ApigwFilter, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxApigwFilter)
+ lookup = apigwFilterSelectQuery(s.config.Dialect).Where(
+ goqu.I("route").Eq(route),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableApigwFilterFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableApigwFilterFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectApigwFilterCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectApigwFilterCursorValues(res *systemType.ApigwFilter, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkApigwFilterConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkApigwFilterConstraints(ctx context.Context, res *systemType.ApigwFilter) (err error) {
+ return nil
+}
+
+// CreateApigwRoute creates one or more rows in apigwRoute collection
+//
+// This function is auto-generated
+func (s Store) CreateApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) (err error) {
+ for i := range rr {
+ if err = s.checkApigwRouteConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, apigwRouteInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateApigwRoute updates one or more existing entries in apigwRoute collection
+//
+// This function is auto-generated
+func (s Store) UpdateApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) (err error) {
+ for i := range rr {
+ if err = s.checkApigwRouteConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, apigwRouteUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertApigwRoute updates one or more existing entries in apigwRoute collection
+//
+// This function is auto-generated
+func (s Store) UpsertApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) (err error) {
+ for i := range rr {
+ if err = s.checkApigwRouteConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, apigwRouteUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteApigwRoute Deletes one or more entries from apigwRoute collection
+//
+// This function is auto-generated
+func (s Store) DeleteApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, apigwRouteDeleteQuery(s.config.Dialect, apigwRoutePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteApigwRouteByID deletes single entry from apigwRoute collection
+//
+// This function is auto-generated
+func (s Store) DeleteApigwRouteByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, apigwRouteDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateApigwRoutes Deletes all rows from the apigwRoute collection
+func (s Store) TruncateApigwRoutes(ctx context.Context) error {
+ return s.Exec(ctx, apigwRouteTruncateQuery(s.config.Dialect))
+}
+
+// SearchApigwRoutes returns (filtered) set of ApigwRoutes
+//
+// This function is auto-generated
+func (s Store) SearchApigwRoutes(ctx context.Context, f systemType.ApigwRouteFilter) (set systemType.ApigwRouteSet, _ systemType.ApigwRouteFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfApigwRoutes fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfApigwRoutes(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfApigwRoutes collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfApigwRoutes(
+ ctx context.Context,
+ filter systemType.ApigwRouteFilter,
+) (set []*systemType.ApigwRoute, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.ApigwRoute
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.ApigwRouteFilter
+ )
+
+ set = make([]*systemType.ApigwRoute, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryApigwRoutes(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectApigwRouteCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectApigwRouteCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectApigwRouteCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryApigwRoutes queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryApigwRoutes(
+ ctx context.Context,
+ f systemType.ApigwRouteFilter,
+) (_ []*systemType.ApigwRoute, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.ApigwRoute, 0, DefaultSliceCapacity)
+ res *systemType.ApigwRoute
+ aux auxApigwRoute
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ApigwRoute != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ApigwRoute(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ApigwRouteFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ApigwRoute: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := apigwRouteSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableApigwRouteFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ApigwRoute: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ApigwRoute: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ApigwRoute: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ApigwRoute: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ApigwRoute: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ApigwRoute: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupApigwRouteByID searches for route by ID
+//
+// It returns route even if deleted or suspended
+//
+// This function is auto-generated
+func (s Store) LookupApigwRouteByID(ctx context.Context, id uint64) (_ *systemType.ApigwRoute, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxApigwRoute)
+ lookup = apigwRouteSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupApigwRouteByEndpoint searches for route by endpoint
+//
+// It returns route even if deleted or suspended
+//
+// This function is auto-generated
+func (s Store) LookupApigwRouteByEndpoint(ctx context.Context, endpoint string) (_ *systemType.ApigwRoute, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxApigwRoute)
+ lookup = apigwRouteSelectQuery(s.config.Dialect).Where(
+ goqu.I("endpoint").Eq(endpoint),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableApigwRouteFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableApigwRouteFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectApigwRouteCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectApigwRouteCursorValues(res *systemType.ApigwRoute, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkApigwRouteConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkApigwRouteConstraints(ctx context.Context, res *systemType.ApigwRoute) (err error) {
+ return nil
+}
+
+// CreateApplication creates one or more rows in application collection
+//
+// This function is auto-generated
+func (s Store) CreateApplication(ctx context.Context, rr ...*systemType.Application) (err error) {
+ for i := range rr {
+ if err = s.checkApplicationConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, applicationInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateApplication updates one or more existing entries in application collection
+//
+// This function is auto-generated
+func (s Store) UpdateApplication(ctx context.Context, rr ...*systemType.Application) (err error) {
+ for i := range rr {
+ if err = s.checkApplicationConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, applicationUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertApplication updates one or more existing entries in application collection
+//
+// This function is auto-generated
+func (s Store) UpsertApplication(ctx context.Context, rr ...*systemType.Application) (err error) {
+ for i := range rr {
+ if err = s.checkApplicationConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, applicationUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteApplication Deletes one or more entries from application collection
+//
+// This function is auto-generated
+func (s Store) DeleteApplication(ctx context.Context, rr ...*systemType.Application) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, applicationDeleteQuery(s.config.Dialect, applicationPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteApplicationByID deletes single entry from application collection
+//
+// This function is auto-generated
+func (s Store) DeleteApplicationByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, applicationDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateApplications Deletes all rows from the application collection
+func (s Store) TruncateApplications(ctx context.Context) error {
+ return s.Exec(ctx, applicationTruncateQuery(s.config.Dialect))
+}
+
+// SearchApplications returns (filtered) set of Applications
+//
+// This function is auto-generated
+func (s Store) SearchApplications(ctx context.Context, f systemType.ApplicationFilter) (set systemType.ApplicationSet, _ systemType.ApplicationFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfApplications fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfApplications(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfApplications collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfApplications(
+ ctx context.Context,
+ filter systemType.ApplicationFilter,
+) (set []*systemType.Application, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Application
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.ApplicationFilter
+ )
+
+ set = make([]*systemType.Application, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryApplications(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectApplicationCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectApplicationCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectApplicationCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryApplications queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryApplications(
+ ctx context.Context,
+ f systemType.ApplicationFilter,
+) (_ []*systemType.Application, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Application, 0, DefaultSliceCapacity)
+ res *systemType.Application
+ aux auxApplication
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Application != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Application(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ApplicationFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Application: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := applicationSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableApplicationFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Application: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Application: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Application: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Application: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Application: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Application: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupApplicationByID searches for role by ID
+//
+// It returns role even if deleted or suspended
+//
+// This function is auto-generated
+func (s Store) LookupApplicationByID(ctx context.Context, id uint64) (_ *systemType.Application, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxApplication)
+ lookup = applicationSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableApplicationFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableApplicationFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectApplicationCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectApplicationCursorValues(res *systemType.Application, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkApplicationConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkApplicationConstraints(ctx context.Context, res *systemType.Application) (err error) {
+ return nil
+}
+
+// CreateAttachment creates one or more rows in attachment collection
+//
+// This function is auto-generated
+func (s Store) CreateAttachment(ctx context.Context, rr ...*systemType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.checkAttachmentConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, attachmentInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAttachment updates one or more existing entries in attachment collection
+//
+// This function is auto-generated
+func (s Store) UpdateAttachment(ctx context.Context, rr ...*systemType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.checkAttachmentConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, attachmentUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAttachment updates one or more existing entries in attachment collection
+//
+// This function is auto-generated
+func (s Store) UpsertAttachment(ctx context.Context, rr ...*systemType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.checkAttachmentConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, attachmentUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAttachment Deletes one or more entries from attachment collection
+//
+// This function is auto-generated
+func (s Store) DeleteAttachment(ctx context.Context, rr ...*systemType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, attachmentDeleteQuery(s.config.Dialect, attachmentPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAttachmentByID deletes single entry from attachment collection
+//
+// This function is auto-generated
+func (s Store) DeleteAttachmentByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, attachmentDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAttachments Deletes all rows from the attachment collection
+func (s Store) TruncateAttachments(ctx context.Context) error {
+ return s.Exec(ctx, attachmentTruncateQuery(s.config.Dialect))
+}
+
+// SearchAttachments returns (filtered) set of Attachments
+//
+// This function is auto-generated
+func (s Store) SearchAttachments(ctx context.Context, f systemType.AttachmentFilter) (set systemType.AttachmentSet, _ systemType.AttachmentFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfAttachments fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAttachments(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfAttachments collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfAttachments(
+ ctx context.Context,
+ filter systemType.AttachmentFilter,
+) (set []*systemType.Attachment, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Attachment
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.AttachmentFilter
+ )
+
+ set = make([]*systemType.Attachment, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryAttachments(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectAttachmentCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectAttachmentCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectAttachmentCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryAttachments queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAttachments(
+ ctx context.Context,
+ f systemType.AttachmentFilter,
+) (_ []*systemType.Attachment, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Attachment, 0, DefaultSliceCapacity)
+ res *systemType.Attachment
+ aux auxAttachment
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Attachment != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Attachment(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AttachmentFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Attachment: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := attachmentSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableAttachmentFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Attachment: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Attachment: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Attachment: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Attachment: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Attachment: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Attachment: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupAttachmentByID
+//
+// This function is auto-generated
+func (s Store) LookupAttachmentByID(ctx context.Context, id uint64) (_ *systemType.Attachment, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAttachment)
+ lookup = attachmentSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAttachmentFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAttachmentFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectAttachmentCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAttachmentCursorValues(res *systemType.Attachment, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAttachmentConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAttachmentConstraints(ctx context.Context, res *systemType.Attachment) (err error) {
+ return nil
+}
+
+// CreateAuthClient creates one or more rows in authClient collection
+//
+// This function is auto-generated
+func (s Store) CreateAuthClient(ctx context.Context, rr ...*systemType.AuthClient) (err error) {
+ for i := range rr {
+ if err = s.checkAuthClientConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authClientInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAuthClient updates one or more existing entries in authClient collection
+//
+// This function is auto-generated
+func (s Store) UpdateAuthClient(ctx context.Context, rr ...*systemType.AuthClient) (err error) {
+ for i := range rr {
+ if err = s.checkAuthClientConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authClientUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAuthClient updates one or more existing entries in authClient collection
+//
+// This function is auto-generated
+func (s Store) UpsertAuthClient(ctx context.Context, rr ...*systemType.AuthClient) (err error) {
+ for i := range rr {
+ if err = s.checkAuthClientConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authClientUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAuthClient Deletes one or more entries from authClient collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthClient(ctx context.Context, rr ...*systemType.AuthClient) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, authClientDeleteQuery(s.config.Dialect, authClientPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAuthClientByID deletes single entry from authClient collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthClientByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, authClientDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAuthClients Deletes all rows from the authClient collection
+func (s Store) TruncateAuthClients(ctx context.Context) error {
+ return s.Exec(ctx, authClientTruncateQuery(s.config.Dialect))
+}
+
+// SearchAuthClients returns (filtered) set of AuthClients
+//
+// This function is auto-generated
+func (s Store) SearchAuthClients(ctx context.Context, f systemType.AuthClientFilter) (set systemType.AuthClientSet, _ systemType.AuthClientFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfAuthClients fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAuthClients(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfAuthClients collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfAuthClients(
+ ctx context.Context,
+ filter systemType.AuthClientFilter,
+) (set []*systemType.AuthClient, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.AuthClient
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.AuthClientFilter
+ )
+
+ set = make([]*systemType.AuthClient, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryAuthClients(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectAuthClientCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectAuthClientCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectAuthClientCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryAuthClients queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAuthClients(
+ ctx context.Context,
+ f systemType.AuthClientFilter,
+) (_ []*systemType.AuthClient, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.AuthClient, 0, DefaultSliceCapacity)
+ res *systemType.AuthClient
+ aux auxAuthClient
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.AuthClient != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AuthClient(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AuthClientFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AuthClient: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := authClientSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableAuthClientFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for AuthClient: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AuthClient: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthClient: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthClient: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AuthClient: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AuthClient: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupAuthClientByID searches for auth client by ID
+//
+// It returns auth clint even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupAuthClientByID(ctx context.Context, id uint64) (_ *systemType.AuthClient, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthClient)
+ lookup = authClientSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupAuthClientByHandle searches for auth client by ID
+//
+// It returns auth clint even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupAuthClientByHandle(ctx context.Context, handle string) (_ *systemType.AuthClient, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthClient)
+ lookup = authClientSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAuthClientFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAuthClientFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "expires_at": "expires_at",
+ "expiresat": "expires_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectAuthClientCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAuthClientCursorValues(res *systemType.AuthClient, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "expiresAt":
+ cur.Set(c.Column, res.ExpiresAt, c.Descending)
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAuthClientConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAuthClientConstraints(ctx context.Context, res *systemType.AuthClient) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupAuthClientByHandle(ctx, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateAuthConfirmedClient creates one or more rows in authConfirmedClient collection
+//
+// This function is auto-generated
+func (s Store) CreateAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) (err error) {
+ for i := range rr {
+ if err = s.checkAuthConfirmedClientConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authConfirmedClientInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAuthConfirmedClient updates one or more existing entries in authConfirmedClient collection
+//
+// This function is auto-generated
+func (s Store) UpdateAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) (err error) {
+ for i := range rr {
+ if err = s.checkAuthConfirmedClientConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authConfirmedClientUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAuthConfirmedClient updates one or more existing entries in authConfirmedClient collection
+//
+// This function is auto-generated
+func (s Store) UpsertAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) (err error) {
+ for i := range rr {
+ if err = s.checkAuthConfirmedClientConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authConfirmedClientUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAuthConfirmedClient Deletes one or more entries from authConfirmedClient collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, authConfirmedClientDeleteQuery(s.config.Dialect, authConfirmedClientPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAuthConfirmedClientByID deletes single entry from authConfirmedClient collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthConfirmedClientByUserIDClientID(ctx context.Context, userID uint64, clientID uint64) error {
+ return s.Exec(ctx, authConfirmedClientDeleteQuery(s.config.Dialect, goqu.Ex{
+ "rel_user": userID,
+ "rel_client": clientID,
+ }))
+}
+
+// TruncateAuthConfirmedClients Deletes all rows from the authConfirmedClient collection
+func (s Store) TruncateAuthConfirmedClients(ctx context.Context) error {
+ return s.Exec(ctx, authConfirmedClientTruncateQuery(s.config.Dialect))
+}
+
+// SearchAuthConfirmedClients returns (filtered) set of AuthConfirmedClients
+//
+// This function is auto-generated
+func (s Store) SearchAuthConfirmedClients(ctx context.Context, f systemType.AuthConfirmedClientFilter) (set systemType.AuthConfirmedClientSet, _ systemType.AuthConfirmedClientFilter, err error) {
+
+ set, _, err = s.QueryAuthConfirmedClients(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryAuthConfirmedClients queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAuthConfirmedClients(
+ ctx context.Context,
+ f systemType.AuthConfirmedClientFilter,
+) (_ []*systemType.AuthConfirmedClient, more bool, err error) {
+ var (
+ set = make([]*systemType.AuthConfirmedClient, 0, DefaultSliceCapacity)
+ res *systemType.AuthConfirmedClient
+ aux auxAuthConfirmedClient
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.AuthConfirmedClient != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AuthConfirmedClient(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AuthConfirmedClientFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AuthConfirmedClient: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := authConfirmedClientSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AuthConfirmedClient: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthConfirmedClient: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthConfirmedClient: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AuthConfirmedClient: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AuthConfirmedClient: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupAuthConfirmedClientByUserIDClientID
+//
+// This function is auto-generated
+func (s Store) LookupAuthConfirmedClientByUserIDClientID(ctx context.Context, userID uint64, clientID uint64) (_ *systemType.AuthConfirmedClient, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthConfirmedClient)
+ lookup = authConfirmedClientSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_user").Eq(userID),
+ goqu.I("rel_client").Eq(clientID),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAuthConfirmedClientFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAuthConfirmedClientFields() map[string]string {
+ return map[string]string{
+ "client_id": "client_id",
+ "clientid": "client_id",
+ "confirmed_at": "confirmed_at",
+ "confirmedat": "confirmed_at",
+ "user_id": "user_id",
+ "userid": "user_id",
+ }
+}
+
+// collectAuthConfirmedClientCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAuthConfirmedClientCursorValues(res *systemType.AuthConfirmedClient, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkUserID bool
+ pkClientID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "userID":
+ cur.Set(c.Column, res.UserID, c.Descending)
+ pkUserID = true
+ case "clientID":
+ cur.Set(c.Column, res.ClientID, c.Descending)
+ pkClientID = true
+ case "confirmedAt":
+ cur.Set(c.Column, res.ConfirmedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkUserID {
+ collect(&filter.SortExpr{Column: "userID", Descending: false})
+ }
+ if !hasUnique || !pkClientID {
+ collect(&filter.SortExpr{Column: "clientID", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAuthConfirmedClientConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAuthConfirmedClientConstraints(ctx context.Context, res *systemType.AuthConfirmedClient) (err error) {
+ return nil
+}
+
+// CreateAuthOa2token creates one or more rows in authOa2token collection
+//
+// This function is auto-generated
+func (s Store) CreateAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) (err error) {
+ for i := range rr {
+ if err = s.checkAuthOa2tokenConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authOa2tokenInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAuthOa2token updates one or more existing entries in authOa2token collection
+//
+// This function is auto-generated
+func (s Store) UpdateAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) (err error) {
+ for i := range rr {
+ if err = s.checkAuthOa2tokenConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authOa2tokenUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAuthOa2token updates one or more existing entries in authOa2token collection
+//
+// This function is auto-generated
+func (s Store) UpsertAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) (err error) {
+ for i := range rr {
+ if err = s.checkAuthOa2tokenConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authOa2tokenUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAuthOa2token Deletes one or more entries from authOa2token collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, authOa2tokenPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAuthOa2tokenByID deletes single entry from authOa2token collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthOa2tokenByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, authOa2tokenDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAuthOa2tokens Deletes all rows from the authOa2token collection
+func (s Store) TruncateAuthOa2tokens(ctx context.Context) error {
+ return s.Exec(ctx, authOa2tokenTruncateQuery(s.config.Dialect))
+}
+
+// SearchAuthOa2tokens returns (filtered) set of AuthOa2tokens
+//
+// This function is auto-generated
+func (s Store) SearchAuthOa2tokens(ctx context.Context, f systemType.AuthOa2tokenFilter) (set systemType.AuthOa2tokenSet, _ systemType.AuthOa2tokenFilter, err error) {
+
+ set, _, err = s.QueryAuthOa2tokens(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryAuthOa2tokens queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAuthOa2tokens(
+ ctx context.Context,
+ f systemType.AuthOa2tokenFilter,
+) (_ []*systemType.AuthOa2token, more bool, err error) {
+ var (
+ set = make([]*systemType.AuthOa2token, 0, DefaultSliceCapacity)
+ res *systemType.AuthOa2token
+ aux auxAuthOa2token
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.AuthOa2token != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AuthOa2token(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AuthOa2tokenFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AuthOa2token: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := authOa2tokenSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AuthOa2token: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthOa2token: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthOa2token: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AuthOa2token: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AuthOa2token: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupAuthOa2tokenByID
+//
+// This function is auto-generated
+func (s Store) LookupAuthOa2tokenByID(ctx context.Context, id uint64) (_ *systemType.AuthOa2token, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthOa2token)
+ lookup = authOa2tokenSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupAuthOa2tokenByCode
+//
+// This function is auto-generated
+func (s Store) LookupAuthOa2tokenByCode(ctx context.Context, code string) (_ *systemType.AuthOa2token, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthOa2token)
+ lookup = authOa2tokenSelectQuery(s.config.Dialect).Where(
+ goqu.I("code").Eq(code),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupAuthOa2tokenByAccess
+//
+// This function is auto-generated
+func (s Store) LookupAuthOa2tokenByAccess(ctx context.Context, access string) (_ *systemType.AuthOa2token, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthOa2token)
+ lookup = authOa2tokenSelectQuery(s.config.Dialect).Where(
+ goqu.I("access").Eq(access),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupAuthOa2tokenByRefresh
+//
+// This function is auto-generated
+func (s Store) LookupAuthOa2tokenByRefresh(ctx context.Context, refresh string) (_ *systemType.AuthOa2token, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthOa2token)
+ lookup = authOa2tokenSelectQuery(s.config.Dialect).Where(
+ goqu.I("refresh").Eq(refresh),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAuthOa2tokenFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAuthOa2tokenFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "expires_at": "expires_at",
+ "expiresat": "expires_at",
+ "id": "id",
+ }
+}
+
+// collectAuthOa2tokenCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAuthOa2tokenCursorValues(res *systemType.AuthOa2token, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "expiresAt":
+ cur.Set(c.Column, res.ExpiresAt, c.Descending)
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAuthOa2tokenConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAuthOa2tokenConstraints(ctx context.Context, res *systemType.AuthOa2token) (err error) {
+ return nil
+}
+
+// CreateAuthSession creates one or more rows in authSession collection
+//
+// This function is auto-generated
+func (s Store) CreateAuthSession(ctx context.Context, rr ...*systemType.AuthSession) (err error) {
+ for i := range rr {
+ if err = s.checkAuthSessionConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authSessionInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAuthSession updates one or more existing entries in authSession collection
+//
+// This function is auto-generated
+func (s Store) UpdateAuthSession(ctx context.Context, rr ...*systemType.AuthSession) (err error) {
+ for i := range rr {
+ if err = s.checkAuthSessionConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authSessionUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAuthSession updates one or more existing entries in authSession collection
+//
+// This function is auto-generated
+func (s Store) UpsertAuthSession(ctx context.Context, rr ...*systemType.AuthSession) (err error) {
+ for i := range rr {
+ if err = s.checkAuthSessionConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, authSessionUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAuthSession Deletes one or more entries from authSession collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthSession(ctx context.Context, rr ...*systemType.AuthSession) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, authSessionDeleteQuery(s.config.Dialect, authSessionPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAuthSessionByID deletes single entry from authSession collection
+//
+// This function is auto-generated
+func (s Store) DeleteAuthSessionByID(ctx context.Context, id string) error {
+ return s.Exec(ctx, authSessionDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAuthSessions Deletes all rows from the authSession collection
+func (s Store) TruncateAuthSessions(ctx context.Context) error {
+ return s.Exec(ctx, authSessionTruncateQuery(s.config.Dialect))
+}
+
+// SearchAuthSessions returns (filtered) set of AuthSessions
+//
+// This function is auto-generated
+func (s Store) SearchAuthSessions(ctx context.Context, f systemType.AuthSessionFilter) (set systemType.AuthSessionSet, _ systemType.AuthSessionFilter, err error) {
+
+ set, _, err = s.QueryAuthSessions(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryAuthSessions queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAuthSessions(
+ ctx context.Context,
+ f systemType.AuthSessionFilter,
+) (_ []*systemType.AuthSession, more bool, err error) {
+ var (
+ set = make([]*systemType.AuthSession, 0, DefaultSliceCapacity)
+ res *systemType.AuthSession
+ aux auxAuthSession
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.AuthSession != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AuthSession(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AuthSessionFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AuthSession: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := authSessionSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AuthSession: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthSession: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AuthSession: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AuthSession: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AuthSession: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupAuthSessionByID
+//
+// This function is auto-generated
+func (s Store) LookupAuthSessionByID(ctx context.Context, id string) (_ *systemType.AuthSession, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAuthSession)
+ lookup = authSessionSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAuthSessionFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAuthSessionFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "expires_at": "expires_at",
+ "expiresat": "expires_at",
+ "id": "id",
+ }
+}
+
+// collectAuthSessionCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAuthSessionCursorValues(res *systemType.AuthSession, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "expiresAt":
+ cur.Set(c.Column, res.ExpiresAt, c.Descending)
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAuthSessionConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAuthSessionConstraints(ctx context.Context, res *systemType.AuthSession) (err error) {
+ return nil
+}
+
+// CreateAutomationSession creates one or more rows in automationSession collection
+//
+// This function is auto-generated
+func (s Store) CreateAutomationSession(ctx context.Context, rr ...*automationType.Session) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationSessionConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationSessionInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAutomationSession updates one or more existing entries in automationSession collection
+//
+// This function is auto-generated
+func (s Store) UpdateAutomationSession(ctx context.Context, rr ...*automationType.Session) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationSessionConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationSessionUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAutomationSession updates one or more existing entries in automationSession collection
+//
+// This function is auto-generated
+func (s Store) UpsertAutomationSession(ctx context.Context, rr ...*automationType.Session) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationSessionConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationSessionUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAutomationSession Deletes one or more entries from automationSession collection
+//
+// This function is auto-generated
+func (s Store) DeleteAutomationSession(ctx context.Context, rr ...*automationType.Session) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, automationSessionDeleteQuery(s.config.Dialect, automationSessionPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAutomationSessionByID deletes single entry from automationSession collection
+//
+// This function is auto-generated
+func (s Store) DeleteAutomationSessionByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, automationSessionDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAutomationSessions Deletes all rows from the automationSession collection
+func (s Store) TruncateAutomationSessions(ctx context.Context) error {
+ return s.Exec(ctx, automationSessionTruncateQuery(s.config.Dialect))
+}
+
+// SearchAutomationSessions returns (filtered) set of AutomationSessions
+//
+// This function is auto-generated
+func (s Store) SearchAutomationSessions(ctx context.Context, f automationType.SessionFilter) (set automationType.SessionSet, _ automationType.SessionFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfAutomationSessions fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAutomationSessions(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfAutomationSessions collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfAutomationSessions(
+ ctx context.Context,
+ filter automationType.SessionFilter,
+) (set []*automationType.Session, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*automationType.Session
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter automationType.SessionFilter
+ )
+
+ set = make([]*automationType.Session, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryAutomationSessions(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectAutomationSessionCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectAutomationSessionCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectAutomationSessionCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryAutomationSessions queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAutomationSessions(
+ ctx context.Context,
+ f automationType.SessionFilter,
+) (_ []*automationType.Session, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*automationType.Session, 0, DefaultSliceCapacity)
+ res *automationType.Session
+ aux auxAutomationSession
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.AutomationSession != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AutomationSession(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AutomationSessionFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AutomationSession: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := automationSessionSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableAutomationSessionFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for AutomationSession: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AutomationSession: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AutomationSession: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AutomationSession: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AutomationSession: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AutomationSession: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupAutomationSessionByID searches for session by ID
+//
+// It returns session even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupAutomationSessionByID(ctx context.Context, id uint64) (_ *automationType.Session, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAutomationSession)
+ lookup = automationSessionSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAutomationSessionFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAutomationSessionFields() map[string]string {
+ return map[string]string{
+ "completed_at": "completed_at",
+ "completedat": "completed_at",
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "id": "id",
+ "purge_at": "purge_at",
+ "purgeat": "purge_at",
+ "suspended_at": "suspended_at",
+ "suspendedat": "suspended_at",
+ }
+}
+
+// collectAutomationSessionCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAutomationSessionCursorValues(res *automationType.Session, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "purgeAt":
+ cur.Set(c.Column, res.PurgeAt, c.Descending)
+ case "completedAt":
+ cur.Set(c.Column, res.CompletedAt, c.Descending)
+ case "suspendedAt":
+ cur.Set(c.Column, res.SuspendedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAutomationSessionConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAutomationSessionConstraints(ctx context.Context, res *automationType.Session) (err error) {
+ return nil
+}
+
+// CreateAutomationTrigger creates one or more rows in automationTrigger collection
+//
+// This function is auto-generated
+func (s Store) CreateAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationTriggerConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationTriggerInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAutomationTrigger updates one or more existing entries in automationTrigger collection
+//
+// This function is auto-generated
+func (s Store) UpdateAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationTriggerConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationTriggerUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAutomationTrigger updates one or more existing entries in automationTrigger collection
+//
+// This function is auto-generated
+func (s Store) UpsertAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationTriggerConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationTriggerUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAutomationTrigger Deletes one or more entries from automationTrigger collection
+//
+// This function is auto-generated
+func (s Store) DeleteAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, automationTriggerDeleteQuery(s.config.Dialect, automationTriggerPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAutomationTriggerByID deletes single entry from automationTrigger collection
+//
+// This function is auto-generated
+func (s Store) DeleteAutomationTriggerByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, automationTriggerDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAutomationTriggers Deletes all rows from the automationTrigger collection
+func (s Store) TruncateAutomationTriggers(ctx context.Context) error {
+ return s.Exec(ctx, automationTriggerTruncateQuery(s.config.Dialect))
+}
+
+// SearchAutomationTriggers returns (filtered) set of AutomationTriggers
+//
+// This function is auto-generated
+func (s Store) SearchAutomationTriggers(ctx context.Context, f automationType.TriggerFilter) (set automationType.TriggerSet, _ automationType.TriggerFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfAutomationTriggers fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAutomationTriggers(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfAutomationTriggers collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfAutomationTriggers(
+ ctx context.Context,
+ filter automationType.TriggerFilter,
+) (set []*automationType.Trigger, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*automationType.Trigger
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter automationType.TriggerFilter
+ )
+
+ set = make([]*automationType.Trigger, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryAutomationTriggers(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectAutomationTriggerCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectAutomationTriggerCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectAutomationTriggerCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryAutomationTriggers queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAutomationTriggers(
+ ctx context.Context,
+ f automationType.TriggerFilter,
+) (_ []*automationType.Trigger, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*automationType.Trigger, 0, DefaultSliceCapacity)
+ res *automationType.Trigger
+ aux auxAutomationTrigger
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.AutomationTrigger != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AutomationTrigger(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AutomationTriggerFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AutomationTrigger: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := automationTriggerSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableAutomationTriggerFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for AutomationTrigger: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AutomationTrigger: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AutomationTrigger: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AutomationTrigger: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AutomationTrigger: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AutomationTrigger: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupAutomationTriggerByID searches for trigger by ID
+//
+// It returns trigger even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupAutomationTriggerByID(ctx context.Context, id uint64) (_ *automationType.Trigger, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAutomationTrigger)
+ lookup = automationTriggerSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAutomationTriggerFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAutomationTriggerFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectAutomationTriggerCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAutomationTriggerCursorValues(res *automationType.Trigger, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAutomationTriggerConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAutomationTriggerConstraints(ctx context.Context, res *automationType.Trigger) (err error) {
+ return nil
+}
+
+// CreateAutomationWorkflow creates one or more rows in automationWorkflow collection
+//
+// This function is auto-generated
+func (s Store) CreateAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationWorkflowConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationWorkflowInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateAutomationWorkflow updates one or more existing entries in automationWorkflow collection
+//
+// This function is auto-generated
+func (s Store) UpdateAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationWorkflowConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationWorkflowUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertAutomationWorkflow updates one or more existing entries in automationWorkflow collection
+//
+// This function is auto-generated
+func (s Store) UpsertAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) (err error) {
+ for i := range rr {
+ if err = s.checkAutomationWorkflowConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, automationWorkflowUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteAutomationWorkflow Deletes one or more entries from automationWorkflow collection
+//
+// This function is auto-generated
+func (s Store) DeleteAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, automationWorkflowDeleteQuery(s.config.Dialect, automationWorkflowPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteAutomationWorkflowByID deletes single entry from automationWorkflow collection
+//
+// This function is auto-generated
+func (s Store) DeleteAutomationWorkflowByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, automationWorkflowDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateAutomationWorkflows Deletes all rows from the automationWorkflow collection
+func (s Store) TruncateAutomationWorkflows(ctx context.Context) error {
+ return s.Exec(ctx, automationWorkflowTruncateQuery(s.config.Dialect))
+}
+
+// SearchAutomationWorkflows returns (filtered) set of AutomationWorkflows
+//
+// This function is auto-generated
+func (s Store) SearchAutomationWorkflows(ctx context.Context, f automationType.WorkflowFilter) (set automationType.WorkflowSet, _ automationType.WorkflowFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfAutomationWorkflows fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAutomationWorkflows(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfAutomationWorkflows collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfAutomationWorkflows(
+ ctx context.Context,
+ filter automationType.WorkflowFilter,
+) (set []*automationType.Workflow, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*automationType.Workflow
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter automationType.WorkflowFilter
+ )
+
+ set = make([]*automationType.Workflow, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryAutomationWorkflows(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectAutomationWorkflowCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectAutomationWorkflowCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectAutomationWorkflowCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryAutomationWorkflows queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryAutomationWorkflows(
+ ctx context.Context,
+ f automationType.WorkflowFilter,
+) (_ []*automationType.Workflow, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*automationType.Workflow, 0, DefaultSliceCapacity)
+ res *automationType.Workflow
+ aux auxAutomationWorkflow
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.AutomationWorkflow != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.AutomationWorkflow(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = AutomationWorkflowFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for AutomationWorkflow: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := automationWorkflowSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableAutomationWorkflowFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for AutomationWorkflow: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query AutomationWorkflow: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AutomationWorkflow: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query AutomationWorkflow: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for AutomationWorkflow: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode AutomationWorkflow: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupAutomationWorkflowByID searches for workflow by ID
+//
+// It returns workflow even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupAutomationWorkflowByID(ctx context.Context, id uint64) (_ *automationType.Workflow, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAutomationWorkflow)
+ lookup = automationWorkflowSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupAutomationWorkflowByHandle searches for workflow by their handle
+//
+// It returns only valid workflows
+//
+// This function is auto-generated
+func (s Store) LookupAutomationWorkflowByHandle(ctx context.Context, handle string) (_ *automationType.Workflow, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxAutomationWorkflow)
+ lookup = automationWorkflowSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableAutomationWorkflowFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableAutomationWorkflowFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectAutomationWorkflowCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectAutomationWorkflowCursorValues(res *automationType.Workflow, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkAutomationWorkflowConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkAutomationWorkflowConstraints(ctx context.Context, res *automationType.Workflow) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupAutomationWorkflowByHandle(ctx, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateComposeAttachment creates one or more rows in composeAttachment collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.checkComposeAttachmentConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeAttachmentInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeAttachment updates one or more existing entries in composeAttachment collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.checkComposeAttachmentConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeAttachmentUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeAttachment updates one or more existing entries in composeAttachment collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.checkComposeAttachmentConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeAttachmentUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeAttachment Deletes one or more entries from composeAttachment collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeAttachmentDeleteQuery(s.config.Dialect, composeAttachmentPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeAttachmentByID deletes single entry from composeAttachment collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeAttachmentByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, composeAttachmentDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposeAttachments Deletes all rows from the composeAttachment collection
+func (s Store) TruncateComposeAttachments(ctx context.Context) error {
+ return s.Exec(ctx, composeAttachmentTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeAttachments returns (filtered) set of ComposeAttachments
+//
+// This function is auto-generated
+func (s Store) SearchComposeAttachments(ctx context.Context, f composeType.AttachmentFilter) (set composeType.AttachmentSet, _ composeType.AttachmentFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfComposeAttachments fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeAttachments(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfComposeAttachments collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfComposeAttachments(
+ ctx context.Context,
+ filter composeType.AttachmentFilter,
+) (set []*composeType.Attachment, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*composeType.Attachment
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter composeType.AttachmentFilter
+ )
+
+ set = make([]*composeType.Attachment, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryComposeAttachments(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectComposeAttachmentCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectComposeAttachmentCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectComposeAttachmentCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryComposeAttachments queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeAttachments(
+ ctx context.Context,
+ f composeType.AttachmentFilter,
+) (_ []*composeType.Attachment, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*composeType.Attachment, 0, DefaultSliceCapacity)
+ res *composeType.Attachment
+ aux auxComposeAttachment
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ComposeAttachment != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeAttachment(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeAttachmentFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeAttachment: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := composeAttachmentSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableComposeAttachmentFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ComposeAttachment: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeAttachment: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeAttachment: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeAttachment: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeAttachment: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeAttachment: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupComposeAttachmentByID
+//
+// This function is auto-generated
+func (s Store) LookupComposeAttachmentByID(ctx context.Context, id uint64) (_ *composeType.Attachment, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeAttachment)
+ lookup = composeAttachmentSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposeAttachmentFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeAttachmentFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectComposeAttachmentCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeAttachmentCursorValues(res *composeType.Attachment, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeAttachmentConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeAttachmentConstraints(ctx context.Context, res *composeType.Attachment) (err error) {
+ return nil
+}
+
+// CreateComposeChart creates one or more rows in composeChart collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeChart(ctx context.Context, rr ...*composeType.Chart) (err error) {
+ for i := range rr {
+ if err = s.checkComposeChartConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeChartInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeChart updates one or more existing entries in composeChart collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeChart(ctx context.Context, rr ...*composeType.Chart) (err error) {
+ for i := range rr {
+ if err = s.checkComposeChartConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeChartUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeChart updates one or more existing entries in composeChart collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeChart(ctx context.Context, rr ...*composeType.Chart) (err error) {
+ for i := range rr {
+ if err = s.checkComposeChartConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeChartUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeChart Deletes one or more entries from composeChart collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeChart(ctx context.Context, rr ...*composeType.Chart) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeChartDeleteQuery(s.config.Dialect, composeChartPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeChartByID deletes single entry from composeChart collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeChartByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, composeChartDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposeCharts Deletes all rows from the composeChart collection
+func (s Store) TruncateComposeCharts(ctx context.Context) error {
+ return s.Exec(ctx, composeChartTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeCharts returns (filtered) set of ComposeCharts
+//
+// This function is auto-generated
+func (s Store) SearchComposeCharts(ctx context.Context, f composeType.ChartFilter) (set composeType.ChartSet, _ composeType.ChartFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfComposeCharts fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeCharts(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfComposeCharts collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfComposeCharts(
+ ctx context.Context,
+ filter composeType.ChartFilter,
+) (set []*composeType.Chart, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*composeType.Chart
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter composeType.ChartFilter
+ )
+
+ set = make([]*composeType.Chart, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryComposeCharts(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectComposeChartCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectComposeChartCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectComposeChartCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryComposeCharts queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeCharts(
+ ctx context.Context,
+ f composeType.ChartFilter,
+) (_ []*composeType.Chart, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*composeType.Chart, 0, DefaultSliceCapacity)
+ res *composeType.Chart
+ aux auxComposeChart
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ComposeChart != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeChart(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeChartFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeChart: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := composeChartSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableComposeChartFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ComposeChart: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeChart: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeChart: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeChart: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeChart: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeChart: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupComposeChartByID searches for compose chart by ID
+//
+// It returns compose chart even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupComposeChartByID(ctx context.Context, id uint64) (_ *composeType.Chart, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeChart)
+ lookup = composeChartSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupComposeChartByNamespaceIDHandle searches for compose chart by handle (case-insensitive)
+//
+// This function is auto-generated
+func (s Store) LookupComposeChartByNamespaceIDHandle(ctx context.Context, namespaceID uint64, handle string) (_ *composeType.Chart, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeChart)
+ lookup = composeChartSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_namespace").Eq(namespaceID),
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposeChartFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeChartFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectComposeChartCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeChartCursorValues(res *composeType.Chart, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeChartConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeChartConstraints(ctx context.Context, res *composeType.Chart) (err error) {
+ return nil
+}
+
+// CreateComposeModule creates one or more rows in composeModule collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeModule(ctx context.Context, rr ...*composeType.Module) (err error) {
+ for i := range rr {
+ if err = s.checkComposeModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeModuleInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeModule updates one or more existing entries in composeModule collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeModule(ctx context.Context, rr ...*composeType.Module) (err error) {
+ for i := range rr {
+ if err = s.checkComposeModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeModuleUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeModule updates one or more existing entries in composeModule collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeModule(ctx context.Context, rr ...*composeType.Module) (err error) {
+ for i := range rr {
+ if err = s.checkComposeModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeModuleUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeModule Deletes one or more entries from composeModule collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeModule(ctx context.Context, rr ...*composeType.Module) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeModuleDeleteQuery(s.config.Dialect, composeModulePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeModuleByID deletes single entry from composeModule collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeModuleByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, composeModuleDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposeModules Deletes all rows from the composeModule collection
+func (s Store) TruncateComposeModules(ctx context.Context) error {
+ return s.Exec(ctx, composeModuleTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeModules returns (filtered) set of ComposeModules
+//
+// This function is auto-generated
+func (s Store) SearchComposeModules(ctx context.Context, f composeType.ModuleFilter) (set composeType.ModuleSet, _ composeType.ModuleFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfComposeModules fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeModules(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfComposeModules collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfComposeModules(
+ ctx context.Context,
+ filter composeType.ModuleFilter,
+) (set []*composeType.Module, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*composeType.Module
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter composeType.ModuleFilter
+ )
+
+ set = make([]*composeType.Module, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryComposeModules(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectComposeModuleCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectComposeModuleCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectComposeModuleCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryComposeModules queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeModules(
+ ctx context.Context,
+ f composeType.ModuleFilter,
+) (_ []*composeType.Module, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*composeType.Module, 0, DefaultSliceCapacity)
+ res *composeType.Module
+ aux auxComposeModule
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ComposeModule != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeModule(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeModuleFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeModule: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := composeModuleSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableComposeModuleFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ComposeModule: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeModule: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeModule: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeModule: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeModule: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeModule: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupComposeModuleByNamespaceIDHandle searches for compose module by handle (case-insensitive)
+//
+// This function is auto-generated
+func (s Store) LookupComposeModuleByNamespaceIDHandle(ctx context.Context, namespaceID uint64, handle string) (_ *composeType.Module, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeModule)
+ lookup = composeModuleSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_namespace").Eq(namespaceID),
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupComposeModuleByNamespaceIDName searches for compose module by name (case-insensitive)
+//
+// This function is auto-generated
+func (s Store) LookupComposeModuleByNamespaceIDName(ctx context.Context, namespaceID uint64, name string) (_ *composeType.Module, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeModule)
+ lookup = composeModuleSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_namespace").Eq(namespaceID),
+ goqu.I("name").Eq(name),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupComposeModuleByID searches for compose module by ID
+//
+// It returns compose module even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupComposeModuleByID(ctx context.Context, id uint64) (_ *composeType.Module, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeModule)
+ lookup = composeModuleSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposeModuleFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeModuleFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectComposeModuleCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeModuleCursorValues(res *composeType.Module, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeModuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeModuleConstraints(ctx context.Context, res *composeType.Module) (err error) {
+ err = func() (err error) {
+
+ if res.NamespaceID == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupComposeModuleByNamespaceIDHandle(ctx, res.NamespaceID, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateComposeModuleField creates one or more rows in composeModuleField collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) (err error) {
+ for i := range rr {
+ if err = s.checkComposeModuleFieldConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeModuleFieldInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeModuleField updates one or more existing entries in composeModuleField collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) (err error) {
+ for i := range rr {
+ if err = s.checkComposeModuleFieldConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeModuleFieldUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeModuleField updates one or more existing entries in composeModuleField collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) (err error) {
+ for i := range rr {
+ if err = s.checkComposeModuleFieldConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeModuleFieldUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeModuleField Deletes one or more entries from composeModuleField collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeModuleFieldDeleteQuery(s.config.Dialect, composeModuleFieldPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeModuleFieldByID deletes single entry from composeModuleField collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeModuleFieldByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, composeModuleFieldDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposeModuleFields Deletes all rows from the composeModuleField collection
+func (s Store) TruncateComposeModuleFields(ctx context.Context) error {
+ return s.Exec(ctx, composeModuleFieldTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeModuleFields returns (filtered) set of ComposeModuleFields
+//
+// This function is auto-generated
+func (s Store) SearchComposeModuleFields(ctx context.Context, f composeType.ModuleFieldFilter) (set composeType.ModuleFieldSet, _ composeType.ModuleFieldFilter, err error) {
+
+ set, _, err = s.QueryComposeModuleFields(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryComposeModuleFields queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeModuleFields(
+ ctx context.Context,
+ f composeType.ModuleFieldFilter,
+) (_ []*composeType.ModuleField, more bool, err error) {
+ var (
+ set = make([]*composeType.ModuleField, 0, DefaultSliceCapacity)
+ res *composeType.ModuleField
+ aux auxComposeModuleField
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.ComposeModuleField != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeModuleField(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeModuleFieldFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeModuleField: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := composeModuleFieldSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeModuleField: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeModuleField: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeModuleField: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeModuleField: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeModuleField: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupComposeModuleFieldByModuleIDName searches for compose module field by name (case-insensitive)
+//
+// This function is auto-generated
+func (s Store) LookupComposeModuleFieldByModuleIDName(ctx context.Context, moduleID uint64, name string) (_ *composeType.ModuleField, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeModuleField)
+ lookup = composeModuleFieldSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_module").Eq(moduleID),
+ goqu.I("name").Eq(name),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposeModuleFieldFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeModuleFieldFields() map[string]string {
+ return map[string]string{
+ "id": "id",
+ }
+}
+
+// collectComposeModuleFieldCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeModuleFieldCursorValues(res *composeType.ModuleField, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeModuleFieldConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeModuleFieldConstraints(ctx context.Context, res *composeType.ModuleField) (err error) {
+ err = func() (err error) {
+
+ if res.ModuleID == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ // handling string type as default
+ if len(res.Name) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupComposeModuleFieldByModuleIDName(ctx, res.ModuleID, res.Name)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateComposeNamespace creates one or more rows in composeNamespace collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) (err error) {
+ for i := range rr {
+ if err = s.checkComposeNamespaceConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeNamespaceInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeNamespace updates one or more existing entries in composeNamespace collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) (err error) {
+ for i := range rr {
+ if err = s.checkComposeNamespaceConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeNamespaceUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeNamespace updates one or more existing entries in composeNamespace collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) (err error) {
+ for i := range rr {
+ if err = s.checkComposeNamespaceConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeNamespaceUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeNamespace Deletes one or more entries from composeNamespace collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeNamespaceDeleteQuery(s.config.Dialect, composeNamespacePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeNamespaceByID deletes single entry from composeNamespace collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeNamespaceByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, composeNamespaceDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposeNamespaces Deletes all rows from the composeNamespace collection
+func (s Store) TruncateComposeNamespaces(ctx context.Context) error {
+ return s.Exec(ctx, composeNamespaceTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeNamespaces returns (filtered) set of ComposeNamespaces
+//
+// This function is auto-generated
+func (s Store) SearchComposeNamespaces(ctx context.Context, f composeType.NamespaceFilter) (set composeType.NamespaceSet, _ composeType.NamespaceFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfComposeNamespaces fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeNamespaces(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfComposeNamespaces collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfComposeNamespaces(
+ ctx context.Context,
+ filter composeType.NamespaceFilter,
+) (set []*composeType.Namespace, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*composeType.Namespace
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter composeType.NamespaceFilter
+ )
+
+ set = make([]*composeType.Namespace, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryComposeNamespaces(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectComposeNamespaceCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectComposeNamespaceCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectComposeNamespaceCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryComposeNamespaces queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeNamespaces(
+ ctx context.Context,
+ f composeType.NamespaceFilter,
+) (_ []*composeType.Namespace, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*composeType.Namespace, 0, DefaultSliceCapacity)
+ res *composeType.Namespace
+ aux auxComposeNamespace
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ComposeNamespace != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeNamespace(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeNamespaceFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeNamespace: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := composeNamespaceSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableComposeNamespaceFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ComposeNamespace: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeNamespace: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeNamespace: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeNamespace: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeNamespace: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeNamespace: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupComposeNamespaceBySlug searches for namespace by slug (case-insensitive)
+//
+// This function is auto-generated
+func (s Store) LookupComposeNamespaceBySlug(ctx context.Context, slug string) (_ *composeType.Namespace, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeNamespace)
+ lookup = composeNamespaceSelectQuery(s.config.Dialect).Where(
+ goqu.I("slug").Eq(slug),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupComposeNamespaceByID searches for compose namespace by ID
+//
+// It returns compose namespace even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupComposeNamespaceByID(ctx context.Context, id uint64) (_ *composeType.Namespace, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeNamespace)
+ lookup = composeNamespaceSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposeNamespaceFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeNamespaceFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectComposeNamespaceCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeNamespaceCursorValues(res *composeType.Namespace, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeNamespaceConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeNamespaceConstraints(ctx context.Context, res *composeType.Namespace) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Slug) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupComposeNamespaceBySlug(ctx, res.Slug)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateComposePage creates one or more rows in composePage collection
+//
+// This function is auto-generated
+func (s Store) CreateComposePage(ctx context.Context, rr ...*composeType.Page) (err error) {
+ for i := range rr {
+ if err = s.checkComposePageConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composePageInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposePage updates one or more existing entries in composePage collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposePage(ctx context.Context, rr ...*composeType.Page) (err error) {
+ for i := range rr {
+ if err = s.checkComposePageConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composePageUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposePage updates one or more existing entries in composePage collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposePage(ctx context.Context, rr ...*composeType.Page) (err error) {
+ for i := range rr {
+ if err = s.checkComposePageConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composePageUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposePage Deletes one or more entries from composePage collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposePage(ctx context.Context, rr ...*composeType.Page) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composePageDeleteQuery(s.config.Dialect, composePagePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposePageByID deletes single entry from composePage collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposePageByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, composePageDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposePages Deletes all rows from the composePage collection
+func (s Store) TruncateComposePages(ctx context.Context) error {
+ return s.Exec(ctx, composePageTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposePages returns (filtered) set of ComposePages
+//
+// This function is auto-generated
+func (s Store) SearchComposePages(ctx context.Context, f composeType.PageFilter) (set composeType.PageSet, _ composeType.PageFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfComposePages fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposePages(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfComposePages collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfComposePages(
+ ctx context.Context,
+ filter composeType.PageFilter,
+) (set []*composeType.Page, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*composeType.Page
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter composeType.PageFilter
+ )
+
+ set = make([]*composeType.Page, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryComposePages(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectComposePageCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectComposePageCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectComposePageCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryComposePages queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposePages(
+ ctx context.Context,
+ f composeType.PageFilter,
+) (_ []*composeType.Page, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*composeType.Page, 0, DefaultSliceCapacity)
+ res *composeType.Page
+ aux auxComposePage
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ComposePage != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposePage(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposePageFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposePage: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := composePageSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableComposePageFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ComposePage: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposePage: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposePage: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposePage: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposePage: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposePage: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupComposePageByNamespaceIDHandle searches for page by handle (case-insensitive)
+//
+// This function is auto-generated
+func (s Store) LookupComposePageByNamespaceIDHandle(ctx context.Context, namespaceID uint64, handle string) (_ *composeType.Page, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposePage)
+ lookup = composePageSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_namespace").Eq(namespaceID),
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupComposePageByNamespaceIDModuleID searches for page by moduleID
+//
+// This function is auto-generated
+func (s Store) LookupComposePageByNamespaceIDModuleID(ctx context.Context, namespaceID uint64, moduleID uint64) (_ *composeType.Page, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposePage)
+ lookup = composePageSelectQuery(s.config.Dialect).Where(
+ goqu.I("rel_namespace").Eq(namespaceID),
+ goqu.I("rel_module").Eq(moduleID),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupComposePageByID searches for compose page by ID
+//
+// It returns compose page even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupComposePageByID(ctx context.Context, id uint64) (_ *composeType.Page, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposePage)
+ lookup = composePageSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposePageFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposePageFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectComposePageCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposePageCursorValues(res *composeType.Page, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposePageConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposePageConstraints(ctx context.Context, res *composeType.Page) (err error) {
+ return nil
+}
+
+// CreateComposeRecord creates one or more rows in composeRecord collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) (err error) {
+ for i := range rr {
+ if err = s.checkComposeRecordConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeRecordInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeRecord updates one or more existing entries in composeRecord collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) (err error) {
+ for i := range rr {
+ if err = s.checkComposeRecordConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeRecordUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeRecord updates one or more existing entries in composeRecord collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) (err error) {
+ for i := range rr {
+ if err = s.checkComposeRecordConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeRecordUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeRecord Deletes one or more entries from composeRecord collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeRecordDeleteQuery(s.config.Dialect, composeRecordPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeRecordByID deletes single entry from composeRecord collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeRecordByID(ctx context.Context, mod *composeType.Module, id uint64) error {
+ return s.Exec(ctx, composeRecordDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateComposeRecords Deletes all rows from the composeRecord collection
+func (s Store) TruncateComposeRecords(ctx context.Context, mod *composeType.Module) error {
+ return s.Exec(ctx, composeRecordTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeRecords returns (filtered) set of ComposeRecords
+//
+// This function is auto-generated
+func (s Store) SearchComposeRecords(ctx context.Context, mod *composeType.Module, f composeType.RecordFilter) (set composeType.RecordSet, _ composeType.RecordFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfComposeRecords fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeRecords(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfComposeRecords collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfComposeRecords(
+ ctx context.Context,
+ filter composeType.RecordFilter,
+) (set []*composeType.Record, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*composeType.Record
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter composeType.RecordFilter
+ )
+
+ set = make([]*composeType.Record, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryComposeRecords(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectComposeRecordCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectComposeRecordCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectComposeRecordCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryComposeRecords queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeRecords(
+ ctx context.Context,
+ f composeType.RecordFilter,
+) (_ []*composeType.Record, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*composeType.Record, 0, DefaultSliceCapacity)
+ res *composeType.Record
+ aux auxComposeRecord
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ComposeRecord != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeRecord(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeRecordFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeRecord: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := composeRecordSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableComposeRecordFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ComposeRecord: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeRecord: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeRecord: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeRecord: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeRecord: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeRecord: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupComposeRecordByID searches for compose record by ID
+//
+// It returns compose record even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupComposeRecordByID(ctx context.Context, mod *composeType.Module, id uint64) (_ *composeType.Record, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxComposeRecord)
+ lookup = composeRecordSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableComposeRecordFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeRecordFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectComposeRecordCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeRecordCursorValues(res *composeType.Record, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeRecordConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeRecordConstraints(ctx context.Context, res *composeType.Record) (err error) {
+ return nil
+}
+
+// CreateComposeRecordValue creates one or more rows in composeRecordValue collection
+//
+// This function is auto-generated
+func (s Store) CreateComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) (err error) {
+ for i := range rr {
+ if err = s.checkComposeRecordValueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeRecordValueInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateComposeRecordValue updates one or more existing entries in composeRecordValue collection
+//
+// This function is auto-generated
+func (s Store) UpdateComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) (err error) {
+ for i := range rr {
+ if err = s.checkComposeRecordValueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeRecordValueUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertComposeRecordValue updates one or more existing entries in composeRecordValue collection
+//
+// This function is auto-generated
+func (s Store) UpsertComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) (err error) {
+ for i := range rr {
+ if err = s.checkComposeRecordValueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, composeRecordValueUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteComposeRecordValue Deletes one or more entries from composeRecordValue collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, composeRecordValueDeleteQuery(s.config.Dialect, composeRecordValuePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteComposeRecordValueByID deletes single entry from composeRecordValue collection
+//
+// This function is auto-generated
+func (s Store) DeleteComposeRecordValueByRecordIDNamePlace(ctx context.Context, recordID uint64, name string, place uint) error {
+ return s.Exec(ctx, composeRecordValueDeleteQuery(s.config.Dialect, goqu.Ex{
+ "record_id": recordID,
+ "name": name,
+ "place": place,
+ }))
+}
+
+// TruncateComposeRecordValues Deletes all rows from the composeRecordValue collection
+func (s Store) TruncateComposeRecordValues(ctx context.Context) error {
+ return s.Exec(ctx, composeRecordValueTruncateQuery(s.config.Dialect))
+}
+
+// SearchComposeRecordValues returns (filtered) set of ComposeRecordValues
+//
+// This function is auto-generated
+func (s Store) SearchComposeRecordValues(ctx context.Context, f composeType.RecordValueFilter) (set composeType.RecordValueSet, _ composeType.RecordValueFilter, err error) {
+
+ set, _, err = s.QueryComposeRecordValues(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryComposeRecordValues queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryComposeRecordValues(
+ ctx context.Context,
+ f composeType.RecordValueFilter,
+) (_ []*composeType.RecordValue, more bool, err error) {
+ var (
+ set = make([]*composeType.RecordValue, 0, DefaultSliceCapacity)
+ res *composeType.RecordValue
+ aux auxComposeRecordValue
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.ComposeRecordValue != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ComposeRecordValue(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ComposeRecordValueFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ComposeRecordValue: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := composeRecordValueSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ComposeRecordValue: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeRecordValue: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ComposeRecordValue: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ComposeRecordValue: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ComposeRecordValue: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// sortableComposeRecordValueFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableComposeRecordValueFields() map[string]string {
+ return map[string]string{
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "name": "name",
+ "place": "place",
+ "record_id": "record_id",
+ "recordid": "record_id",
+ }
+}
+
+// collectComposeRecordValueCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectComposeRecordValueCursorValues(res *composeType.RecordValue, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkRecordID bool
+ pkName bool
+ pkPlace bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "recordID":
+ cur.Set(c.Column, res.RecordID, c.Descending)
+ pkRecordID = true
+ case "name":
+ cur.Set(c.Column, res.Name, c.Descending)
+ pkName = true
+ case "place":
+ cur.Set(c.Column, res.Place, c.Descending)
+ pkPlace = true
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkRecordID {
+ collect(&filter.SortExpr{Column: "recordID", Descending: false})
+ }
+ if !hasUnique || !pkName {
+ collect(&filter.SortExpr{Column: "name", Descending: false})
+ }
+ if !hasUnique || !pkPlace {
+ collect(&filter.SortExpr{Column: "place", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkComposeRecordValueConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkComposeRecordValueConstraints(ctx context.Context, res *composeType.RecordValue) (err error) {
+ return nil
+}
+
+// CreateCredential creates one or more rows in credential collection
+//
+// This function is auto-generated
+func (s Store) CreateCredential(ctx context.Context, rr ...*systemType.Credential) (err error) {
+ for i := range rr {
+ if err = s.checkCredentialConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, credentialInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateCredential updates one or more existing entries in credential collection
+//
+// This function is auto-generated
+func (s Store) UpdateCredential(ctx context.Context, rr ...*systemType.Credential) (err error) {
+ for i := range rr {
+ if err = s.checkCredentialConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, credentialUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertCredential updates one or more existing entries in credential collection
+//
+// This function is auto-generated
+func (s Store) UpsertCredential(ctx context.Context, rr ...*systemType.Credential) (err error) {
+ for i := range rr {
+ if err = s.checkCredentialConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, credentialUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteCredential Deletes one or more entries from credential collection
+//
+// This function is auto-generated
+func (s Store) DeleteCredential(ctx context.Context, rr ...*systemType.Credential) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, credentialDeleteQuery(s.config.Dialect, credentialPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteCredentialByID deletes single entry from credential collection
+//
+// This function is auto-generated
+func (s Store) DeleteCredentialByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, credentialDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateCredentials Deletes all rows from the credential collection
+func (s Store) TruncateCredentials(ctx context.Context) error {
+ return s.Exec(ctx, credentialTruncateQuery(s.config.Dialect))
+}
+
+// SearchCredentials returns (filtered) set of Credentials
+//
+// This function is auto-generated
+func (s Store) SearchCredentials(ctx context.Context, f systemType.CredentialFilter) (set systemType.CredentialSet, _ systemType.CredentialFilter, err error) {
+
+ set, _, err = s.QueryCredentials(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryCredentials queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryCredentials(
+ ctx context.Context,
+ f systemType.CredentialFilter,
+) (_ []*systemType.Credential, more bool, err error) {
+ var (
+ set = make([]*systemType.Credential, 0, DefaultSliceCapacity)
+ res *systemType.Credential
+ aux auxCredential
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.Credential != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Credential(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = CredentialFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Credential: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := credentialSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Credential: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Credential: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Credential: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Credential: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Credential: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupCredentialByID searches for credentials by ID
+//
+// It returns credentials even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupCredentialByID(ctx context.Context, id uint64) (_ *systemType.Credential, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxCredential)
+ lookup = credentialSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableCredentialFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableCredentialFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "expires_at": "expires_at",
+ "expiresat": "expires_at",
+ "id": "id",
+ "last_used_at": "last_used_at",
+ "lastusedat": "last_used_at",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectCredentialCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectCredentialCursorValues(res *systemType.Credential, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ case "lastUsedAt":
+ cur.Set(c.Column, res.LastUsedAt, c.Descending)
+ case "expiresAt":
+ cur.Set(c.Column, res.ExpiresAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkCredentialConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkCredentialConstraints(ctx context.Context, res *systemType.Credential) (err error) {
+ return nil
+}
+
+// CreateFederationExposedModule creates one or more rows in federationExposedModule collection
+//
+// This function is auto-generated
+func (s Store) CreateFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) (err error) {
+ for i := range rr {
+ if err = s.checkFederationExposedModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationExposedModuleInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateFederationExposedModule updates one or more existing entries in federationExposedModule collection
+//
+// This function is auto-generated
+func (s Store) UpdateFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) (err error) {
+ for i := range rr {
+ if err = s.checkFederationExposedModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationExposedModuleUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertFederationExposedModule updates one or more existing entries in federationExposedModule collection
+//
+// This function is auto-generated
+func (s Store) UpsertFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) (err error) {
+ for i := range rr {
+ if err = s.checkFederationExposedModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationExposedModuleUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteFederationExposedModule Deletes one or more entries from federationExposedModule collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, federationExposedModuleDeleteQuery(s.config.Dialect, federationExposedModulePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteFederationExposedModuleByID deletes single entry from federationExposedModule collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationExposedModuleByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, federationExposedModuleDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateFederationExposedModules Deletes all rows from the federationExposedModule collection
+func (s Store) TruncateFederationExposedModules(ctx context.Context) error {
+ return s.Exec(ctx, federationExposedModuleTruncateQuery(s.config.Dialect))
+}
+
+// SearchFederationExposedModules returns (filtered) set of FederationExposedModules
+//
+// This function is auto-generated
+func (s Store) SearchFederationExposedModules(ctx context.Context, f federationType.ExposedModuleFilter) (set federationType.ExposedModuleSet, _ federationType.ExposedModuleFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfFederationExposedModules fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationExposedModules(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfFederationExposedModules collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfFederationExposedModules(
+ ctx context.Context,
+ filter federationType.ExposedModuleFilter,
+) (set []*federationType.ExposedModule, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*federationType.ExposedModule
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter federationType.ExposedModuleFilter
+ )
+
+ set = make([]*federationType.ExposedModule, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryFederationExposedModules(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectFederationExposedModuleCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectFederationExposedModuleCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectFederationExposedModuleCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryFederationExposedModules queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryFederationExposedModules(
+ ctx context.Context,
+ f federationType.ExposedModuleFilter,
+) (_ []*federationType.ExposedModule, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*federationType.ExposedModule, 0, DefaultSliceCapacity)
+ res *federationType.ExposedModule
+ aux auxFederationExposedModule
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.FederationExposedModule != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.FederationExposedModule(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = FederationExposedModuleFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for FederationExposedModule: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := federationExposedModuleSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableFederationExposedModuleFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for FederationExposedModule: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query FederationExposedModule: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationExposedModule: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationExposedModule: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for FederationExposedModule: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode FederationExposedModule: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupFederationExposedModuleByID searches for federation module by ID
+//
+// It returns federation module
+//
+// This function is auto-generated
+func (s Store) LookupFederationExposedModuleByID(ctx context.Context, id uint64) (_ *federationType.ExposedModule, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationExposedModule)
+ lookup = federationExposedModuleSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableFederationExposedModuleFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableFederationExposedModuleFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectFederationExposedModuleCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectFederationExposedModuleCursorValues(res *federationType.ExposedModule, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkFederationExposedModuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkFederationExposedModuleConstraints(ctx context.Context, res *federationType.ExposedModule) (err error) {
+ return nil
+}
+
+// CreateFederationModuleMapping creates one or more rows in federationModuleMapping collection
+//
+// This function is auto-generated
+func (s Store) CreateFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) (err error) {
+ for i := range rr {
+ if err = s.checkFederationModuleMappingConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationModuleMappingInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateFederationModuleMapping updates one or more existing entries in federationModuleMapping collection
+//
+// This function is auto-generated
+func (s Store) UpdateFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) (err error) {
+ for i := range rr {
+ if err = s.checkFederationModuleMappingConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationModuleMappingUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertFederationModuleMapping updates one or more existing entries in federationModuleMapping collection
+//
+// This function is auto-generated
+func (s Store) UpsertFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) (err error) {
+ for i := range rr {
+ if err = s.checkFederationModuleMappingConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationModuleMappingUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteFederationModuleMapping Deletes one or more entries from federationModuleMapping collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, federationModuleMappingDeleteQuery(s.config.Dialect, federationModuleMappingPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteFederationModuleMappingByID deletes single entry from federationModuleMapping collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationModuleMappingBy(ctx context.Context) error {
+ return s.Exec(ctx, federationModuleMappingDeleteQuery(s.config.Dialect, goqu.Ex{}))
+}
+
+// TruncateFederationModuleMappings Deletes all rows from the federationModuleMapping collection
+func (s Store) TruncateFederationModuleMappings(ctx context.Context) error {
+ return s.Exec(ctx, federationModuleMappingTruncateQuery(s.config.Dialect))
+}
+
+// SearchFederationModuleMappings returns (filtered) set of FederationModuleMappings
+//
+// This function is auto-generated
+func (s Store) SearchFederationModuleMappings(ctx context.Context, f federationType.ModuleMappingFilter) (set federationType.ModuleMappingSet, _ federationType.ModuleMappingFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfFederationModuleMappings fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationModuleMappings(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfFederationModuleMappings collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfFederationModuleMappings(
+ ctx context.Context,
+ filter federationType.ModuleMappingFilter,
+) (set []*federationType.ModuleMapping, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*federationType.ModuleMapping
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter federationType.ModuleMappingFilter
+ )
+
+ set = make([]*federationType.ModuleMapping, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryFederationModuleMappings(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectFederationModuleMappingCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectFederationModuleMappingCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectFederationModuleMappingCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryFederationModuleMappings queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryFederationModuleMappings(
+ ctx context.Context,
+ f federationType.ModuleMappingFilter,
+) (_ []*federationType.ModuleMapping, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*federationType.ModuleMapping, 0, DefaultSliceCapacity)
+ res *federationType.ModuleMapping
+ aux auxFederationModuleMapping
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.FederationModuleMapping != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.FederationModuleMapping(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = FederationModuleMappingFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for FederationModuleMapping: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := federationModuleMappingSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableFederationModuleMappingFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for FederationModuleMapping: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query FederationModuleMapping: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationModuleMapping: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationModuleMapping: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for FederationModuleMapping: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode FederationModuleMapping: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID searches for module mapping by federation module id and compose module id
+//
+// It returns module mapping
+//
+// This function is auto-generated
+func (s Store) LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, federationModuleID uint64, composeModuleID uint64, composeNamespaceID uint64) (_ *federationType.ModuleMapping, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationModuleMapping)
+ lookup = federationModuleMappingSelectQuery(s.config.Dialect).Where(
+ goqu.I("federation_module_id").Eq(federationModuleID),
+ goqu.I("compose_module_id").Eq(composeModuleID),
+ goqu.I("compose_namespace_id").Eq(composeNamespaceID),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupFederationModuleMappingByFederationModuleID searches for module mapping by federation module id
+//
+// It returns module mapping
+//
+// This function is auto-generated
+func (s Store) LookupFederationModuleMappingByFederationModuleID(ctx context.Context, federationModuleID uint64) (_ *federationType.ModuleMapping, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationModuleMapping)
+ lookup = federationModuleMappingSelectQuery(s.config.Dialect).Where(
+ goqu.I("federation_module_id").Eq(federationModuleID),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableFederationModuleMappingFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableFederationModuleMappingFields() map[string]string {
+ return map[string]string{}
+}
+
+// collectFederationModuleMappingCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectFederationModuleMappingCursorValues(res *federationType.ModuleMapping, cc ...*filter.SortExpr) *filter.PagingCursor {
+ return nil
+}
+
+// checkFederationModuleMappingConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkFederationModuleMappingConstraints(ctx context.Context, res *federationType.ModuleMapping) (err error) {
+ return nil
+}
+
+// CreateFederationNode creates one or more rows in federationNode collection
+//
+// This function is auto-generated
+func (s Store) CreateFederationNode(ctx context.Context, rr ...*federationType.Node) (err error) {
+ for i := range rr {
+ if err = s.checkFederationNodeConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationNodeInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateFederationNode updates one or more existing entries in federationNode collection
+//
+// This function is auto-generated
+func (s Store) UpdateFederationNode(ctx context.Context, rr ...*federationType.Node) (err error) {
+ for i := range rr {
+ if err = s.checkFederationNodeConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationNodeUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertFederationNode updates one or more existing entries in federationNode collection
+//
+// This function is auto-generated
+func (s Store) UpsertFederationNode(ctx context.Context, rr ...*federationType.Node) (err error) {
+ for i := range rr {
+ if err = s.checkFederationNodeConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationNodeUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteFederationNode Deletes one or more entries from federationNode collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationNode(ctx context.Context, rr ...*federationType.Node) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, federationNodeDeleteQuery(s.config.Dialect, federationNodePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteFederationNodeByID deletes single entry from federationNode collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationNodeByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, federationNodeDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateFederationNodes Deletes all rows from the federationNode collection
+func (s Store) TruncateFederationNodes(ctx context.Context) error {
+ return s.Exec(ctx, federationNodeTruncateQuery(s.config.Dialect))
+}
+
+// SearchFederationNodes returns (filtered) set of FederationNodes
+//
+// This function is auto-generated
+func (s Store) SearchFederationNodes(ctx context.Context, f federationType.NodeFilter) (set federationType.NodeSet, _ federationType.NodeFilter, err error) {
+
+ set, _, err = s.QueryFederationNodes(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryFederationNodes queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryFederationNodes(
+ ctx context.Context,
+ f federationType.NodeFilter,
+) (_ []*federationType.Node, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*federationType.Node, 0, DefaultSliceCapacity)
+ res *federationType.Node
+ aux auxFederationNode
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.FederationNode != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.FederationNode(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = FederationNodeFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for FederationNode: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := federationNodeSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query FederationNode: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationNode: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationNode: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for FederationNode: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode FederationNode: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupFederationNodeByID searches for federation node by ID
+//
+// It returns federation node
+//
+// This function is auto-generated
+func (s Store) LookupFederationNodeByID(ctx context.Context, id uint64) (_ *federationType.Node, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationNode)
+ lookup = federationNodeSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupFederationNodeByBaseURLSharedNodeID searches for node by shared-node-id and base-url
+//
+// This function is auto-generated
+func (s Store) LookupFederationNodeByBaseURLSharedNodeID(ctx context.Context, baseURL string, sharedNodeID uint64) (_ *federationType.Node, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationNode)
+ lookup = federationNodeSelectQuery(s.config.Dialect).Where(
+ goqu.I("base_url").Eq(baseURL),
+ goqu.I("shared_node_id").Eq(sharedNodeID),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupFederationNodeBySharedNodeID searches for node by shared-node-id
+//
+// This function is auto-generated
+func (s Store) LookupFederationNodeBySharedNodeID(ctx context.Context, sharedNodeID uint64) (_ *federationType.Node, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationNode)
+ lookup = federationNodeSelectQuery(s.config.Dialect).Where(
+ goqu.I("shared_node_id").Eq(sharedNodeID),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableFederationNodeFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableFederationNodeFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectFederationNodeCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectFederationNodeCursorValues(res *federationType.Node, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkFederationNodeConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkFederationNodeConstraints(ctx context.Context, res *federationType.Node) (err error) {
+ return nil
+}
+
+// CreateFederationNodeSync creates one or more rows in federationNodeSync collection
+//
+// This function is auto-generated
+func (s Store) CreateFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) (err error) {
+ for i := range rr {
+ if err = s.checkFederationNodeSyncConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationNodeSyncInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateFederationNodeSync updates one or more existing entries in federationNodeSync collection
+//
+// This function is auto-generated
+func (s Store) UpdateFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) (err error) {
+ for i := range rr {
+ if err = s.checkFederationNodeSyncConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationNodeSyncUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertFederationNodeSync updates one or more existing entries in federationNodeSync collection
+//
+// This function is auto-generated
+func (s Store) UpsertFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) (err error) {
+ for i := range rr {
+ if err = s.checkFederationNodeSyncConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationNodeSyncUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteFederationNodeSync Deletes one or more entries from federationNodeSync collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, federationNodeSyncDeleteQuery(s.config.Dialect, federationNodeSyncPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteFederationNodeSyncByID deletes single entry from federationNodeSync collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationNodeSyncByNodeID(ctx context.Context, nodeID uint64) error {
+ return s.Exec(ctx, federationNodeSyncDeleteQuery(s.config.Dialect, goqu.Ex{
+ "node_id": nodeID,
+ }))
+}
+
+// TruncateFederationNodeSyncs Deletes all rows from the federationNodeSync collection
+func (s Store) TruncateFederationNodeSyncs(ctx context.Context) error {
+ return s.Exec(ctx, federationNodeSyncTruncateQuery(s.config.Dialect))
+}
+
+// SearchFederationNodeSyncs returns (filtered) set of FederationNodeSyncs
+//
+// This function is auto-generated
+func (s Store) SearchFederationNodeSyncs(ctx context.Context, f federationType.NodeSyncFilter) (set federationType.NodeSyncSet, _ federationType.NodeSyncFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfFederationNodeSyncs fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationNodeSyncs(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfFederationNodeSyncs collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfFederationNodeSyncs(
+ ctx context.Context,
+ filter federationType.NodeSyncFilter,
+) (set []*federationType.NodeSync, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*federationType.NodeSync
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter federationType.NodeSyncFilter
+ )
+
+ set = make([]*federationType.NodeSync, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryFederationNodeSyncs(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectFederationNodeSyncCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectFederationNodeSyncCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectFederationNodeSyncCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryFederationNodeSyncs queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryFederationNodeSyncs(
+ ctx context.Context,
+ f federationType.NodeSyncFilter,
+) (_ []*federationType.NodeSync, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*federationType.NodeSync, 0, DefaultSliceCapacity)
+ res *federationType.NodeSync
+ aux auxFederationNodeSync
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.FederationNodeSync != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.FederationNodeSync(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = FederationNodeSyncFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for FederationNodeSync: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := federationNodeSyncSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableFederationNodeSyncFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for FederationNodeSync: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query FederationNodeSync: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationNodeSync: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationNodeSync: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for FederationNodeSync: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode FederationNodeSync: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupFederationNodeSyncByNodeID searches for sync activity by node ID
+//
+// It returns sync activity
+//
+// This function is auto-generated
+func (s Store) LookupFederationNodeSyncByNodeID(ctx context.Context, nodeID uint64) (_ *federationType.NodeSync, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationNodeSync)
+ lookup = federationNodeSyncSelectQuery(s.config.Dialect).Where(
+ goqu.I("node_id").Eq(nodeID),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupFederationNodeSyncByNodeIDModuleIDSyncTypeSyncStatus searches for activity by node, type and status
+//
+// It returns sync activity
+//
+// This function is auto-generated
+func (s Store) LookupFederationNodeSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx context.Context, nodeID uint64, moduleID uint64, syncType string, syncStatus string) (_ *federationType.NodeSync, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationNodeSync)
+ lookup = federationNodeSyncSelectQuery(s.config.Dialect).Where(
+ goqu.I("node_id").Eq(nodeID),
+ goqu.I("module_id").Eq(moduleID),
+ goqu.I("sync_type").Eq(syncType),
+ goqu.I("sync_status").Eq(syncStatus),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableFederationNodeSyncFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableFederationNodeSyncFields() map[string]string {
+ return map[string]string{
+ "node_id": "node_id",
+ "nodeid": "node_id",
+ "time_of_action": "time_of_action",
+ "timeofaction": "time_of_action",
+ }
+}
+
+// collectFederationNodeSyncCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectFederationNodeSyncCursorValues(res *federationType.NodeSync, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkNodeID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "nodeID":
+ cur.Set(c.Column, res.NodeID, c.Descending)
+ pkNodeID = true
+ case "timeOfAction":
+ cur.Set(c.Column, res.TimeOfAction, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkNodeID {
+ collect(&filter.SortExpr{Column: "nodeID", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkFederationNodeSyncConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkFederationNodeSyncConstraints(ctx context.Context, res *federationType.NodeSync) (err error) {
+ return nil
+}
+
+// CreateFederationSharedModule creates one or more rows in federationSharedModule collection
+//
+// This function is auto-generated
+func (s Store) CreateFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) (err error) {
+ for i := range rr {
+ if err = s.checkFederationSharedModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationSharedModuleInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateFederationSharedModule updates one or more existing entries in federationSharedModule collection
+//
+// This function is auto-generated
+func (s Store) UpdateFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) (err error) {
+ for i := range rr {
+ if err = s.checkFederationSharedModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationSharedModuleUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertFederationSharedModule updates one or more existing entries in federationSharedModule collection
+//
+// This function is auto-generated
+func (s Store) UpsertFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) (err error) {
+ for i := range rr {
+ if err = s.checkFederationSharedModuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, federationSharedModuleUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteFederationSharedModule Deletes one or more entries from federationSharedModule collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, federationSharedModuleDeleteQuery(s.config.Dialect, federationSharedModulePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteFederationSharedModuleByID deletes single entry from federationSharedModule collection
+//
+// This function is auto-generated
+func (s Store) DeleteFederationSharedModuleByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, federationSharedModuleDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateFederationSharedModules Deletes all rows from the federationSharedModule collection
+func (s Store) TruncateFederationSharedModules(ctx context.Context) error {
+ return s.Exec(ctx, federationSharedModuleTruncateQuery(s.config.Dialect))
+}
+
+// SearchFederationSharedModules returns (filtered) set of FederationSharedModules
+//
+// This function is auto-generated
+func (s Store) SearchFederationSharedModules(ctx context.Context, f federationType.SharedModuleFilter) (set federationType.SharedModuleSet, _ federationType.SharedModuleFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfFederationSharedModules fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationSharedModules(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfFederationSharedModules collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfFederationSharedModules(
+ ctx context.Context,
+ filter federationType.SharedModuleFilter,
+) (set []*federationType.SharedModule, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*federationType.SharedModule
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter federationType.SharedModuleFilter
+ )
+
+ set = make([]*federationType.SharedModule, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryFederationSharedModules(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectFederationSharedModuleCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectFederationSharedModuleCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectFederationSharedModuleCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryFederationSharedModules queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryFederationSharedModules(
+ ctx context.Context,
+ f federationType.SharedModuleFilter,
+) (_ []*federationType.SharedModule, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*federationType.SharedModule, 0, DefaultSliceCapacity)
+ res *federationType.SharedModule
+ aux auxFederationSharedModule
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.FederationSharedModule != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.FederationSharedModule(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = FederationSharedModuleFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for FederationSharedModule: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := federationSharedModuleSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableFederationSharedModuleFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for FederationSharedModule: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query FederationSharedModule: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationSharedModule: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query FederationSharedModule: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for FederationSharedModule: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode FederationSharedModule: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupFederationSharedModuleByID searches for shared federation module by ID
+//
+// It returns shared federation module
+//
+// This function is auto-generated
+func (s Store) LookupFederationSharedModuleByID(ctx context.Context, id uint64) (_ *federationType.SharedModule, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFederationSharedModule)
+ lookup = federationSharedModuleSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableFederationSharedModuleFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableFederationSharedModuleFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectFederationSharedModuleCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectFederationSharedModuleCursorValues(res *federationType.SharedModule, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkFederationSharedModuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkFederationSharedModuleConstraints(ctx context.Context, res *federationType.SharedModule) (err error) {
+ return nil
+}
+
+// CreateFlag creates one or more rows in flag collection
+//
+// This function is auto-generated
+func (s Store) CreateFlag(ctx context.Context, rr ...*flagType.Flag) (err error) {
+ for i := range rr {
+ if err = s.checkFlagConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, flagInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateFlag updates one or more existing entries in flag collection
+//
+// This function is auto-generated
+func (s Store) UpdateFlag(ctx context.Context, rr ...*flagType.Flag) (err error) {
+ for i := range rr {
+ if err = s.checkFlagConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, flagUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertFlag updates one or more existing entries in flag collection
+//
+// This function is auto-generated
+func (s Store) UpsertFlag(ctx context.Context, rr ...*flagType.Flag) (err error) {
+ for i := range rr {
+ if err = s.checkFlagConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, flagUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteFlag Deletes one or more entries from flag collection
+//
+// This function is auto-generated
+func (s Store) DeleteFlag(ctx context.Context, rr ...*flagType.Flag) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, flagDeleteQuery(s.config.Dialect, flagPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteFlagByID deletes single entry from flag collection
+//
+// This function is auto-generated
+func (s Store) DeleteFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resourceID uint64, ownedBy uint64, name string) error {
+ return s.Exec(ctx, flagDeleteQuery(s.config.Dialect, goqu.Ex{
+ "kind": kind,
+ "rel_resource": resourceID,
+ "owned_by": ownedBy,
+ "name": name,
+ }))
+}
+
+// TruncateFlags Deletes all rows from the flag collection
+func (s Store) TruncateFlags(ctx context.Context) error {
+ return s.Exec(ctx, flagTruncateQuery(s.config.Dialect))
+}
+
+// SearchFlags returns (filtered) set of Flags
+//
+// This function is auto-generated
+func (s Store) SearchFlags(ctx context.Context, f flagType.FlagFilter) (set flagType.FlagSet, _ flagType.FlagFilter, err error) {
+
+ set, _, err = s.QueryFlags(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryFlags queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryFlags(
+ ctx context.Context,
+ f flagType.FlagFilter,
+) (_ []*flagType.Flag, more bool, err error) {
+ var (
+ set = make([]*flagType.Flag, 0, DefaultSliceCapacity)
+ res *flagType.Flag
+ aux auxFlag
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.Flag != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Flag(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = FlagFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Flag: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := flagSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Flag: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Flag: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Flag: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Flag: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Flag: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupFlagByKindResourceIDOwnedByName searches for flag by kind, resource ID, owner and name
+//
+// This function is auto-generated
+func (s Store) LookupFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resourceID uint64, ownedBy uint64, name string) (_ *flagType.Flag, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxFlag)
+ lookup = flagSelectQuery(s.config.Dialect).Where(
+ goqu.I("kind").Eq(kind),
+ goqu.I("rel_resource").Eq(resourceID),
+ goqu.I("owned_by").Eq(ownedBy),
+ s.config.Functions.LOWER(goqu.I("name")).Eq(strings.ToLower(name)),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableFlagFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableFlagFields() map[string]string {
+ return map[string]string{
+ "kind": "kind",
+ "name": "name",
+ "owned_by": "owned_by",
+ "ownedby": "owned_by",
+ "resource_id": "resource_id",
+ "resourceid": "resource_id",
+ }
+}
+
+// collectFlagCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectFlagCursorValues(res *flagType.Flag, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkKind bool
+ pkResourceID bool
+ pkOwnedBy bool
+ pkName bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "kind":
+ cur.Set(c.Column, res.Kind, c.Descending)
+ pkKind = true
+ case "resourceID":
+ cur.Set(c.Column, res.ResourceID, c.Descending)
+ pkResourceID = true
+ case "ownedBy":
+ cur.Set(c.Column, res.OwnedBy, c.Descending)
+ pkOwnedBy = true
+ case "name":
+ cur.Set(c.Column, res.Name, c.Descending)
+ pkName = true
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkKind {
+ collect(&filter.SortExpr{Column: "kind", Descending: false})
+ }
+ if !hasUnique || !pkResourceID {
+ collect(&filter.SortExpr{Column: "resourceID", Descending: false})
+ }
+ if !hasUnique || !pkOwnedBy {
+ collect(&filter.SortExpr{Column: "ownedBy", Descending: false})
+ }
+ if !hasUnique || !pkName {
+ collect(&filter.SortExpr{Column: "name", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkFlagConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkFlagConstraints(ctx context.Context, res *flagType.Flag) (err error) {
+ return nil
+}
+
+// CreateLabel creates one or more rows in label collection
+//
+// This function is auto-generated
+func (s Store) CreateLabel(ctx context.Context, rr ...*labelsType.Label) (err error) {
+ for i := range rr {
+ if err = s.checkLabelConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, labelInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateLabel updates one or more existing entries in label collection
+//
+// This function is auto-generated
+func (s Store) UpdateLabel(ctx context.Context, rr ...*labelsType.Label) (err error) {
+ for i := range rr {
+ if err = s.checkLabelConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, labelUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertLabel updates one or more existing entries in label collection
+//
+// This function is auto-generated
+func (s Store) UpsertLabel(ctx context.Context, rr ...*labelsType.Label) (err error) {
+ for i := range rr {
+ if err = s.checkLabelConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, labelUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteLabel Deletes one or more entries from label collection
+//
+// This function is auto-generated
+func (s Store) DeleteLabel(ctx context.Context, rr ...*labelsType.Label) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, labelDeleteQuery(s.config.Dialect, labelPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteLabelByID deletes single entry from label collection
+//
+// This function is auto-generated
+func (s Store) DeleteLabelByKindResourceIDName(ctx context.Context, kind string, resourceID uint64, name string) error {
+ return s.Exec(ctx, labelDeleteQuery(s.config.Dialect, goqu.Ex{
+ "kind": kind,
+ "rel_resource": resourceID,
+ "name": name,
+ }))
+}
+
+// TruncateLabels Deletes all rows from the label collection
+func (s Store) TruncateLabels(ctx context.Context) error {
+ return s.Exec(ctx, labelTruncateQuery(s.config.Dialect))
+}
+
+// SearchLabels returns (filtered) set of Labels
+//
+// This function is auto-generated
+func (s Store) SearchLabels(ctx context.Context, f labelsType.LabelFilter) (set labelsType.LabelSet, _ labelsType.LabelFilter, err error) {
+
+ set, _, err = s.QueryLabels(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryLabels queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryLabels(
+ ctx context.Context,
+ f labelsType.LabelFilter,
+) (_ []*labelsType.Label, more bool, err error) {
+ var (
+ set = make([]*labelsType.Label, 0, DefaultSliceCapacity)
+ res *labelsType.Label
+ aux auxLabel
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.Label != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Label(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = LabelFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Label: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := labelSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Label: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Label: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Label: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Label: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Label: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupLabelByKindResourceIDName searches for label by kind, resource ID and name
+//
+// This function is auto-generated
+func (s Store) LookupLabelByKindResourceIDName(ctx context.Context, kind string, resourceID uint64, name string) (_ *labelsType.Label, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxLabel)
+ lookup = labelSelectQuery(s.config.Dialect).Where(
+ goqu.I("kind").Eq(kind),
+ goqu.I("rel_resource").Eq(resourceID),
+ s.config.Functions.LOWER(goqu.I("name")).Eq(strings.ToLower(name)),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableLabelFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableLabelFields() map[string]string {
+ return map[string]string{
+ "kind": "kind",
+ "name": "name",
+ "resource_id": "resource_id",
+ "resourceid": "resource_id",
+ }
+}
+
+// collectLabelCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectLabelCursorValues(res *labelsType.Label, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkKind bool
+ pkResourceID bool
+ pkName bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "kind":
+ cur.Set(c.Column, res.Kind, c.Descending)
+ pkKind = true
+ case "resourceID":
+ cur.Set(c.Column, res.ResourceID, c.Descending)
+ pkResourceID = true
+ case "name":
+ cur.Set(c.Column, res.Name, c.Descending)
+ pkName = true
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkKind {
+ collect(&filter.SortExpr{Column: "kind", Descending: false})
+ }
+ if !hasUnique || !pkResourceID {
+ collect(&filter.SortExpr{Column: "resourceID", Descending: false})
+ }
+ if !hasUnique || !pkName {
+ collect(&filter.SortExpr{Column: "name", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkLabelConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkLabelConstraints(ctx context.Context, res *labelsType.Label) (err error) {
+ return nil
+}
+
+// CreateQueue creates one or more rows in queue collection
+//
+// This function is auto-generated
+func (s Store) CreateQueue(ctx context.Context, rr ...*systemType.Queue) (err error) {
+ for i := range rr {
+ if err = s.checkQueueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, queueInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateQueue updates one or more existing entries in queue collection
+//
+// This function is auto-generated
+func (s Store) UpdateQueue(ctx context.Context, rr ...*systemType.Queue) (err error) {
+ for i := range rr {
+ if err = s.checkQueueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, queueUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertQueue updates one or more existing entries in queue collection
+//
+// This function is auto-generated
+func (s Store) UpsertQueue(ctx context.Context, rr ...*systemType.Queue) (err error) {
+ for i := range rr {
+ if err = s.checkQueueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, queueUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteQueue Deletes one or more entries from queue collection
+//
+// This function is auto-generated
+func (s Store) DeleteQueue(ctx context.Context, rr ...*systemType.Queue) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, queueDeleteQuery(s.config.Dialect, queuePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteQueueByID deletes single entry from queue collection
+//
+// This function is auto-generated
+func (s Store) DeleteQueueByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, queueDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateQueues Deletes all rows from the queue collection
+func (s Store) TruncateQueues(ctx context.Context) error {
+ return s.Exec(ctx, queueTruncateQuery(s.config.Dialect))
+}
+
+// SearchQueues returns (filtered) set of Queues
+//
+// This function is auto-generated
+func (s Store) SearchQueues(ctx context.Context, f systemType.QueueFilter) (set systemType.QueueSet, _ systemType.QueueFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfQueues fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfQueues(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfQueues collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfQueues(
+ ctx context.Context,
+ filter systemType.QueueFilter,
+) (set []*systemType.Queue, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Queue
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.QueueFilter
+ )
+
+ set = make([]*systemType.Queue, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryQueues(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectQueueCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectQueueCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectQueueCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryQueues queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryQueues(
+ ctx context.Context,
+ f systemType.QueueFilter,
+) (_ []*systemType.Queue, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Queue, 0, DefaultSliceCapacity)
+ res *systemType.Queue
+ aux auxQueue
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Queue != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Queue(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = QueueFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Queue: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := queueSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableQueueFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Queue: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Queue: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Queue: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Queue: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Queue: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Queue: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupQueueByID searches for queue by ID
+//
+// This function is auto-generated
+func (s Store) LookupQueueByID(ctx context.Context, id uint64) (_ *systemType.Queue, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxQueue)
+ lookup = queueSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupQueueByQueue searches for queue by queue name
+//
+// This function is auto-generated
+func (s Store) LookupQueueByQueue(ctx context.Context, queue string) (_ *systemType.Queue, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxQueue)
+ lookup = queueSelectQuery(s.config.Dialect).Where(
+ goqu.I("queue").Eq(queue),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableQueueFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableQueueFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectQueueCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectQueueCursorValues(res *systemType.Queue, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkQueueConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkQueueConstraints(ctx context.Context, res *systemType.Queue) (err error) {
+ return nil
+}
+
+// CreateQueueMessage creates one or more rows in queueMessage collection
+//
+// This function is auto-generated
+func (s Store) CreateQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) (err error) {
+ for i := range rr {
+ if err = s.checkQueueMessageConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, queueMessageInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateQueueMessage updates one or more existing entries in queueMessage collection
+//
+// This function is auto-generated
+func (s Store) UpdateQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) (err error) {
+ for i := range rr {
+ if err = s.checkQueueMessageConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, queueMessageUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertQueueMessage updates one or more existing entries in queueMessage collection
+//
+// This function is auto-generated
+func (s Store) UpsertQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) (err error) {
+ for i := range rr {
+ if err = s.checkQueueMessageConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, queueMessageUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteQueueMessage Deletes one or more entries from queueMessage collection
+//
+// This function is auto-generated
+func (s Store) DeleteQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, queueMessageDeleteQuery(s.config.Dialect, queueMessagePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteQueueMessageByID deletes single entry from queueMessage collection
+//
+// This function is auto-generated
+func (s Store) DeleteQueueMessageByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, queueMessageDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateQueueMessages Deletes all rows from the queueMessage collection
+func (s Store) TruncateQueueMessages(ctx context.Context) error {
+ return s.Exec(ctx, queueMessageTruncateQuery(s.config.Dialect))
+}
+
+// SearchQueueMessages returns (filtered) set of QueueMessages
+//
+// This function is auto-generated
+func (s Store) SearchQueueMessages(ctx context.Context, f systemType.QueueMessageFilter) (set systemType.QueueMessageSet, _ systemType.QueueMessageFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfQueueMessages fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfQueueMessages(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfQueueMessages collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfQueueMessages(
+ ctx context.Context,
+ filter systemType.QueueMessageFilter,
+) (set []*systemType.QueueMessage, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.QueueMessage
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.QueueMessageFilter
+ )
+
+ set = make([]*systemType.QueueMessage, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryQueueMessages(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectQueueMessageCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectQueueMessageCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectQueueMessageCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryQueueMessages queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryQueueMessages(
+ ctx context.Context,
+ f systemType.QueueMessageFilter,
+) (_ []*systemType.QueueMessage, more bool, err error) {
+ var (
+ set = make([]*systemType.QueueMessage, 0, DefaultSliceCapacity)
+ res *systemType.QueueMessage
+ aux auxQueueMessage
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.QueueMessage != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.QueueMessage(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = QueueMessageFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for QueueMessage: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := queueMessageSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableQueueMessageFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for QueueMessage: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query QueueMessage: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query QueueMessage: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query QueueMessage: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for QueueMessage: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode QueueMessage: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// sortableQueueMessageFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableQueueMessageFields() map[string]string {
+ return map[string]string{
+ "created": "created",
+ "id": "id",
+ "processed": "processed",
+ }
+}
+
+// collectQueueMessageCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectQueueMessageCursorValues(res *systemType.QueueMessage, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "processed":
+ cur.Set(c.Column, res.Processed, c.Descending)
+ case "created":
+ cur.Set(c.Column, res.Created, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkQueueMessageConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkQueueMessageConstraints(ctx context.Context, res *systemType.QueueMessage) (err error) {
+ return nil
+}
+
+// CreateRbacRule creates one or more rows in rbacRule collection
+//
+// This function is auto-generated
+func (s Store) CreateRbacRule(ctx context.Context, rr ...*rbacType.Rule) (err error) {
+ for i := range rr {
+ if err = s.checkRbacRuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, rbacRuleInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateRbacRule updates one or more existing entries in rbacRule collection
+//
+// This function is auto-generated
+func (s Store) UpdateRbacRule(ctx context.Context, rr ...*rbacType.Rule) (err error) {
+ for i := range rr {
+ if err = s.checkRbacRuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, rbacRuleUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertRbacRule updates one or more existing entries in rbacRule collection
+//
+// This function is auto-generated
+func (s Store) UpsertRbacRule(ctx context.Context, rr ...*rbacType.Rule) (err error) {
+ for i := range rr {
+ if err = s.checkRbacRuleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, rbacRuleUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteRbacRule Deletes one or more entries from rbacRule collection
+//
+// This function is auto-generated
+func (s Store) DeleteRbacRule(ctx context.Context, rr ...*rbacType.Rule) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, rbacRuleDeleteQuery(s.config.Dialect, rbacRulePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteRbacRuleByID deletes single entry from rbacRule collection
+//
+// This function is auto-generated
+func (s Store) DeleteRbacRuleByRoleIDResourceOperation(ctx context.Context, roleID uint64, resource string, operation string) error {
+ return s.Exec(ctx, rbacRuleDeleteQuery(s.config.Dialect, goqu.Ex{
+ "rel_role": roleID,
+ "resource": resource,
+ "operation": operation,
+ }))
+}
+
+// TruncateRbacRules Deletes all rows from the rbacRule collection
+func (s Store) TruncateRbacRules(ctx context.Context) error {
+ return s.Exec(ctx, rbacRuleTruncateQuery(s.config.Dialect))
+}
+
+// SearchRbacRules returns (filtered) set of RbacRules
+//
+// This function is auto-generated
+func (s Store) SearchRbacRules(ctx context.Context, f rbacType.RuleFilter) (set rbacType.RuleSet, _ rbacType.RuleFilter, err error) {
+
+ set, _, err = s.QueryRbacRules(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryRbacRules queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryRbacRules(
+ ctx context.Context,
+ f rbacType.RuleFilter,
+) (_ []*rbacType.Rule, more bool, err error) {
+ var (
+ set = make([]*rbacType.Rule, 0, DefaultSliceCapacity)
+ res *rbacType.Rule
+ aux auxRbacRule
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.RbacRule != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.RbacRule(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = RbacRuleFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for RbacRule: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := rbacRuleSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query RbacRule: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query RbacRule: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query RbacRule: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for RbacRule: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode RbacRule: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// sortableRbacRuleFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableRbacRuleFields() map[string]string {
+ return map[string]string{
+ "operation": "operation",
+ "resource": "resource",
+ "role_id": "role_id",
+ "roleid": "role_id",
+ }
+}
+
+// collectRbacRuleCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectRbacRuleCursorValues(res *rbacType.Rule, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkRoleID bool
+ pkResource bool
+ pkOperation bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "roleID":
+ cur.Set(c.Column, res.RoleID, c.Descending)
+ pkRoleID = true
+ case "resource":
+ cur.Set(c.Column, res.Resource, c.Descending)
+ pkResource = true
+ case "operation":
+ cur.Set(c.Column, res.Operation, c.Descending)
+ pkOperation = true
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkRoleID {
+ collect(&filter.SortExpr{Column: "roleID", Descending: false})
+ }
+ if !hasUnique || !pkResource {
+ collect(&filter.SortExpr{Column: "resource", Descending: false})
+ }
+ if !hasUnique || !pkOperation {
+ collect(&filter.SortExpr{Column: "operation", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkRbacRuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkRbacRuleConstraints(ctx context.Context, res *rbacType.Rule) (err error) {
+ return nil
+}
+
+// CreateReminder creates one or more rows in reminder collection
+//
+// This function is auto-generated
+func (s Store) CreateReminder(ctx context.Context, rr ...*systemType.Reminder) (err error) {
+ for i := range rr {
+ if err = s.checkReminderConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, reminderInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateReminder updates one or more existing entries in reminder collection
+//
+// This function is auto-generated
+func (s Store) UpdateReminder(ctx context.Context, rr ...*systemType.Reminder) (err error) {
+ for i := range rr {
+ if err = s.checkReminderConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, reminderUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertReminder updates one or more existing entries in reminder collection
+//
+// This function is auto-generated
+func (s Store) UpsertReminder(ctx context.Context, rr ...*systemType.Reminder) (err error) {
+ for i := range rr {
+ if err = s.checkReminderConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, reminderUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteReminder Deletes one or more entries from reminder collection
+//
+// This function is auto-generated
+func (s Store) DeleteReminder(ctx context.Context, rr ...*systemType.Reminder) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, reminderDeleteQuery(s.config.Dialect, reminderPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteReminderByID deletes single entry from reminder collection
+//
+// This function is auto-generated
+func (s Store) DeleteReminderByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, reminderDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateReminders Deletes all rows from the reminder collection
+func (s Store) TruncateReminders(ctx context.Context) error {
+ return s.Exec(ctx, reminderTruncateQuery(s.config.Dialect))
+}
+
+// SearchReminders returns (filtered) set of Reminders
+//
+// This function is auto-generated
+func (s Store) SearchReminders(ctx context.Context, f systemType.ReminderFilter) (set systemType.ReminderSet, _ systemType.ReminderFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfReminders fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfReminders(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfReminders collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfReminders(
+ ctx context.Context,
+ filter systemType.ReminderFilter,
+) (set []*systemType.Reminder, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Reminder
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.ReminderFilter
+ )
+
+ set = make([]*systemType.Reminder, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryReminders(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectReminderCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectReminderCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectReminderCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryReminders queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryReminders(
+ ctx context.Context,
+ f systemType.ReminderFilter,
+) (_ []*systemType.Reminder, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Reminder, 0, DefaultSliceCapacity)
+ res *systemType.Reminder
+ aux auxReminder
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Reminder != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Reminder(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ReminderFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Reminder: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := reminderSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableReminderFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Reminder: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Reminder: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Reminder: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Reminder: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Reminder: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Reminder: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupReminderByID
+//
+// This function is auto-generated
+func (s Store) LookupReminderByID(ctx context.Context, id uint64) (_ *systemType.Reminder, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxReminder)
+ lookup = reminderSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableReminderFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableReminderFields() map[string]string {
+ return map[string]string{
+ "assigned_at": "assigned_at",
+ "assignedat": "assigned_at",
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "dismissed_at": "dismissed_at",
+ "dismissedat": "dismissed_at",
+ "id": "id",
+ "remind_at": "remind_at",
+ "remindat": "remind_at",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectReminderCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectReminderCursorValues(res *systemType.Reminder, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "assignedAt":
+ cur.Set(c.Column, res.AssignedAt, c.Descending)
+ case "dismissedAt":
+ cur.Set(c.Column, res.DismissedAt, c.Descending)
+ case "remindAt":
+ cur.Set(c.Column, res.RemindAt, c.Descending)
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkReminderConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkReminderConstraints(ctx context.Context, res *systemType.Reminder) (err error) {
+ return nil
+}
+
+// CreateReport creates one or more rows in report collection
+//
+// This function is auto-generated
+func (s Store) CreateReport(ctx context.Context, rr ...*systemType.Report) (err error) {
+ for i := range rr {
+ if err = s.checkReportConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, reportInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateReport updates one or more existing entries in report collection
+//
+// This function is auto-generated
+func (s Store) UpdateReport(ctx context.Context, rr ...*systemType.Report) (err error) {
+ for i := range rr {
+ if err = s.checkReportConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, reportUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertReport updates one or more existing entries in report collection
+//
+// This function is auto-generated
+func (s Store) UpsertReport(ctx context.Context, rr ...*systemType.Report) (err error) {
+ for i := range rr {
+ if err = s.checkReportConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, reportUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteReport Deletes one or more entries from report collection
+//
+// This function is auto-generated
+func (s Store) DeleteReport(ctx context.Context, rr ...*systemType.Report) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, reportDeleteQuery(s.config.Dialect, reportPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteReportByID deletes single entry from report collection
+//
+// This function is auto-generated
+func (s Store) DeleteReportByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, reportDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateReports Deletes all rows from the report collection
+func (s Store) TruncateReports(ctx context.Context) error {
+ return s.Exec(ctx, reportTruncateQuery(s.config.Dialect))
+}
+
+// SearchReports returns (filtered) set of Reports
+//
+// This function is auto-generated
+func (s Store) SearchReports(ctx context.Context, f systemType.ReportFilter) (set systemType.ReportSet, _ systemType.ReportFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfReports fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfReports(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfReports collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfReports(
+ ctx context.Context,
+ filter systemType.ReportFilter,
+) (set []*systemType.Report, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Report
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.ReportFilter
+ )
+
+ set = make([]*systemType.Report, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryReports(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectReportCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectReportCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectReportCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryReports queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryReports(
+ ctx context.Context,
+ f systemType.ReportFilter,
+) (_ []*systemType.Report, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Report, 0, DefaultSliceCapacity)
+ res *systemType.Report
+ aux auxReport
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Report != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Report(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ReportFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Report: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := reportSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableReportFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Report: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Report: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Report: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Report: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Report: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Report: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupReportByID searches for report by ID
+//
+// It returns report even if deleted
+//
+// This function is auto-generated
+func (s Store) LookupReportByID(ctx context.Context, id uint64) (_ *systemType.Report, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxReport)
+ lookup = reportSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupReportByHandle searches for report by handle
+//
+// It returns report if deleted
+//
+// This function is auto-generated
+func (s Store) LookupReportByHandle(ctx context.Context, handle string) (_ *systemType.Report, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxReport)
+ lookup = reportSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableReportFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableReportFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectReportCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectReportCursorValues(res *systemType.Report, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkReportConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkReportConstraints(ctx context.Context, res *systemType.Report) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupReportByHandle(ctx, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateResourceActivity creates one or more rows in resourceActivity collection
+//
+// This function is auto-generated
+func (s Store) CreateResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) (err error) {
+ for i := range rr {
+ if err = s.checkResourceActivityConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, resourceActivityInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateResourceActivity updates one or more existing entries in resourceActivity collection
+//
+// This function is auto-generated
+func (s Store) UpdateResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) (err error) {
+ for i := range rr {
+ if err = s.checkResourceActivityConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, resourceActivityUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertResourceActivity updates one or more existing entries in resourceActivity collection
+//
+// This function is auto-generated
+func (s Store) UpsertResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) (err error) {
+ for i := range rr {
+ if err = s.checkResourceActivityConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, resourceActivityUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteResourceActivity Deletes one or more entries from resourceActivity collection
+//
+// This function is auto-generated
+func (s Store) DeleteResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, resourceActivityDeleteQuery(s.config.Dialect, resourceActivityPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteResourceActivityByID deletes single entry from resourceActivity collection
+//
+// This function is auto-generated
+func (s Store) DeleteResourceActivityByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, resourceActivityDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateResourceActivitys Deletes all rows from the resourceActivity collection
+func (s Store) TruncateResourceActivitys(ctx context.Context) error {
+ return s.Exec(ctx, resourceActivityTruncateQuery(s.config.Dialect))
+}
+
+// SearchResourceActivitys returns (filtered) set of ResourceActivitys
+//
+// This function is auto-generated
+func (s Store) SearchResourceActivitys(ctx context.Context, f discoveryType.ResourceActivityFilter) (set discoveryType.ResourceActivitySet, _ discoveryType.ResourceActivityFilter, err error) {
+
+ set, _, err = s.QueryResourceActivitys(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryResourceActivitys queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryResourceActivitys(
+ ctx context.Context,
+ f discoveryType.ResourceActivityFilter,
+) (_ []*discoveryType.ResourceActivity, more bool, err error) {
+ var (
+ set = make([]*discoveryType.ResourceActivity, 0, DefaultSliceCapacity)
+ res *discoveryType.ResourceActivity
+ aux auxResourceActivity
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.ResourceActivity != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ResourceActivity(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ResourceActivityFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ResourceActivity: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := resourceActivitySelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ResourceActivity: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ResourceActivity: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ResourceActivity: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ResourceActivity: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ResourceActivity: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// sortableResourceActivityFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableResourceActivityFields() map[string]string {
+ return map[string]string{
+ "id": "id",
+ "timestamp": "timestamp",
+ }
+}
+
+// collectResourceActivityCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectResourceActivityCursorValues(res *discoveryType.ResourceActivity, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "timestamp":
+ cur.Set(c.Column, res.Timestamp, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkResourceActivityConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkResourceActivityConstraints(ctx context.Context, res *discoveryType.ResourceActivity) (err error) {
+ return nil
+}
+
+// CreateResourceTranslation creates one or more rows in resourceTranslation collection
+//
+// This function is auto-generated
+func (s Store) CreateResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) (err error) {
+ for i := range rr {
+ if err = s.checkResourceTranslationConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, resourceTranslationInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateResourceTranslation updates one or more existing entries in resourceTranslation collection
+//
+// This function is auto-generated
+func (s Store) UpdateResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) (err error) {
+ for i := range rr {
+ if err = s.checkResourceTranslationConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, resourceTranslationUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertResourceTranslation updates one or more existing entries in resourceTranslation collection
+//
+// This function is auto-generated
+func (s Store) UpsertResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) (err error) {
+ for i := range rr {
+ if err = s.checkResourceTranslationConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, resourceTranslationUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteResourceTranslation Deletes one or more entries from resourceTranslation collection
+//
+// This function is auto-generated
+func (s Store) DeleteResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, resourceTranslationDeleteQuery(s.config.Dialect, resourceTranslationPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteResourceTranslationByID deletes single entry from resourceTranslation collection
+//
+// This function is auto-generated
+func (s Store) DeleteResourceTranslationByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, resourceTranslationDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateResourceTranslations Deletes all rows from the resourceTranslation collection
+func (s Store) TruncateResourceTranslations(ctx context.Context) error {
+ return s.Exec(ctx, resourceTranslationTruncateQuery(s.config.Dialect))
+}
+
+// SearchResourceTranslations returns (filtered) set of ResourceTranslations
+//
+// This function is auto-generated
+func (s Store) SearchResourceTranslations(ctx context.Context, f systemType.ResourceTranslationFilter) (set systemType.ResourceTranslationSet, _ systemType.ResourceTranslationFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfResourceTranslations fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfResourceTranslations(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfResourceTranslations collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfResourceTranslations(
+ ctx context.Context,
+ filter systemType.ResourceTranslationFilter,
+) (set []*systemType.ResourceTranslation, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.ResourceTranslation
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.ResourceTranslationFilter
+ )
+
+ set = make([]*systemType.ResourceTranslation, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryResourceTranslations(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectResourceTranslationCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectResourceTranslationCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectResourceTranslationCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryResourceTranslations queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryResourceTranslations(
+ ctx context.Context,
+ f systemType.ResourceTranslationFilter,
+) (_ []*systemType.ResourceTranslation, more bool, err error) {
+ var (
+ set = make([]*systemType.ResourceTranslation, 0, DefaultSliceCapacity)
+ res *systemType.ResourceTranslation
+ aux auxResourceTranslation
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.ResourceTranslation != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.ResourceTranslation(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = ResourceTranslationFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for ResourceTranslation: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := resourceTranslationSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableResourceTranslationFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for ResourceTranslation: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query ResourceTranslation: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ResourceTranslation: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query ResourceTranslation: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for ResourceTranslation: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode ResourceTranslation: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupResourceTranslationByID searches for resource translation by ID
+// It also returns deleted resource translations.
+//
+// This function is auto-generated
+func (s Store) LookupResourceTranslationByID(ctx context.Context, id uint64) (_ *systemType.ResourceTranslation, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxResourceTranslation)
+ lookup = resourceTranslationSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableResourceTranslationFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableResourceTranslationFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectResourceTranslationCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectResourceTranslationCursorValues(res *systemType.ResourceTranslation, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkResourceTranslationConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkResourceTranslationConstraints(ctx context.Context, res *systemType.ResourceTranslation) (err error) {
+ return nil
+}
+
+// CreateRole creates one or more rows in role collection
+//
+// This function is auto-generated
+func (s Store) CreateRole(ctx context.Context, rr ...*systemType.Role) (err error) {
+ for i := range rr {
+ if err = s.checkRoleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, roleInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateRole updates one or more existing entries in role collection
+//
+// This function is auto-generated
+func (s Store) UpdateRole(ctx context.Context, rr ...*systemType.Role) (err error) {
+ for i := range rr {
+ if err = s.checkRoleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, roleUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertRole updates one or more existing entries in role collection
+//
+// This function is auto-generated
+func (s Store) UpsertRole(ctx context.Context, rr ...*systemType.Role) (err error) {
+ for i := range rr {
+ if err = s.checkRoleConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, roleUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteRole Deletes one or more entries from role collection
+//
+// This function is auto-generated
+func (s Store) DeleteRole(ctx context.Context, rr ...*systemType.Role) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, roleDeleteQuery(s.config.Dialect, rolePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteRoleByID deletes single entry from role collection
+//
+// This function is auto-generated
+func (s Store) DeleteRoleByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, roleDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateRoles Deletes all rows from the role collection
+func (s Store) TruncateRoles(ctx context.Context) error {
+ return s.Exec(ctx, roleTruncateQuery(s.config.Dialect))
+}
+
+// SearchRoles returns (filtered) set of Roles
+//
+// This function is auto-generated
+func (s Store) SearchRoles(ctx context.Context, f systemType.RoleFilter) (set systemType.RoleSet, _ systemType.RoleFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfRoles fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfRoles(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfRoles collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfRoles(
+ ctx context.Context,
+ filter systemType.RoleFilter,
+) (set []*systemType.Role, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Role
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.RoleFilter
+ )
+
+ set = make([]*systemType.Role, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryRoles(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectRoleCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectRoleCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectRoleCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryRoles queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryRoles(
+ ctx context.Context,
+ f systemType.RoleFilter,
+) (_ []*systemType.Role, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Role, 0, DefaultSliceCapacity)
+ res *systemType.Role
+ aux auxRole
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Role != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Role(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = RoleFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Role: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := roleSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableRoleFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Role: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Role: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Role: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Role: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Role: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Role: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupRoleByID searches for role by ID
+//
+// It returns role even if deleted or suspended
+//
+// This function is auto-generated
+func (s Store) LookupRoleByID(ctx context.Context, id uint64) (_ *systemType.Role, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxRole)
+ lookup = roleSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupRoleByHandle searches for role by handle
+//
+// It returns only valid role (not deleted, not suspended)
+//
+// This function is auto-generated
+func (s Store) LookupRoleByHandle(ctx context.Context, handle string) (_ *systemType.Role, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxRole)
+ lookup = roleSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupRoleByName searches for role by name
+//
+// It returns only valid role (not deleted, not suspended)
+//
+// This function is auto-generated
+func (s Store) LookupRoleByName(ctx context.Context, name string) (_ *systemType.Role, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxRole)
+ lookup = roleSelectQuery(s.config.Dialect).Where(
+ goqu.I("name").Eq(name),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableRoleFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableRoleFields() map[string]string {
+ return map[string]string{
+ "archived_at": "archived_at",
+ "archivedat": "archived_at",
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectRoleCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectRoleCursorValues(res *systemType.Role, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ case "archivedAt":
+ cur.Set(c.Column, res.ArchivedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkRoleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkRoleConstraints(ctx context.Context, res *systemType.Role) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupRoleByHandle(ctx, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Name) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupRoleByName(ctx, res.Name)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateRoleMember creates one or more rows in roleMember collection
+//
+// This function is auto-generated
+func (s Store) CreateRoleMember(ctx context.Context, rr ...*systemType.RoleMember) (err error) {
+ for i := range rr {
+ if err = s.checkRoleMemberConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, roleMemberInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateRoleMember updates one or more existing entries in roleMember collection
+//
+// This function is auto-generated
+func (s Store) UpdateRoleMember(ctx context.Context, rr ...*systemType.RoleMember) (err error) {
+ for i := range rr {
+ if err = s.checkRoleMemberConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, roleMemberUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertRoleMember updates one or more existing entries in roleMember collection
+//
+// This function is auto-generated
+func (s Store) UpsertRoleMember(ctx context.Context, rr ...*systemType.RoleMember) (err error) {
+ for i := range rr {
+ if err = s.checkRoleMemberConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, roleMemberUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteRoleMember Deletes one or more entries from roleMember collection
+//
+// This function is auto-generated
+func (s Store) DeleteRoleMember(ctx context.Context, rr ...*systemType.RoleMember) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, roleMemberDeleteQuery(s.config.Dialect, roleMemberPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteRoleMemberByID deletes single entry from roleMember collection
+//
+// This function is auto-generated
+func (s Store) DeleteRoleMemberByUserIDRoleID(ctx context.Context, userID uint64, roleID uint64) error {
+ return s.Exec(ctx, roleMemberDeleteQuery(s.config.Dialect, goqu.Ex{
+ "rel_user": userID,
+ "rel_role": roleID,
+ }))
+}
+
+// TruncateRoleMembers Deletes all rows from the roleMember collection
+func (s Store) TruncateRoleMembers(ctx context.Context) error {
+ return s.Exec(ctx, roleMemberTruncateQuery(s.config.Dialect))
+}
+
+// SearchRoleMembers returns (filtered) set of RoleMembers
+//
+// This function is auto-generated
+func (s Store) SearchRoleMembers(ctx context.Context, f systemType.RoleMemberFilter) (set systemType.RoleMemberSet, _ systemType.RoleMemberFilter, err error) {
+
+ set, _, err = s.QueryRoleMembers(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QueryRoleMembers queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryRoleMembers(
+ ctx context.Context,
+ f systemType.RoleMemberFilter,
+) (_ []*systemType.RoleMember, more bool, err error) {
+ var (
+ set = make([]*systemType.RoleMember, 0, DefaultSliceCapacity)
+ res *systemType.RoleMember
+ aux auxRoleMember
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.RoleMember != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.RoleMember(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = RoleMemberFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for RoleMember: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := roleMemberSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query RoleMember: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query RoleMember: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query RoleMember: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for RoleMember: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode RoleMember: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// sortableRoleMemberFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableRoleMemberFields() map[string]string {
+ return map[string]string{
+ "role_id": "role_id",
+ "roleid": "role_id",
+ "user_id": "user_id",
+ "userid": "user_id",
+ }
+}
+
+// collectRoleMemberCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectRoleMemberCursorValues(res *systemType.RoleMember, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkUserID bool
+ pkRoleID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "userID":
+ cur.Set(c.Column, res.UserID, c.Descending)
+ pkUserID = true
+ case "roleID":
+ cur.Set(c.Column, res.RoleID, c.Descending)
+ pkRoleID = true
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkUserID {
+ collect(&filter.SortExpr{Column: "userID", Descending: false})
+ }
+ if !hasUnique || !pkRoleID {
+ collect(&filter.SortExpr{Column: "roleID", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkRoleMemberConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkRoleMemberConstraints(ctx context.Context, res *systemType.RoleMember) (err error) {
+ return nil
+}
+
+// CreateSettingValue creates one or more rows in settingValue collection
+//
+// This function is auto-generated
+func (s Store) CreateSettingValue(ctx context.Context, rr ...*systemType.SettingValue) (err error) {
+ for i := range rr {
+ if err = s.checkSettingValueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, settingValueInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateSettingValue updates one or more existing entries in settingValue collection
+//
+// This function is auto-generated
+func (s Store) UpdateSettingValue(ctx context.Context, rr ...*systemType.SettingValue) (err error) {
+ for i := range rr {
+ if err = s.checkSettingValueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, settingValueUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertSettingValue updates one or more existing entries in settingValue collection
+//
+// This function is auto-generated
+func (s Store) UpsertSettingValue(ctx context.Context, rr ...*systemType.SettingValue) (err error) {
+ for i := range rr {
+ if err = s.checkSettingValueConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, settingValueUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteSettingValue Deletes one or more entries from settingValue collection
+//
+// This function is auto-generated
+func (s Store) DeleteSettingValue(ctx context.Context, rr ...*systemType.SettingValue) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, settingValueDeleteQuery(s.config.Dialect, settingValuePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteSettingValueByID deletes single entry from settingValue collection
+//
+// This function is auto-generated
+func (s Store) DeleteSettingValueByNameOwnedBy(ctx context.Context, name string, ownedBy uint64) error {
+ return s.Exec(ctx, settingValueDeleteQuery(s.config.Dialect, goqu.Ex{
+ "name": name,
+ "rel_owner": ownedBy,
+ }))
+}
+
+// TruncateSettingValues Deletes all rows from the settingValue collection
+func (s Store) TruncateSettingValues(ctx context.Context) error {
+ return s.Exec(ctx, settingValueTruncateQuery(s.config.Dialect))
+}
+
+// SearchSettingValues returns (filtered) set of SettingValues
+//
+// This function is auto-generated
+func (s Store) SearchSettingValues(ctx context.Context, f systemType.SettingsFilter) (set systemType.SettingValueSet, _ systemType.SettingsFilter, err error) {
+
+ set, _, err = s.QuerySettingValues(ctx, f)
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// QuerySettingValues queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QuerySettingValues(
+ ctx context.Context,
+ f systemType.SettingsFilter,
+) (_ []*systemType.SettingValue, more bool, err error) {
+ var (
+ set = make([]*systemType.SettingValue, 0, DefaultSliceCapacity)
+ res *systemType.SettingValue
+ aux auxSettingValue
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+ )
+
+ if s.config.Filters.SettingValue != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.SettingValue(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = SettingValueFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for SettingValue: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ query := settingValueSelectQuery(s.config.Dialect).Where(expr...)
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query SettingValue: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query SettingValue: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query SettingValue: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for SettingValue: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode SettingValue: %w", err)
+ return
+ }
+
+ set = append(set, res)
+ }
+
+ return set, false, err
+
+}
+
+// LookupSettingValueByNameOwnedBy searches for settings by name and owner
+//
+// This function is auto-generated
+func (s Store) LookupSettingValueByNameOwnedBy(ctx context.Context, name string, ownedBy uint64) (_ *systemType.SettingValue, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxSettingValue)
+ lookup = settingValueSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("name")).Eq(strings.ToLower(name)),
+ goqu.I("rel_owner").Eq(ownedBy),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableSettingValueFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableSettingValueFields() map[string]string {
+ return map[string]string{
+ "name": "name",
+ "owned_by": "owned_by",
+ "ownedby": "owned_by",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectSettingValueCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectSettingValueCursorValues(res *systemType.SettingValue, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkName bool
+ pkOwnedBy bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "name":
+ cur.Set(c.Column, res.Name, c.Descending)
+ pkName = true
+ case "ownedBy":
+ cur.Set(c.Column, res.OwnedBy, c.Descending)
+ pkOwnedBy = true
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkName {
+ collect(&filter.SortExpr{Column: "name", Descending: false})
+ }
+ if !hasUnique || !pkOwnedBy {
+ collect(&filter.SortExpr{Column: "ownedBy", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkSettingValueConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkSettingValueConstraints(ctx context.Context, res *systemType.SettingValue) (err error) {
+ return nil
+}
+
+// CreateTemplate creates one or more rows in template collection
+//
+// This function is auto-generated
+func (s Store) CreateTemplate(ctx context.Context, rr ...*systemType.Template) (err error) {
+ for i := range rr {
+ if err = s.checkTemplateConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, templateInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateTemplate updates one or more existing entries in template collection
+//
+// This function is auto-generated
+func (s Store) UpdateTemplate(ctx context.Context, rr ...*systemType.Template) (err error) {
+ for i := range rr {
+ if err = s.checkTemplateConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, templateUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertTemplate updates one or more existing entries in template collection
+//
+// This function is auto-generated
+func (s Store) UpsertTemplate(ctx context.Context, rr ...*systemType.Template) (err error) {
+ for i := range rr {
+ if err = s.checkTemplateConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, templateUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteTemplate Deletes one or more entries from template collection
+//
+// This function is auto-generated
+func (s Store) DeleteTemplate(ctx context.Context, rr ...*systemType.Template) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, templateDeleteQuery(s.config.Dialect, templatePrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteTemplateByID deletes single entry from template collection
+//
+// This function is auto-generated
+func (s Store) DeleteTemplateByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, templateDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateTemplates Deletes all rows from the template collection
+func (s Store) TruncateTemplates(ctx context.Context) error {
+ return s.Exec(ctx, templateTruncateQuery(s.config.Dialect))
+}
+
+// SearchTemplates returns (filtered) set of Templates
+//
+// This function is auto-generated
+func (s Store) SearchTemplates(ctx context.Context, f systemType.TemplateFilter) (set systemType.TemplateSet, _ systemType.TemplateFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfTemplates fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfTemplates(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfTemplates collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfTemplates(
+ ctx context.Context,
+ filter systemType.TemplateFilter,
+) (set []*systemType.Template, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.Template
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.TemplateFilter
+ )
+
+ set = make([]*systemType.Template, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryTemplates(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectTemplateCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectTemplateCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectTemplateCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryTemplates queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryTemplates(
+ ctx context.Context,
+ f systemType.TemplateFilter,
+) (_ []*systemType.Template, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.Template, 0, DefaultSliceCapacity)
+ res *systemType.Template
+ aux auxTemplate
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.Template != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.Template(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = TemplateFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for Template: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := templateSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableTemplateFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for Template: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query Template: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Template: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query Template: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for Template: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode Template: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupTemplateByID searches for template by ID
+//
+// It also returns deleted templates.
+//
+// This function is auto-generated
+func (s Store) LookupTemplateByID(ctx context.Context, id uint64) (_ *systemType.Template, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxTemplate)
+ lookup = templateSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupTemplateByHandle searches for template by handle
+//
+// It returns only valid templates (not deleted)
+//
+// This function is auto-generated
+func (s Store) LookupTemplateByHandle(ctx context.Context, handle string) (_ *systemType.Template, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxTemplate)
+ lookup = templateSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableTemplateFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableTemplateFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "handle": "handle",
+ "id": "id",
+ "last_used_at": "last_used_at",
+ "lastusedat": "last_used_at",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ }
+}
+
+// collectTemplateCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectTemplateCursorValues(res *systemType.Template, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ case "lastUsedAt":
+ cur.Set(c.Column, res.LastUsedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkTemplateConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkTemplateConstraints(ctx context.Context, res *systemType.Template) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupTemplateByHandle(ctx, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
+
+// CreateUser creates one or more rows in user collection
+//
+// This function is auto-generated
+func (s Store) CreateUser(ctx context.Context, rr ...*systemType.User) (err error) {
+ for i := range rr {
+ if err = s.checkUserConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, userInsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpdateUser updates one or more existing entries in user collection
+//
+// This function is auto-generated
+func (s Store) UpdateUser(ctx context.Context, rr ...*systemType.User) (err error) {
+ for i := range rr {
+ if err = s.checkUserConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, userUpdateQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// UpsertUser updates one or more existing entries in user collection
+//
+// This function is auto-generated
+func (s Store) UpsertUser(ctx context.Context, rr ...*systemType.User) (err error) {
+ for i := range rr {
+ if err = s.checkUserConstraints(ctx, rr[i]); err != nil {
+ return
+ }
+
+ if err = s.Exec(ctx, userUpsertQuery(s.config.Dialect, rr[i])); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+// DeleteUser Deletes one or more entries from user collection
+//
+// This function is auto-generated
+func (s Store) DeleteUser(ctx context.Context, rr ...*systemType.User) (err error) {
+ for i := range rr {
+ if err = s.Exec(ctx, userDeleteQuery(s.config.Dialect, userPrimaryKeys(rr[i]))); err != nil {
+ return
+ }
+ }
+
+ return nil
+}
+
+// DeleteUserByID deletes single entry from user collection
+//
+// This function is auto-generated
+func (s Store) DeleteUserByID(ctx context.Context, id uint64) error {
+ return s.Exec(ctx, userDeleteQuery(s.config.Dialect, goqu.Ex{
+ "id": id,
+ }))
+}
+
+// TruncateUsers Deletes all rows from the user collection
+func (s Store) TruncateUsers(ctx context.Context) error {
+ return s.Exec(ctx, userTruncateQuery(s.config.Dialect))
+}
+
+// SearchUsers returns (filtered) set of Users
+//
+// This function is auto-generated
+func (s Store) SearchUsers(ctx context.Context, f systemType.UserFilter) (set systemType.UserSet, _ systemType.UserFilter, err error) {
+
+ // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
+ f.PrevPage, f.NextPage = nil, nil
+
+ if f.PageCursor != nil {
+ // Page cursor exists; we need to validate it against used sort
+ // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
+ // from the cursor.
+ // This (extracted sorting info) is then returned as part of response
+ if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
+ return
+ }
+ }
+
+ // Make sure results are always sorted at least by primary keys
+ if f.Sort.Get("id") == nil {
+ f.Sort = append(f.Sort, &filter.SortExpr{
+ Column: "id",
+ Descending: f.Sort.LastDescending(),
+ })
+ }
+
+ // Cloned sorting instructions for the actual sorting
+ // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
+ // direction information
+ sort := f.Sort.Clone()
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ if f.PageCursor != nil && f.PageCursor.ROrder {
+ sort.Reverse()
+ }
+
+ set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfUsers(
+ ctx,
+ f,
+ )
+
+ f.PageCursor = nil
+ if err != nil {
+ return nil, f, err
+ }
+
+ return set, f, nil
+}
+
+// fetchFullPageOfUsers collects all requested results.
+//
+// Function applies:
+// - cursor conditions (where ...)
+// - limit
+//
+// Main responsibility of this function is to perform additional sequential queries in case when not enough results
+// are collected due to failed check on a specific row (by check fn).
+//
+// Function then moves cursor to the last item fetched
+//
+// This function is auto-generated
+func (s Store) fetchFullPageOfUsers(
+ ctx context.Context,
+ filter systemType.UserFilter,
+) (set []*systemType.User, prev, next *filter.PagingCursor, err error) {
+ var (
+ aux []*systemType.User
+
+ // When cursor for a previous page is used it's marked as reversed
+ // This tells us to flip the descending flag on all used sort keys
+ reversedOrder = filter.PageCursor != nil && filter.PageCursor.ROrder
+
+ // Copy no. of required items to limit
+ // Limit will change when doing subsequent queries to fill
+ // the set with all required items
+ limit = filter.Limit
+
+ reqItems = filter.Limit
+
+ // cursor to prev. page is only calculated when cursor is used
+ hasPrev = filter.PageCursor != nil
+
+ // next cursor is calculated when there are more pages to come
+ hasNext bool
+
+ tryFilter systemType.UserFilter
+ )
+
+ set = make([]*systemType.User, 0, DefaultSliceCapacity)
+
+ for try := 0; try < MaxRefetches; try++ {
+ // Copy filter
+ tryFilter = filter
+
+ if limit > 0 {
+ // fetching + 1 to peak ahead if there are more items
+ // we can fetch (next-page cursor)
+ tryFilter.Limit = limit + 1
+ }
+
+ if aux, hasNext, err = s.QueryUsers(ctx, tryFilter); err != nil {
+ return nil, nil, nil, err
+ }
+
+ if len(aux) == 0 {
+ // nothing fetched
+ break
+ }
+
+ // append fetched items
+ set = append(set, aux...)
+
+ if reqItems == 0 || !hasNext {
+ // no max requested items specified, break out
+ break
+ }
+
+ collected := uint(len(set))
+
+ if reqItems > collected {
+ // not enough items fetched, try again with adjusted limit
+ limit = reqItems - collected
+
+ if limit < MinEnsureFetchLimit {
+ // In case limit is set very low and we've missed records in the first fetch,
+ // make sure next fetch limit is a bit higher
+ limit = MinEnsureFetchLimit
+ }
+
+ // Update cursor so that it points to the last item fetched
+ tryFilter.PageCursor = s.collectUserCursorValues(set[collected-1], filter.Sort...)
+
+ // Copy reverse flag from sorting
+ tryFilter.PageCursor.LThen = filter.Sort.Reversed()
+ continue
+ }
+
+ if reqItems < collected {
+ set = set[:reqItems]
+ }
+
+ break
+ }
+
+ collected := len(set)
+
+ if collected == 0 {
+ return nil, nil, nil, nil
+ }
+
+ if reversedOrder {
+ // Fetched set needs to be reversed because we've forced a descending order to get the previous page
+ for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
+ set[i], set[j] = set[j], set[i]
+ }
+
+ // when in reverse-order rules on what cursor to return change
+ hasPrev, hasNext = hasNext, hasPrev
+ }
+
+ if hasPrev {
+ prev = s.collectUserCursorValues(set[0], filter.Sort...)
+ prev.ROrder = true
+ prev.LThen = !filter.Sort.Reversed()
+ }
+
+ if hasNext {
+ next = s.collectUserCursorValues(set[collected-1], filter.Sort...)
+ next.LThen = filter.Sort.Reversed()
+ }
+
+ return set, prev, next, nil
+}
+
+// QueryUsers queries the database, converts and checks each row and returns collected set
+//
+// With generics, we can remove this per-resource-generated function
+// and replace it with a single utility fetcher
+//
+// This function is auto-generated
+func (s Store) QueryUsers(
+ ctx context.Context,
+ f systemType.UserFilter,
+) (_ []*systemType.User, more bool, err error) {
+ var (
+ ok bool
+
+ set = make([]*systemType.User, 0, DefaultSliceCapacity)
+ res *systemType.User
+ aux auxUser
+ rows *sql.Rows
+ count uint
+ expr, tExpr []goqu.Expression
+
+ sortExpr []exp.OrderedExpression
+ )
+
+ if s.config.Filters.User != nil {
+ // extended filter set
+ tExpr, f, err = s.config.Filters.User(f)
+ } else {
+ // using generated filter
+ tExpr, f, err = UserFilter(f)
+ }
+
+ if err != nil {
+ err = fmt.Errorf("could generate filter expression for User: %w", err)
+ return
+ }
+
+ expr = append(expr, tExpr...)
+
+ // paging feature is enabled
+ if f.PageCursor != nil {
+ if tExpr, err = cursor(f.PageCursor); err != nil {
+ return
+ } else {
+ expr = append(expr, tExpr...)
+ }
+ }
+
+ query := userSelectQuery(s.config.Dialect).Where(expr...)
+
+ // sorting feature is enabled
+ if sortExpr, err = order(f.Sort, s.sortableUserFields()); err != nil {
+ err = fmt.Errorf("could generate order expression for User: %w", err)
+ return
+ }
+
+ if len(sortExpr) > 0 {
+ query = query.Order(sortExpr...)
+ }
+
+ if f.Limit > 0 {
+ query = query.Limit(f.Limit)
+ }
+
+ rows, err = s.Query(ctx, query)
+ if err != nil {
+ err = fmt.Errorf("could not query User: %w", err)
+ return
+ }
+
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query User: %w", err)
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ for rows.Next() {
+ if err = rows.Err(); err != nil {
+ err = fmt.Errorf("could not query User: %w", err)
+ return
+ }
+
+ if err = aux.scan(rows); err != nil {
+ err = fmt.Errorf("could not scan rows for User: %w", err)
+ return
+ }
+
+ count++
+ if res, err = aux.decode(); err != nil {
+ err = fmt.Errorf("could not decode User: %w", err)
+ return
+ }
+
+ // check fn set, call it and see if it passed the test
+ // if not, skip the item
+ if f.Check != nil {
+ if ok, err = f.Check(res); err != nil {
+ return
+ } else if !ok {
+ continue
+ }
+ }
+
+ set = append(set, res)
+ }
+
+ return set, f.Limit > 0 && count >= f.Limit, err
+
+}
+
+// LookupUserByID searches for user by ID
+//
+// It returns user even if deleted or suspended
+//
+// This function is auto-generated
+func (s Store) LookupUserByID(ctx context.Context, id uint64) (_ *systemType.User, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxUser)
+ lookup = userSelectQuery(s.config.Dialect).Where(
+ goqu.I("id").Eq(id),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupUserByEmail searches for user by email
+//
+// It returns only valid user (not deleted, not suspended)
+//
+// This function is auto-generated
+func (s Store) LookupUserByEmail(ctx context.Context, email string) (_ *systemType.User, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxUser)
+ lookup = userSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("email")).Eq(strings.ToLower(email)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupUserByHandle searches for user by handle
+//
+// It returns only valid user (not deleted, not suspended)
+//
+// This function is auto-generated
+func (s Store) LookupUserByHandle(ctx context.Context, handle string) (_ *systemType.User, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxUser)
+ lookup = userSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("handle")).Eq(strings.ToLower(handle)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// LookupUserByUsername searches for user by username
+//
+// It returns only valid user (not deleted, not suspended)
+//
+// This function is auto-generated
+func (s Store) LookupUserByUsername(ctx context.Context, username string) (_ *systemType.User, err error) {
+ var (
+ rows *sql.Rows
+ aux = new(auxUser)
+ lookup = userSelectQuery(s.config.Dialect).Where(
+ s.config.Functions.LOWER(goqu.I("username")).Eq(strings.ToLower(username)),
+ goqu.I("deleted_at").IsNull(),
+ ).Limit(1)
+ )
+
+ rows, err = s.Query(ctx, lookup)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return nil, store.ErrNotFound.Stack(1)
+ }
+
+ if err = aux.scan(rows); err != nil {
+ return
+ }
+
+ return aux.decode()
+}
+
+// sortableUserFields returns all columns flagged as sortable
+//
+// With optional string arg, all columns are returned aliased
+//
+// This function is auto-generated
+func (Store) sortableUserFields() map[string]string {
+ return map[string]string{
+ "created_at": "created_at",
+ "createdat": "created_at",
+ "deleted_at": "deleted_at",
+ "deletedat": "deleted_at",
+ "email": "email",
+ "handle": "handle",
+ "id": "id",
+ "suspended_at": "suspended_at",
+ "suspendedat": "suspended_at",
+ "updated_at": "updated_at",
+ "updatedat": "updated_at",
+ "username": "username",
+ }
+}
+
+// collectUserCursorValues collects values from the given resource that and sets them to the cursor
+// to be used for pagination
+//
+// Values that are collected must come from sortable, unique or primary columns/fields
+// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
+//
+// Known issue:
+// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
+// undeleted items)
+//
+// This function is auto-generated
+func (s Store) collectUserCursorValues(res *systemType.User, cc ...*filter.SortExpr) *filter.PagingCursor {
+ var (
+ cur = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
+
+ hasUnique bool
+
+ pkID bool
+
+ collect = func(cc ...*filter.SortExpr) {
+ for _, c := range cc {
+ switch c.Column {
+ case "id":
+ cur.Set(c.Column, res.ID, c.Descending)
+ pkID = true
+ case "handle":
+ cur.Set(c.Column, res.Handle, c.Descending)
+ hasUnique = true
+ case "email":
+ cur.Set(c.Column, res.Email, c.Descending)
+ hasUnique = true
+ case "username":
+ cur.Set(c.Column, res.Username, c.Descending)
+ hasUnique = true
+ case "createdAt":
+ cur.Set(c.Column, res.CreatedAt, c.Descending)
+ case "updatedAt":
+ cur.Set(c.Column, res.UpdatedAt, c.Descending)
+ case "deletedAt":
+ cur.Set(c.Column, res.DeletedAt, c.Descending)
+ case "suspendedAt":
+ cur.Set(c.Column, res.SuspendedAt, c.Descending)
+ }
+ }
+ }
+ )
+
+ collect(cc...)
+ if !hasUnique || !pkID {
+ collect(&filter.SortExpr{Column: "id", Descending: false})
+ }
+
+ return cur
+
+}
+
+// checkUserConstraints performs lookups (on valid) resource to check if any of the values on unique fields
+// already exists in the store
+//
+// Using built-in constraint checking would be more performant, but unfortunately we cannot rely
+// on the full support (MySQL does not support conditional indexes)
+//
+// This function is auto-generated
+func (s *Store) checkUserConstraints(ctx context.Context, res *systemType.User) (err error) {
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Email) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupUserByEmail(ctx, res.Email)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Handle) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupUserByHandle(ctx, res.Handle)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ err = func() (err error) {
+
+ // handling string type as default
+ if len(res.Username) == 0 {
+ // skip check on empty values
+ return nil
+ }
+
+ if res.DeletedAt != nil {
+ // skip check if value is not nil
+ return nil
+ }
+
+ ex, err := s.LookupUserByUsername(ctx, res.Username)
+ if err == nil && ex != nil && ex.ID != res.ID {
+ return store.ErrNotUnique.Stack(1)
+ } else if !errors.IsNotFound(err) {
+ return err
+ }
+
+ return nil
+ }()
+
+ if err != nil {
+ return
+ }
+
+ return nil
+}
diff --git a/store/adapters/rdbms/rdbms.go b/store/adapters/rdbms/rdbms.go
new file mode 100644
index 000000000..038c1481f
--- /dev/null
+++ b/store/adapters/rdbms/rdbms.go
@@ -0,0 +1,98 @@
+package rdbms
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+
+ "github.com/cortezaproject/corteza-server/store"
+ "github.com/doug-martin/goqu/v9/exec"
+ "go.uber.org/zap"
+)
+
+type (
+ sqlizer interface {
+ ToSQL() (string, []interface{}, error)
+ }
+
+ scalable interface {
+ Scan(...interface{}) error
+ }
+
+ Store struct {
+ db dbLayer
+
+ // rdbms store configuration
+ config *Config
+
+ // Logger for connection
+ logger *zap.Logger
+ }
+)
+
+func (s Store) Exec(ctx context.Context, q sqlizer) error {
+ var (
+ query, args, err = q.ToSQL()
+ )
+
+ if err != nil {
+ return fmt.Errorf("could not build query: %w", err)
+ }
+
+ _, err = s.db.ExecContext(ctx, query, args...)
+ return store.HandleError(err, s.config.ErrorHandler)
+}
+
+func (s Store) Query(ctx context.Context, q sqlizer) (*sql.Rows, error) {
+ var (
+ rr *sql.Rows
+
+ query, args, err = q.ToSQL()
+ )
+
+ if err != nil {
+ return nil, fmt.Errorf("could not build query: %w", err)
+ }
+
+ rr, err = s.db.QueryContext(ctx, query, args...)
+ if err = store.HandleError(err, s.config.ErrorHandler); err != nil {
+ return nil, err
+ }
+
+ return rr, nil
+}
+
+func (s Store) QueryOne(ctx context.Context, q sqlizer, dst interface{}) (err error) {
+ var (
+ rows *sql.Rows
+ )
+
+ rows, err = s.Query(ctx, q)
+ if err != nil {
+ return
+ }
+
+ defer func() {
+ closeError := rows.Close()
+ if err == nil {
+ // return error from close
+ err = closeError
+ }
+ }()
+
+ if err = rows.Err(); err != nil {
+ return
+ }
+
+ if !rows.Next() {
+ return store.ErrNotFound.Stack(1)
+ }
+
+ return exec.NewScanner(rows).ScanStruct(dst)
+}
+
+// Config returns store's config as a value
+// as protection against changes
+func (s Store) Config() Config {
+ return *s.config
+}
diff --git a/store/adapters/rdbms/rdbms_test.go b/store/adapters/rdbms/rdbms_test.go
new file mode 100644
index 000000000..aebfd1a58
--- /dev/null
+++ b/store/adapters/rdbms/rdbms_test.go
@@ -0,0 +1,2 @@
+package rdbms
+
diff --git a/store/adapters/rdbms/schema/README.md b/store/adapters/rdbms/schema/README.md
new file mode 100644
index 000000000..ea7a46d41
--- /dev/null
+++ b/store/adapters/rdbms/schema/README.md
@@ -0,0 +1,23 @@
+# RDBMS Schema package
+
+Package contains
+
+1. DDL
+2. Current schema definition instructions
+3. Upgrade instructions using state detection and modification instructions
+
+## DDL or Data Definition Language
+
+This package provides building blocks and generic dialect for specifying RDBMS schema creation and alternation instructions.
+
+## Flow
+
+### General steps
+1. Application (or tests) start the boot procedure
+2. `store.Upgrade()` (`store/upgrade.go`) is called with current primary store connection
+
+### RDBMS specific steps
+
+RDBMS implementation of schema upgrade is unified across all drivers (store implementations)
+3. `schema.Upgrade()` initializes common (across implementations) upgrade procedure and use `schemaUpgrader` interface that each store implementation provides.
+4.
diff --git a/store/rdbms/ddl/def.go b/store/adapters/rdbms/schema/def.go
similarity index 98%
rename from store/rdbms/ddl/def.go
rename to store/adapters/rdbms/schema/def.go
index 56f0f26bd..23680fcd3 100644
--- a/store/rdbms/ddl/def.go
+++ b/store/adapters/rdbms/schema/def.go
@@ -1,4 +1,4 @@
-package ddl
+package schema
import (
"fmt"
@@ -64,7 +64,7 @@ const (
// Subset of SQL types
//
// Just the ones we use in Corteza
- // Each type should have it's own formatter inside
+ // Each type should have its own formatter inside
ColumnTypeIdentifier columnType = iota
ColumnTypeVarchar
diff --git a/store/rdbms/ddl/gen.go b/store/adapters/rdbms/schema/dialect.go
similarity index 51%
rename from store/rdbms/ddl/gen.go
rename to store/adapters/rdbms/schema/dialect.go
index cf34d889a..2601be25b 100644
--- a/store/rdbms/ddl/gen.go
+++ b/store/adapters/rdbms/schema/dialect.go
@@ -1,4 +1,4 @@
-package ddl
+package schema
import (
"bytes"
@@ -6,23 +6,17 @@ import (
"regexp"
"strings"
"text/template"
-
- "go.uber.org/zap"
)
type (
- Generator struct {
- log *zap.Logger
+ CommonDialect struct {
tpl *template.Template
}
)
-// @todo all DDL operations (altering, droping, adding...) from all *sql* implementations should be moved here
-// logic is more or less the same with a differet approach on how to read schema specs (tables, columns)
-
const (
// table creation
- genericCreateTable = `
+ commonCreateTable = `
CREATE TABLE {{template "if-not-exists-clause" .}} {{ .Name }} (
{{ range $n, $c := .Columns -}}
{{ if $n }}, {{ else }} {{ end }}{{ template "create-table-column" . }}
@@ -33,27 +27,27 @@ const (
) {{- template "create-table-suffix" . -}}
`
- genericCreateTableSuffix = ``
+ commonCreateTableSuffix = ``
- genericCreateTableColumn = `
+ commonCreateTableColumn = `
{{- .Name }} {{ columnType .Type }}
{{- if not .IsNull }} NOT NULL{{end}}
{{- if .DefaultValue }} DEFAULT {{ .DefaultValue }} {{end}}
`
- genericAddColumn = `ALTER TABLE {{ .Table }} ADD {{ template "create-table-column" .Column }}`
- genericAddPrimaryKey = `ALTER TABLE {{ .Table }} ADD CONSTRAINT PRIMARY KEY {{ template "index-fields" .PrimaryKey.Fields }}`
- genericDropColumn = `ALTER TABLE {{ .Table }} DROP {{ .Column }}`
- genericRenameColumn = `ALTER TABLE {{ .Table }} RENAME COLUMN {{ .OldName }} TO {{ .NewName }}`
+ commonAddColumn = `ALTER TABLE {{ .Table }} ADD {{ template "create-table-column" .Column }}`
+ commonAddPrimaryKey = `ALTER TABLE {{ .Table }} ADD CONSTRAINT PRIMARY KEY {{ template "index-fields" .PrimaryKey.Fields }}`
+ commonDropColumn = `ALTER TABLE {{ .Table }} DROP {{ .Column }}`
+ commonRenameColumn = `ALTER TABLE {{ .Table }} RENAME COLUMN {{ .OldName }} TO {{ .NewName }}`
// index creation
- genericCreateIndex = `CREATE {{ if .Unique }}UNIQUE {{ end }}INDEX {{ template "if-not-exists-clause" . }} {{ template "index-name" . }} ON {{ .Table }} {{ template "index-fields" .Fields }}{{ template "index-condition" . }}`
+ commonCreateIndex = `CREATE {{ if .Unique }}UNIQUE {{ end }}INDEX {{ template "if-not-exists-clause" . }} {{ template "index-name" . }} ON {{ .Table }} {{ template "index-fields" .Fields }}{{ template "index-condition" . }}`
- genericIndexName = `{{ .Table }}_{{ .Name }}`
- genericIndexCondition = `{{- if .Condition }} WHERE ({{ .Condition }}){{ end }}`
+ commonIndexName = `{{ .Table }}_{{ .Name }}`
+ commonIndexCondition = `{{- if .Condition }} WHERE ({{ .Condition }}){{ end }}`
// index creation
- genericIndexFields = `
+ commonIndexFields = `
({{ range $n, $f := . -}}
{{ if $n }}, {{ end }}
{{- if .Expr}}({{ end }}
@@ -63,29 +57,29 @@ const (
{{- end }})
`
// table/index exist or not clause
- genericIfNotExistsClause = `IF NOT EXISTS`
+ commonIfNotExistsClause = `IF NOT EXISTS`
)
-func NewGenerator(log *zap.Logger) *Generator {
- g := &Generator{log: log, tpl: template.New("")}
+func NewCommonDialect() *CommonDialect {
+ g := &CommonDialect{tpl: template.New("")}
g.AddTemplateFunc("columnType", GenColumnType)
- g.AddTemplate("create-table", genericCreateTable)
- g.AddTemplate("create-table-suffix", genericCreateTableSuffix)
- g.AddTemplate("create-table-column", genericCreateTableColumn)
- g.AddTemplate("add-column", genericAddColumn)
- g.AddTemplate("add-primary-key", genericAddPrimaryKey)
- g.AddTemplate("drop-column", genericDropColumn)
- g.AddTemplate("rename-column", genericRenameColumn)
- g.AddTemplate("create-index", genericCreateIndex)
- g.AddTemplate("index-condition", genericIndexCondition)
- g.AddTemplate("index-name", genericIndexName)
- g.AddTemplate("index-fields", genericIndexFields)
- g.AddTemplate("if-not-exists-clause", genericIfNotExistsClause)
+ g.AddTemplate("create-table", commonCreateTable)
+ g.AddTemplate("create-table-suffix", commonCreateTableSuffix)
+ g.AddTemplate("create-table-column", commonCreateTableColumn)
+ g.AddTemplate("add-column", commonAddColumn)
+ g.AddTemplate("add-primary-key", commonAddPrimaryKey)
+ g.AddTemplate("drop-column", commonDropColumn)
+ g.AddTemplate("rename-column", commonRenameColumn)
+ g.AddTemplate("create-index", commonCreateIndex)
+ g.AddTemplate("index-condition", commonIndexCondition)
+ g.AddTemplate("index-name", commonIndexName)
+ g.AddTemplate("index-fields", commonIndexFields)
+ g.AddTemplate("if-not-exists-clause", commonIfNotExistsClause)
return g
}
-func (g *Generator) executeTemplate(name string, data interface{}) string {
+func (g *CommonDialect) executeTemplate(name string, data interface{}) string {
buf := &bytes.Buffer{}
if err := g.tpl.ExecuteTemplate(buf, name, data); err != nil {
panic(err)
@@ -94,11 +88,11 @@ func (g *Generator) executeTemplate(name string, data interface{}) string {
return buf.String()
}
-func (g *Generator) AddTemplateFunc(name string, fn interface{}) {
+func (g *CommonDialect) AddTemplateFunc(name string, fn interface{}) {
g.tpl.Funcs(template.FuncMap{name: fn})
}
-func (g *Generator) AddTemplate(name, tpl string) {
+func (g *CommonDialect) AddTemplate(name, tpl string) {
funcMap := template.FuncMap{
"trimExpression": func(s string) string {
re := regexp.MustCompile(`^.*\((\w+)\).*$`)
@@ -111,29 +105,29 @@ func (g *Generator) AddTemplate(name, tpl string) {
template.Must(g.tpl.Funcs(funcMap).New(name).Parse(strings.TrimSpace(tpl)))
}
-func (g *Generator) CreateTable(t *Table) string {
+func (g *CommonDialect) CreateTable(t *Table) string {
return g.executeTemplate("create-table", t)
}
-func (g *Generator) CreateIndex(i *Index) string {
+func (g *CommonDialect) CreateIndex(i *Index) string {
return g.executeTemplate("create-index", i)
}
-func (g *Generator) AddColumn(table string, c *Column) string {
+func (g *CommonDialect) AddColumn(table string, c *Column) string {
return g.executeTemplate("add-column", map[string]interface{}{
"Table": table,
"Column": c,
})
}
-func (g *Generator) DropColumn(table, column string) string {
+func (g *CommonDialect) DropColumn(table, column string) string {
return g.executeTemplate("drop-column", map[string]interface{}{
"Table": table,
"Column": column,
})
}
-func (g *Generator) RenameColumn(table, oldName, newName string) string {
+func (g *CommonDialect) RenameColumn(table, oldName, newName string) string {
return g.executeTemplate("rename-column", map[string]interface{}{
"Table": table,
"OldName": oldName,
@@ -141,7 +135,7 @@ func (g *Generator) RenameColumn(table, oldName, newName string) string {
})
}
-func (g *Generator) AddPrimaryKey(table string, pk *Index) string {
+func (g *CommonDialect) AddPrimaryKey(table string, pk *Index) string {
return g.executeTemplate("add-primary-key", map[string]interface{}{
"Table": table,
"PrimaryKey": pk,
diff --git a/store/rdbms/ddl/gen_test.go b/store/adapters/rdbms/schema/dialect_test.go
similarity index 87%
rename from store/rdbms/ddl/gen_test.go
rename to store/adapters/rdbms/schema/dialect_test.go
index 971df8e47..b44eaee6f 100644
--- a/store/rdbms/ddl/gen_test.go
+++ b/store/adapters/rdbms/schema/dialect_test.go
@@ -1,10 +1,11 @@
-package ddl
+package schema
import (
- "github.com/stretchr/testify/require"
- "go.uber.org/zap"
"strings"
"testing"
+
+ "github.com/stretchr/testify/require"
+ "go.uber.org/zap"
)
func Test_generator_CreateTable(t *testing.T) {
@@ -44,7 +45,7 @@ CREATE TABLE tbl (
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- require.New(t).Equal(strings.TrimSpace(tt.out), NewGenerator(zap.NewNop()).CreateTable(tt.in))
+ require.New(t).Equal(strings.TrimSpace(tt.out), NewCommonDialect(zap.NewNop()).CreateTable(tt.in))
})
}
}
@@ -82,7 +83,7 @@ func Test_generator_CreateIndex(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
- require.New(t).Equal(tt.out, NewGenerator(zap.NewNop()).CreateIndex(tt.in.Indexes[0]))
+ require.New(t).Equal(tt.out, NewCommonDialect(zap.NewNop()).CreateIndex(tt.in.Indexes[0]))
})
}
}
diff --git a/store/adapters/rdbms/schema/schema.go b/store/adapters/rdbms/schema/schema.go
new file mode 100644
index 000000000..fe74ee6ed
--- /dev/null
+++ b/store/adapters/rdbms/schema/schema.go
@@ -0,0 +1,43 @@
+package schema
+
+import (
+ "context"
+ "fmt"
+
+ "go.uber.org/zap"
+)
+
+type (
+ Schema struct{}
+
+ // schemaUpgrader provides procedures to upgrade rdbms store tables
+ Upgrader interface {
+ SetLogger(*zap.Logger)
+ Before(context.Context) error
+ CreateTable(context.Context, *Table) error
+ After(context.Context) error
+ }
+)
+
+// Upgrade upgrades given rdbms schema by adding all missing tables and applying changes to existing
+func Upgrade(ctx context.Context, sud Upgrader) (err error) {
+ if sud == nil {
+ return fmt.Errorf("can not upgrade database schema, upgrade interface not set")
+ }
+
+ if err = sud.Before(ctx); err != nil {
+ return fmt.Errorf("could not run \"before\" upgrade procedures: %w", err)
+ }
+
+ for _, t := range tables() {
+ if err = sud.CreateTable(ctx, t); err != nil {
+ return fmt.Errorf("could not create table %s: %w", t.Name, err)
+ }
+ }
+
+ if err = sud.After(ctx); err != nil {
+ return fmt.Errorf("could not run \"after\" upgrade procedures: %w", err)
+ }
+
+ return nil
+}
diff --git a/store/rdbms/rdbms_schema.go b/store/adapters/rdbms/schema/tables.go
similarity index 86%
rename from store/rdbms/rdbms_schema.go
rename to store/adapters/rdbms/schema/tables.go
index 855a3af54..7ab9e3d05 100644
--- a/store/rdbms/rdbms_schema.go
+++ b/store/adapters/rdbms/schema/tables.go
@@ -1,22 +1,4 @@
-package rdbms
-
-import (
- "context"
- "fmt"
-
- . "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
-)
-
-type (
- Schema struct{}
-
- // schemaUpgrader provides procedures to upgrade rdbms store tables
- schemaUpgrader interface {
- Before(context.Context) error
- CreateTable(context.Context, *Table) error
- After(context.Context) error
- }
-)
+package schema
const (
handleLength = 64
@@ -39,72 +21,54 @@ const (
languageKeyLength = 256
)
-// Upgrades schema
-func (s *Schema) Upgrade(ctx context.Context, g schemaUpgrader) (err error) {
- if err = g.Before(ctx); err != nil {
- return fmt.Errorf("could not run \"before\" upgrade procedures: %w", err)
- }
-
- for _, t := range s.Tables() {
- if err = g.CreateTable(ctx, t); err != nil {
- return fmt.Errorf("could not create table %s: %w", t.Name, err)
- }
- }
-
- if err = g.After(ctx); err != nil {
- return fmt.Errorf("could not run \"after\" upgrade procedures: %w", err)
- }
-
- return nil
-}
-
-func (s Schema) Tables() []*Table {
+// Tables fn holds a list of all tables that need to be created for Corteza
+func tables() []*Table {
return []*Table{
- s.Users(),
- s.Credentials(),
- s.AuthClients(),
- s.AuthConfirmedClients(),
- s.AuthSessions(),
- s.AuthOA2Tokens(),
- s.Roles(),
- s.RoleMembers(),
- s.Applications(),
- s.Reminders(),
- s.Attachments(),
- s.ActionLog(),
- s.RbacRules(),
- s.Settings(),
- s.Labels(),
- s.Flags(),
- s.Templates(),
- s.Reports(),
- s.ResourceTranslations(),
- s.ComposeAttachment(),
- s.ComposeChart(),
- s.ComposeModule(),
- s.ComposeModuleField(),
- s.ComposeNamespace(),
- s.ComposePage(),
- s.ComposeRecord(),
- s.ComposeRecordValue(),
- s.FederationModuleShared(),
- s.FederationModuleExposed(),
- s.FederationModuleMapping(),
- s.FederationNodes(),
- s.FederationNodesSync(),
- s.AutomationWorkflows(),
- s.AutomationTriggers(),
- s.AutomationSessions(),
- //s.AutomationState(),
- s.MessagebusQueue(),
- s.MessagebusQueuemessage(),
- s.ApigwRoute(),
- s.ApigwFilter(),
- s.ResourceActivityLog(),
+ tableUsers(),
+ tableCredentials(),
+ tableAuthClients(),
+ tableAuthConfirmedClients(),
+ tableAuthSessions(),
+ tableAuthOA2Tokens(),
+ tableRoles(),
+ tableRoleMembers(),
+ tableApplications(),
+ tableReminders(),
+ tableAttachments(),
+ tableActionLog(),
+ tableRbacRules(),
+ tableSettings(),
+ tableLabels(),
+ tableFlags(),
+ tableTemplates(),
+ tableReports(),
+ tableResourceTranslations(),
+ tableComposeAttachment(),
+ tableComposeChart(),
+ tableComposeModule(),
+ tableComposeModuleField(),
+ tableComposeNamespace(),
+ tableComposePage(),
+ tableComposeRecord(),
+ tableComposeRecordValue(),
+ tableFederationModuleShared(),
+ tableFederationModuleExposed(),
+ tableFederationModuleMapping(),
+ tableFederationNodes(),
+ tableFederationNodesSync(),
+ tableAutomationWorkflows(),
+ tableAutomationTriggers(),
+ tableAutomationSessions(),
+ //tableAutomationState(),
+ tableMessagebusQueue(),
+ tableMessagebusQueuemessage(),
+ tableApigwRoute(),
+ tableApigwFilter(),
+ tableResourceActivityLog(),
}
}
-func (Schema) Users() *Table {
+func tableUsers() *Table {
return TableDef("users",
ID,
ColumnDef("email", ColumnTypeVarchar, ColumnTypeLength(emailLength)),
@@ -123,7 +87,7 @@ func (Schema) Users() *Table {
)
}
-func (Schema) Credentials() *Table {
+func tableCredentials() *Table {
return TableDef(`credentials`,
ID,
ColumnDef("rel_owner", ColumnTypeIdentifier),
@@ -139,7 +103,7 @@ func (Schema) Credentials() *Table {
)
}
-func (Schema) AuthClients() *Table {
+func tableAuthClients() *Table {
return TableDef(`auth_clients`,
ID,
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
@@ -161,7 +125,7 @@ func (Schema) AuthClients() *Table {
)
}
-func (Schema) AuthConfirmedClients() *Table {
+func tableAuthConfirmedClients() *Table {
return TableDef(`auth_confirmed_clients`,
ColumnDef("rel_user", ColumnTypeIdentifier),
ColumnDef("rel_client", ColumnTypeIdentifier),
@@ -171,7 +135,7 @@ func (Schema) AuthConfirmedClients() *Table {
)
}
-func (Schema) AuthSessions() *Table {
+func tableAuthSessions() *Table {
return TableDef(`auth_sessions`,
ColumnDef("id", ColumnTypeVarchar, ColumnTypeLength(64)),
ColumnDef("data", ColumnTypeBinary),
@@ -187,7 +151,7 @@ func (Schema) AuthSessions() *Table {
)
}
-func (Schema) AuthOA2Tokens() *Table {
+func tableAuthOA2Tokens() *Table {
return TableDef(`auth_oa2tokens`,
ID,
@@ -212,7 +176,7 @@ func (Schema) AuthOA2Tokens() *Table {
)
}
-func (Schema) Roles() *Table {
+func tableRoles() *Table {
return TableDef(`roles`,
ID,
ColumnDef("name", ColumnTypeText),
@@ -225,7 +189,7 @@ func (Schema) Roles() *Table {
)
}
-func (Schema) RoleMembers() *Table {
+func tableRoleMembers() *Table {
return TableDef(`role_members`,
ColumnDef("rel_role", ColumnTypeIdentifier),
ColumnDef("rel_user", ColumnTypeIdentifier),
@@ -234,7 +198,7 @@ func (Schema) RoleMembers() *Table {
)
}
-func (Schema) Applications() *Table {
+func tableApplications() *Table {
return TableDef("applications",
ID,
ColumnDef("name", ColumnTypeText),
@@ -246,7 +210,7 @@ func (Schema) Applications() *Table {
)
}
-func (Schema) Reminders() *Table {
+func tableReminders() *Table {
return TableDef("reminders",
ID,
ColumnDef("resource", ColumnTypeVarchar, ColumnTypeLength(resourceLength)),
@@ -265,7 +229,7 @@ func (Schema) Reminders() *Table {
)
}
-func (Schema) Attachments() *Table {
+func tableAttachments() *Table {
return TableDef("attachments",
ID,
ColumnDef("rel_owner", ColumnTypeIdentifier),
@@ -278,7 +242,7 @@ func (Schema) Attachments() *Table {
)
}
-func (Schema) ActionLog() *Table {
+func tableActionLog() *Table {
return TableDef("actionlog",
ID,
ColumnDef("ts", ColumnTypeTimestamp),
@@ -301,7 +265,7 @@ func (Schema) ActionLog() *Table {
)
}
-func (Schema) RbacRules() *Table {
+func tableRbacRules() *Table {
return TableDef("rbac_rules",
ColumnDef("rel_role", ColumnTypeIdentifier),
ColumnDef("resource", ColumnTypeVarchar, ColumnTypeLength(resourceLength)),
@@ -312,7 +276,7 @@ func (Schema) RbacRules() *Table {
)
}
-func (Schema) Settings() *Table {
+func tableSettings() *Table {
return TableDef("settings",
ColumnDef("rel_owner", ColumnTypeIdentifier),
ColumnDef("name", ColumnTypeVarchar, ColumnTypeLength(resourceLength)),
@@ -324,7 +288,7 @@ func (Schema) Settings() *Table {
)
}
-func (Schema) Labels() *Table {
+func tableLabels() *Table {
return TableDef("labels",
ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
ColumnDef("rel_resource", ColumnTypeIdentifier),
@@ -335,7 +299,7 @@ func (Schema) Labels() *Table {
)
}
-func (Schema) Flags() *Table {
+func tableFlags() *Table {
return TableDef("flags",
ColumnDef("kind", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
ColumnDef("rel_resource", ColumnTypeIdentifier),
@@ -347,7 +311,7 @@ func (Schema) Flags() *Table {
)
}
-func (Schema) Templates() *Table {
+func tableTemplates() *Table {
return TableDef("templates",
ID,
ColumnDef("rel_owner", ColumnTypeIdentifier),
@@ -364,7 +328,7 @@ func (Schema) Templates() *Table {
)
}
-func (Schema) Reports() *Table {
+func tableReports() *Table {
return TableDef("reports",
ID,
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
@@ -381,7 +345,7 @@ func (Schema) Reports() *Table {
)
}
-func (Schema) ResourceTranslations() *Table {
+func tableResourceTranslations() *Table {
return TableDef("resource_translations",
ID,
@@ -398,7 +362,7 @@ func (Schema) ResourceTranslations() *Table {
)
}
-func (Schema) ComposeAttachment() *Table {
+func tableComposeAttachment() *Table {
// @todo merge with general attachment table
return TableDef("compose_attachment",
@@ -416,7 +380,7 @@ func (Schema) ComposeAttachment() *Table {
)
}
-//func (Schema) ComposeRecordAttachment() *Table {
+//func tableComposeRecordAttachment() *Table {
// return TableDef("compose_record_attachments",
// ColumnDef("rel_attachment", ColumnTypeIdentifier),
// ColumnDef("rel_namespace", ColumnTypeIdentifier),
@@ -431,7 +395,7 @@ func (Schema) ComposeAttachment() *Table {
// )
//}
-//func (Schema) ComposePageAttachment() *Table {
+//func tableComposePageAttachment() *Table {
// return TableDef("compose_record_attachments",
// ColumnDef("rel_attachment", ColumnTypeIdentifier),
// ColumnDef("rel_namespace", ColumnTypeIdentifier),
@@ -444,7 +408,7 @@ func (Schema) ComposeAttachment() *Table {
// )
//}
-func (Schema) ComposeChart() *Table {
+func tableComposeChart() *Table {
return TableDef("compose_chart",
ID,
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
@@ -458,7 +422,7 @@ func (Schema) ComposeChart() *Table {
)
}
-func (Schema) ComposeModule() *Table {
+func tableComposeModule() *Table {
return TableDef("compose_module",
ID,
ColumnDef("rel_namespace", ColumnTypeIdentifier),
@@ -472,7 +436,7 @@ func (Schema) ComposeModule() *Table {
)
}
-func (Schema) ComposeModuleField() *Table {
+func tableComposeModuleField() *Table {
return TableDef("compose_module_field",
ID,
@@ -496,7 +460,7 @@ func (Schema) ComposeModuleField() *Table {
)
}
-func (Schema) ComposeNamespace() *Table {
+func tableComposeNamespace() *Table {
return TableDef("compose_namespace",
ID,
ColumnDef("name", ColumnTypeText),
@@ -509,7 +473,7 @@ func (Schema) ComposeNamespace() *Table {
)
}
-func (Schema) ComposePage() *Table {
+func tableComposePage() *Table {
return TableDef("compose_page",
ID,
ColumnDef("title", ColumnTypeText),
@@ -531,7 +495,7 @@ func (Schema) ComposePage() *Table {
)
}
-func (Schema) ComposeRecord() *Table {
+func tableComposeRecord() *Table {
return TableDef("compose_record",
ID,
ColumnDef("rel_namespace", ColumnTypeIdentifier),
@@ -546,7 +510,7 @@ func (Schema) ComposeRecord() *Table {
)
}
-func (Schema) ComposeRecordValue() *Table {
+func tableComposeRecordValue() *Table {
return TableDef("compose_record_value",
ColumnDef("record_id", ColumnTypeIdentifier),
ColumnDef("name", ColumnTypeVarchar, ColumnTypeLength(64)),
@@ -560,7 +524,7 @@ func (Schema) ComposeRecordValue() *Table {
)
}
-func (Schema) FederationModuleShared() *Table {
+func tableFederationModuleShared() *Table {
return TableDef("federation_module_shared",
ID,
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
@@ -573,7 +537,7 @@ func (Schema) FederationModuleShared() *Table {
)
}
-func (Schema) FederationModuleExposed() *Table {
+func tableFederationModuleExposed() *Table {
return TableDef("federation_module_exposed",
ID,
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
@@ -589,7 +553,7 @@ func (Schema) FederationModuleExposed() *Table {
)
}
-func (Schema) FederationModuleMapping() *Table {
+func tableFederationModuleMapping() *Table {
return TableDef("federation_module_mapping",
ColumnDef("rel_federation_module", ColumnTypeIdentifier),
ColumnDef("rel_compose_module", ColumnTypeIdentifier),
@@ -600,7 +564,7 @@ func (Schema) FederationModuleMapping() *Table {
)
}
-func (Schema) FederationNodes() *Table {
+func tableFederationNodes() *Table {
return TableDef("federation_nodes",
ID,
ColumnDef("shared_node_id", ColumnTypeIdentifier),
@@ -616,7 +580,7 @@ func (Schema) FederationNodes() *Table {
)
}
-func (Schema) FederationNodesSync() *Table {
+func tableFederationNodesSync() *Table {
return TableDef("federation_nodes_sync",
ColumnDef("rel_node", ColumnTypeIdentifier),
ColumnDef("rel_module", ColumnTypeIdentifier),
@@ -626,7 +590,7 @@ func (Schema) FederationNodesSync() *Table {
)
}
-func (Schema) AutomationWorkflows() *Table {
+func tableAutomationWorkflows() *Table {
return TableDef("automation_workflows",
ID,
ColumnDef("handle", ColumnTypeVarchar, ColumnTypeLength(handleLength)),
@@ -647,7 +611,7 @@ func (Schema) AutomationWorkflows() *Table {
)
}
-func (Schema) AutomationSessions() *Table {
+func tableAutomationSessions() *Table {
return TableDef("automation_sessions",
ID,
ColumnDef("rel_workflow", ColumnTypeIdentifier),
@@ -674,7 +638,7 @@ func (Schema) AutomationSessions() *Table {
)
}
-func (Schema) AutomationTriggers() *Table {
+func tableAutomationTriggers() *Table {
return TableDef("automation_triggers",
ID,
ColumnDef("rel_workflow", ColumnTypeIdentifier),
@@ -693,7 +657,7 @@ func (Schema) AutomationTriggers() *Table {
)
}
-func (Schema) MessagebusQueuemessage() *Table {
+func tableMessagebusQueuemessage() *Table {
return TableDef("queue_messages",
ID,
ColumnDef("queue", ColumnTypeText, ColumnTypeLength(handleLength)),
@@ -705,7 +669,7 @@ func (Schema) MessagebusQueuemessage() *Table {
)
}
-func (Schema) MessagebusQueue() *Table {
+func tableMessagebusQueue() *Table {
return TableDef("queue_settings",
ID,
ColumnDef("consumer", ColumnTypeText, ColumnTypeLength(handleLength)),
@@ -716,7 +680,7 @@ func (Schema) MessagebusQueue() *Table {
)
}
-func (Schema) ApigwRoute() *Table {
+func tableApigwRoute() *Table {
return TableDef("apigw_routes",
ID,
ColumnDef("endpoint", ColumnTypeText, ColumnTypeLength(resourceLength)),
@@ -729,7 +693,7 @@ func (Schema) ApigwRoute() *Table {
)
}
-func (Schema) ApigwFilter() *Table {
+func tableApigwFilter() *Table {
return TableDef("apigw_filters",
ID,
ColumnDef("rel_route", ColumnTypeIdentifier),
@@ -743,7 +707,7 @@ func (Schema) ApigwFilter() *Table {
)
}
-func (Schema) ResourceActivityLog() *Table {
+func tableResourceActivityLog() *Table {
return TableDef("resource_activity_log",
ID,
ColumnDef("rel_resource", ColumnTypeIdentifier),
diff --git a/store/rdbms/generic_upgrades.go b/store/adapters/rdbms/schema/upgrade.go
similarity index 70%
rename from store/rdbms/generic_upgrades.go
rename to store/adapters/rdbms/schema/upgrade.go
index 07cd40799..41c0a690a 100644
--- a/store/rdbms/generic_upgrades.go
+++ b/store/adapters/rdbms/schema/upgrade.go
@@ -1,36 +1,36 @@
-package rdbms
+package schema
import (
"context"
"fmt"
- "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
"go.uber.org/zap"
)
type (
- genericUpgrades struct {
+ commonUpgrades struct {
log *zap.Logger
u upgrader
}
+ //
upgrader interface {
TableExists(context.Context, string) (bool, error)
- AddColumn(context.Context, string, *ddl.Column) (bool, error)
+ AddColumn(context.Context, string, *Column) (bool, error)
DropTable(context.Context, string) (bool, error)
DropColumn(context.Context, string, string) (bool, error)
RenameColumn(context.Context, string, string, string) (bool, error)
- AddPrimaryKey(context.Context, string, *ddl.Index) (bool, error)
- CreateIndex(context.Context, *ddl.Index) (bool, error)
+ AddPrimaryKey(context.Context, string, *Index) (bool, error)
+ CreateIndex(context.Context, *Index) (bool, error)
Exec(context.Context, string, ...interface{}) error
}
)
-func GenericUpgrades(log *zap.Logger, u upgrader) *genericUpgrades {
- return &genericUpgrades{log, u}
+func CommonUpgrades(log *zap.Logger, u upgrader) *commonUpgrades {
+ return &commonUpgrades{log, u}
}
-func (g genericUpgrades) Before(ctx context.Context) error {
+func (g commonUpgrades) Before(ctx context.Context) error {
return g.all(ctx,
g.RenameActionlog,
g.RenameReminders,
@@ -43,11 +43,11 @@ func (g genericUpgrades) Before(ctx context.Context) error {
)
}
-func (g genericUpgrades) After(ctx context.Context) error {
+func (g commonUpgrades) After(ctx context.Context) error {
return nil
}
-func (g genericUpgrades) Upgrade(ctx context.Context, t *ddl.Table) error {
+func (g commonUpgrades) Upgrade(ctx context.Context, t *Table) error {
switch t.Name {
case "settings":
return g.all(ctx,
@@ -108,7 +108,7 @@ func (g genericUpgrades) Upgrade(ctx context.Context, t *ddl.Table) error {
return nil
}
-func (genericUpgrades) all(ctx context.Context, ffn ...func(context.Context) error) (err error) {
+func (commonUpgrades) all(ctx context.Context, ffn ...func(context.Context) error) (err error) {
for _, fn := range ffn {
if err = fn(ctx); err != nil {
return err
@@ -119,7 +119,7 @@ func (genericUpgrades) all(ctx context.Context, ffn ...func(context.Context) err
}
// MergeSettingsTables merges "*_settings" tables into one single "settings"
-func (g genericUpgrades) MergeSettingsTables(ctx context.Context) error {
+func (g commonUpgrades) MergeSettingsTables(ctx context.Context) error {
var (
err error
tt = []struct {
@@ -130,7 +130,7 @@ func (g genericUpgrades) MergeSettingsTables(ctx context.Context) error {
{tbl: "compose_settings", applyNamePrefix: "compose."},
}
- // CONCAT does not work in sqlite but we'Ll ignore this since sqlite should
+ // CONCAT does not work in sqlite; we'll ignore this since sqlite should
// not even get execute this query (*_settings tables do not exist)
merge = `
INSERT INTO settings (rel_owner, name, value, updated_by, updated_at)
@@ -163,7 +163,7 @@ func (g genericUpgrades) MergeSettingsTables(ctx context.Context) error {
}
// MergeSettingsTables merges "*_settings" tables into one single "settings"
-func (g genericUpgrades) MergePermissionRulesTables(ctx context.Context) error {
+func (g commonUpgrades) MergePermissionRulesTables(ctx context.Context) error {
var (
err error
tt = []struct {
@@ -205,27 +205,27 @@ func (g genericUpgrades) MergePermissionRulesTables(ctx context.Context) error {
return nil
}
-func (g genericUpgrades) RenameActionlog(ctx context.Context) error {
+func (g commonUpgrades) RenameActionlog(ctx context.Context) error {
return g.RenameTable(ctx, "sys_actionlog", "actionlog")
}
-func (g genericUpgrades) RenameUsers(ctx context.Context) error {
+func (g commonUpgrades) RenameUsers(ctx context.Context) error {
return g.RenameTable(ctx, "sys_user", "users")
}
-func (g genericUpgrades) RenameRoles(ctx context.Context) error {
+func (g commonUpgrades) RenameRoles(ctx context.Context) error {
return g.RenameTable(ctx, "sys_role", "roles")
}
-func (g genericUpgrades) RenameRoleMembers(ctx context.Context) error {
+func (g commonUpgrades) RenameRoleMembers(ctx context.Context) error {
return g.RenameTable(ctx, "sys_role_member", "role_members")
}
-func (g genericUpgrades) RenameApplications(ctx context.Context) error {
+func (g commonUpgrades) RenameApplications(ctx context.Context) error {
return g.RenameTable(ctx, "sys_application", "applications")
}
-func (g genericUpgrades) RenameCredentials(ctx context.Context) error {
+func (g commonUpgrades) RenameCredentials(ctx context.Context) error {
return g.RenameTable(ctx, "sys_credentials", "credentials")
}
@@ -233,11 +233,11 @@ func (g genericUpgrades) RenameCredentials(ctx context.Context) error {
//
// This is MySQL only; other implementations were never in state with actionlog table
// without ID column.
-func (g genericUpgrades) AlterActionlogAddID(ctx context.Context) (err error) {
+func (g commonUpgrades) AlterActionlogAddID(ctx context.Context) (err error) {
var (
added bool
- col = &ddl.Column{Name: "id", Type: ddl.ColumnType{Type: ddl.ColumnTypeIdentifier}, IsNull: false}
- ind = &ddl.Index{Fields: []*ddl.IField{{Field: col.Name}}}
+ col = &Column{Name: "id", Type: ColumnType{Type: ColumnTypeIdentifier}, IsNull: false}
+ ind = &Index{Fields: []*IField{{Field: col.Name}}}
upd = `UPDATE actionlog SET id = @v := COALESCE(@v, 0) + 1 WHERE id = 0`
)
if added, err = g.u.AddColumn(ctx, "actionlog", col); err != nil {
@@ -260,10 +260,10 @@ func (g genericUpgrades) AlterActionlogAddID(ctx context.Context) (err error) {
return nil
}
-func (g genericUpgrades) AddWeightField(ctx context.Context) error {
- _, err := g.u.AddColumn(ctx, "applications", &ddl.Column{
+func (g commonUpgrades) AddWeightField(ctx context.Context) error {
+ _, err := g.u.AddColumn(ctx, "applications", &Column{
Name: "weight",
- Type: ddl.ColumnType{Type: ddl.ColumnTypeInteger},
+ Type: ColumnType{Type: ColumnTypeInteger},
IsNull: false,
DefaultValue: "0",
})
@@ -271,10 +271,10 @@ func (g genericUpgrades) AddWeightField(ctx context.Context) error {
return err
}
-func (g genericUpgrades) AddRolesMetaField(ctx context.Context) error {
- _, err := g.u.AddColumn(ctx, "roles", &ddl.Column{
+func (g commonUpgrades) AddRolesMetaField(ctx context.Context) error {
+ _, err := g.u.AddColumn(ctx, "roles", &Column{
Name: "meta",
- Type: ddl.ColumnType{Type: ddl.ColumnTypeJson},
+ Type: ColumnType{Type: ColumnTypeJson},
IsNull: false,
DefaultValue: "'{}'",
})
@@ -282,10 +282,10 @@ func (g genericUpgrades) AddRolesMetaField(ctx context.Context) error {
return err
}
-func (g genericUpgrades) AddComposeBlockConfigField(ctx context.Context) error {
- _, err := g.u.AddColumn(ctx, "compose_page", &ddl.Column{
+func (g commonUpgrades) AddComposeBlockConfigField(ctx context.Context) error {
+ _, err := g.u.AddColumn(ctx, "compose_page", &Column{
Name: "config",
- Type: ddl.ColumnType{Type: ddl.ColumnTypeJson},
+ Type: ColumnType{Type: ColumnTypeJson},
IsNull: false,
DefaultValue: "'{}'",
})
@@ -293,20 +293,20 @@ func (g genericUpgrades) AddComposeBlockConfigField(ctx context.Context) error {
return err
}
-func (g genericUpgrades) RenameReminders(ctx context.Context) error {
+func (g commonUpgrades) RenameReminders(ctx context.Context) error {
return g.RenameTable(ctx, "sys_reminder", "reminders")
}
-func (g genericUpgrades) DropOrganisationTable(ctx context.Context) error {
+func (g commonUpgrades) DropOrganisationTable(ctx context.Context) error {
_, err := g.u.DropTable(ctx, "organization")
return err
}
-func (g genericUpgrades) AddScenariosField(ctx context.Context) error {
+func (g commonUpgrades) AddScenariosField(ctx context.Context) error {
var (
- col = &ddl.Column{
+ col = &Column{
Name: "scenarios",
- Type: ddl.ColumnType{Type: ddl.ColumnTypeJson},
+ Type: ColumnType{Type: ColumnTypeJson},
IsNull: false,
DefaultValue: "NULL",
}
@@ -316,17 +316,17 @@ func (g genericUpgrades) AddScenariosField(ctx context.Context) error {
return err
}
-func (g genericUpgrades) AlterUsersDropOrganisation(ctx context.Context) error {
+func (g commonUpgrades) AlterUsersDropOrganisation(ctx context.Context) error {
_, err := g.u.DropColumn(ctx, "users", "rel_organisation")
return err
}
-func (g genericUpgrades) AlterUsersDropRelatedUser(ctx context.Context) error {
+func (g commonUpgrades) AlterUsersDropRelatedUser(ctx context.Context) error {
_, err := g.u.DropColumn(ctx, "users", "rel_user_id")
return err
}
-func (g genericUpgrades) RenameTable(ctx context.Context, old, new string) error {
+func (g commonUpgrades) RenameTable(ctx context.Context, old, new string) error {
if exists, err := g.u.TableExists(ctx, old); err != nil {
return err
} else if !exists {
@@ -350,7 +350,7 @@ func (g genericUpgrades) RenameTable(ctx context.Context, old, new string) error
return nil
}
-//func (g genericUpgrades) MigrateComposeAttachmentsToLinksTable(ctx context.Context) error {
+//func (g commonUpgrades) MigrateComposeAttachmentsToLinksTable(ctx context.Context) error {
// var (
// err error
// tt = []struct {
@@ -417,16 +417,16 @@ func (g genericUpgrades) RenameTable(ctx context.Context, old, new string) error
// return nil
//}
-func (g genericUpgrades) AlterComposeModuleRenameJsonToMeta(ctx context.Context) error {
+func (g commonUpgrades) AlterComposeModuleRenameJsonToMeta(ctx context.Context) error {
_, err := g.u.RenameColumn(ctx, "compose_module", "json", "meta")
return err
}
-func (g genericUpgrades) AlterComposeModuleFieldAddExpresions(ctx context.Context) (err error) {
+func (g commonUpgrades) AlterComposeModuleFieldAddExpresions(ctx context.Context) (err error) {
var (
- col = &ddl.Column{
+ col = &Column{
Name: "expressions",
- Type: ddl.ColumnType{Type: ddl.ColumnTypeJson},
+ Type: ColumnType{Type: ColumnTypeJson},
IsNull: false,
DefaultValue: "'{}'",
}
@@ -436,15 +436,15 @@ func (g genericUpgrades) AlterComposeModuleFieldAddExpresions(ctx context.Contex
return
}
-func (g genericUpgrades) CreateAutomationSessionIndexes(ctx context.Context) (err error) {
+func (g commonUpgrades) CreateAutomationSessionIndexes(ctx context.Context) (err error) {
var (
- ii = []*ddl.Index{
- {Name: "event_type", Fields: []*ddl.IField{{Field: "event_type", Length: handleLength}}},
- {Name: "resource_type", Fields: []*ddl.IField{{Field: "resource_type", Length: handleLength}}},
- {Name: "status", Fields: []*ddl.IField{{Field: "status"}}},
- {Name: "created_at", Fields: []*ddl.IField{{Field: "created_at"}}},
- {Name: "completed_at", Fields: []*ddl.IField{{Field: "completed_at"}}},
- {Name: "suspended_at", Fields: []*ddl.IField{{Field: "suspended_at"}}},
+ ii = []*Index{
+ {Name: "event_type", Fields: []*IField{{Field: "event_type", Length: handleLength}}},
+ {Name: "resource_type", Fields: []*IField{{Field: "resource_type", Length: handleLength}}},
+ {Name: "status", Fields: []*IField{{Field: "status"}}},
+ {Name: "created_at", Fields: []*IField{{Field: "created_at"}}},
+ {Name: "completed_at", Fields: []*IField{{Field: "completed_at"}}},
+ {Name: "suspended_at", Fields: []*IField{{Field: "suspended_at"}}},
}
)
@@ -458,10 +458,10 @@ func (g genericUpgrades) CreateAutomationSessionIndexes(ctx context.Context) (er
return
}
-func (g genericUpgrades) AddResourceActivityLogMetaField(ctx context.Context) error {
- _, err := g.u.AddColumn(ctx, "resource_activity_log", &ddl.Column{
+func (g commonUpgrades) AddResourceActivityLogMetaField(ctx context.Context) error {
+ _, err := g.u.AddColumn(ctx, "resource_activity_log", &Column{
Name: "meta",
- Type: ddl.ColumnType{Type: ddl.ColumnTypeJson},
+ Type: ColumnType{Type: ColumnTypeJson},
IsNull: false,
DefaultValue: "'{}'",
})
diff --git a/store/adapters/rdbms/tx.go b/store/adapters/rdbms/tx.go
new file mode 100644
index 000000000..923bacdf3
--- /dev/null
+++ b/store/adapters/rdbms/tx.go
@@ -0,0 +1,94 @@
+package rdbms
+
+import (
+ "context"
+ "database/sql"
+ "fmt"
+ "time"
+
+ "github.com/cortezaproject/corteza-server/pkg/errors"
+ "github.com/cortezaproject/corteza-server/store"
+ "github.com/jmoiron/sqlx"
+)
+
+func (s Store) Tx(ctx context.Context, fn func(context.Context, store.Storer) error) error {
+ return tx(ctx, s.db, s.config, nil, func(ctx context.Context, tx dbLayer) error {
+ return fn(ctx, s.withTx(tx))
+ })
+}
+
+// tx begins a new db transaction and handles it's retries when possible
+//
+// It utilizes configured transaction error handlers and max-retry limits
+// to determine if and how many times transaction should be retried
+//
+func tx(ctx context.Context, dbCandidate interface{}, cfg *Config, txOpt *sql.TxOptions, task func(context.Context, dbLayer) error) error {
+ if cfg.TxDisabled {
+ return task(ctx, dbCandidate.(dbLayer))
+ }
+
+ var (
+ lastTaskErr error
+ err error
+ db *sqlx.DB
+ tx *sqlx.Tx
+ try = 1
+ )
+
+ switch dbCandidate.(type) {
+ case dbTransactionMaker:
+ // we can make a transaction, yay
+ db = dbCandidate.(*sqlx.DB)
+ case dbLayer:
+ // Already in a transaction, run the given task and finish
+ return task(ctx, dbCandidate.(dbLayer))
+ default:
+ return fmt.Errorf("could not use the db connection for transaction")
+ }
+
+ for {
+ try++
+
+ // Start transaction
+ tx, err = db.BeginTxx(ctx, txOpt)
+ if err != nil {
+ return err
+ }
+
+ if lastTaskErr = task(ctx, tx); lastTaskErr == nil {
+ // Task completed successfully
+ return tx.Commit()
+ }
+
+ // No matter the cause of the error, rollback the transaction
+ if rollbackErr := tx.Rollback(); rollbackErr != nil {
+ return fmt.Errorf("failed to rollback transaction (tries: %d) on error %v: %w", try, lastTaskErr, rollbackErr)
+ }
+
+ if errors.IsAny(lastTaskErr) {
+ // not a store-internal/transaction error and can be returned right away,
+ // no need to re-run the transaction
+ return lastTaskErr
+ }
+
+ // Call the the configured transaction retry error handler
+ // if this particular error should be retried or not
+ //
+ // We cannot generalize here because different store implementation have
+ // different errors and we need to act accordingly
+ if !cfg.TxRetryErrHandler(try, lastTaskErr) {
+ return fmt.Errorf("failed to complete transaction: %w", lastTaskErr)
+ }
+
+ // tx error handlers can take current number of tries into account and
+ // break the retry-loop earlier, but that might not be always the case
+ //
+ // We'll check the configured and hard-limit maximums
+ if try >= cfg.TxMaxRetries || try >= TxRetryHardLimit {
+ return fmt.Errorf("failed to perform transaction (tries: %d), last error: %w", try, lastTaskErr)
+ }
+
+ // Sleep (with a bit of kickback) before doing next retry
+ time.Sleep(50 * time.Duration(try*50))
+ }
+}
diff --git a/store/adapters/rdbms/upgrade.go b/store/adapters/rdbms/upgrade.go
new file mode 100644
index 000000000..5cb8436da
--- /dev/null
+++ b/store/adapters/rdbms/upgrade.go
@@ -0,0 +1,24 @@
+package rdbms
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/schema"
+ "go.uber.org/zap"
+)
+
+func (s Store) Upgrade(ctx context.Context, log *zap.Logger) error {
+ if s.config == nil {
+ return fmt.Errorf("config not set on RDBMS store")
+ }
+
+ if s.config.Upgrader == nil {
+ return fmt.Errorf("upgrader not configured on RDBMS store")
+
+ }
+
+ s.config.Upgrader.SetLogger(log)
+
+ return schema.Upgrade(ctx, s.config.Upgrader)
+}
diff --git a/store/apigw_filter.gen.go b/store/apigw_filter.gen.go
deleted file mode 100644
index 8484ebb35..000000000
--- a/store/apigw_filter.gen.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/apigw_filter.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- ApigwFilters interface {
- SearchApigwFilters(ctx context.Context, f types.ApigwFilterFilter) (types.ApigwFilterSet, types.ApigwFilterFilter, error)
- LookupApigwFilterByID(ctx context.Context, id uint64) (*types.ApigwFilter, error)
- LookupApigwFilterByRoute(ctx context.Context, route string) (*types.ApigwFilter, error)
-
- CreateApigwFilter(ctx context.Context, rr ...*types.ApigwFilter) error
-
- UpdateApigwFilter(ctx context.Context, rr ...*types.ApigwFilter) error
-
- DeleteApigwFilter(ctx context.Context, rr ...*types.ApigwFilter) error
- DeleteApigwFilterByID(ctx context.Context, ID uint64) error
-
- TruncateApigwFilters(ctx context.Context) error
- }
-)
-
-var _ *types.ApigwFilter
-var _ context.Context
-
-// SearchApigwFilters returns all matching ApigwFilters from store
-func SearchApigwFilters(ctx context.Context, s ApigwFilters, f types.ApigwFilterFilter) (types.ApigwFilterSet, types.ApigwFilterFilter, error) {
- return s.SearchApigwFilters(ctx, f)
-}
-
-// LookupApigwFilterByID searches for filter by ID
-func LookupApigwFilterByID(ctx context.Context, s ApigwFilters, id uint64) (*types.ApigwFilter, error) {
- return s.LookupApigwFilterByID(ctx, id)
-}
-
-// LookupApigwFilterByRoute searches for filter by route
-func LookupApigwFilterByRoute(ctx context.Context, s ApigwFilters, route string) (*types.ApigwFilter, error) {
- return s.LookupApigwFilterByRoute(ctx, route)
-}
-
-// CreateApigwFilter creates one or more ApigwFilters in store
-func CreateApigwFilter(ctx context.Context, s ApigwFilters, rr ...*types.ApigwFilter) error {
- return s.CreateApigwFilter(ctx, rr...)
-}
-
-// UpdateApigwFilter updates one or more (existing) ApigwFilters in store
-func UpdateApigwFilter(ctx context.Context, s ApigwFilters, rr ...*types.ApigwFilter) error {
- return s.UpdateApigwFilter(ctx, rr...)
-}
-
-// DeleteApigwFilter Deletes one or more ApigwFilters from store
-func DeleteApigwFilter(ctx context.Context, s ApigwFilters, rr ...*types.ApigwFilter) error {
- return s.DeleteApigwFilter(ctx, rr...)
-}
-
-// DeleteApigwFilterByID Deletes ApigwFilter from store
-func DeleteApigwFilterByID(ctx context.Context, s ApigwFilters, ID uint64) error {
- return s.DeleteApigwFilterByID(ctx, ID)
-}
-
-// TruncateApigwFilters Deletes all ApigwFilters from store
-func TruncateApigwFilters(ctx context.Context, s ApigwFilters) error {
- return s.TruncateApigwFilters(ctx)
-}
diff --git a/store/apigw_filter.yaml b/store/apigw_filter.yaml
deleted file mode 100644
index 736af48ae..000000000
--- a/store/apigw_filter.yaml
+++ /dev/null
@@ -1,43 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-types:
- package: types
- type: types.ApigwFilter
- filterType: types.ApigwFilterFilter
-
-fields:
- - { field: ID, sortable: false }
- - { field: Route }
- - { field: Weight }
- - { field: Kind }
- - { field: Ref }
- - { field: Enabled }
- - { field: Params, type: "map[string]interface{}" }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for filter by ID
- - fields: [ Route ]
- description: |-
- searches for filter by route
-
-rdbms:
- alias: af
- table: apigw_filters
- customFilterConverter: true
- mapFields:
- Route: { column: rel_route }
-
-search:
- enablePaging: true
-
-upsert:
- enable: false
diff --git a/store/apigw_route.gen.go b/store/apigw_route.gen.go
deleted file mode 100644
index 2af69fdff..000000000
--- a/store/apigw_route.gen.go
+++ /dev/null
@@ -1,74 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/apigw_route.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- ApigwRoutes interface {
- SearchApigwRoutes(ctx context.Context, f types.ApigwRouteFilter) (types.ApigwRouteSet, types.ApigwRouteFilter, error)
- LookupApigwRouteByID(ctx context.Context, id uint64) (*types.ApigwRoute, error)
- LookupApigwRouteByEndpoint(ctx context.Context, endpoint string) (*types.ApigwRoute, error)
-
- CreateApigwRoute(ctx context.Context, rr ...*types.ApigwRoute) error
-
- UpdateApigwRoute(ctx context.Context, rr ...*types.ApigwRoute) error
-
- DeleteApigwRoute(ctx context.Context, rr ...*types.ApigwRoute) error
- DeleteApigwRouteByID(ctx context.Context, ID uint64) error
-
- TruncateApigwRoutes(ctx context.Context) error
- }
-)
-
-var _ *types.ApigwRoute
-var _ context.Context
-
-// SearchApigwRoutes returns all matching ApigwRoutes from store
-func SearchApigwRoutes(ctx context.Context, s ApigwRoutes, f types.ApigwRouteFilter) (types.ApigwRouteSet, types.ApigwRouteFilter, error) {
- return s.SearchApigwRoutes(ctx, f)
-}
-
-// LookupApigwRouteByID searches for route by ID
-func LookupApigwRouteByID(ctx context.Context, s ApigwRoutes, id uint64) (*types.ApigwRoute, error) {
- return s.LookupApigwRouteByID(ctx, id)
-}
-
-// LookupApigwRouteByEndpoint searches for route by endpoint
-func LookupApigwRouteByEndpoint(ctx context.Context, s ApigwRoutes, endpoint string) (*types.ApigwRoute, error) {
- return s.LookupApigwRouteByEndpoint(ctx, endpoint)
-}
-
-// CreateApigwRoute creates one or more ApigwRoutes in store
-func CreateApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*types.ApigwRoute) error {
- return s.CreateApigwRoute(ctx, rr...)
-}
-
-// UpdateApigwRoute updates one or more (existing) ApigwRoutes in store
-func UpdateApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*types.ApigwRoute) error {
- return s.UpdateApigwRoute(ctx, rr...)
-}
-
-// DeleteApigwRoute Deletes one or more ApigwRoutes from store
-func DeleteApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*types.ApigwRoute) error {
- return s.DeleteApigwRoute(ctx, rr...)
-}
-
-// DeleteApigwRouteByID Deletes ApigwRoute from store
-func DeleteApigwRouteByID(ctx context.Context, s ApigwRoutes, ID uint64) error {
- return s.DeleteApigwRouteByID(ctx, ID)
-}
-
-// TruncateApigwRoutes Deletes all ApigwRoutes from store
-func TruncateApigwRoutes(ctx context.Context, s ApigwRoutes) error {
- return s.TruncateApigwRoutes(ctx)
-}
diff --git a/store/apigw_route.yaml b/store/apigw_route.yaml
deleted file mode 100644
index 8eba8f4f1..000000000
--- a/store/apigw_route.yaml
+++ /dev/null
@@ -1,42 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-types:
- package: types
- type: types.ApigwRoute
- filterType: types.ApigwRouteFilter
-
-fields:
- - { field: ID, sortable: false }
- - { field: Endpoint, sortable: true }
- - { field: Method, sortable: true }
- - { field: Enabled }
- - { field: Group }
- - { field: Meta, type: "types.ApigwRouteMeta" }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for route by ID
- - fields: [ Endpoint ]
- description: |-
- searches for route by endpoint
-
-rdbms:
- alias: ar
- table: apigw_routes
- customFilterConverter: true
- mapFields:
- Group: { column: rel_group }
-
-search:
- enablePaging: true
-
-upsert:
- enable: false
diff --git a/store/applications.gen.go b/store/applications.gen.go
deleted file mode 100644
index 0cacfb74d..000000000
--- a/store/applications.gen.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/applications.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Applications interface {
- SearchApplications(ctx context.Context, f types.ApplicationFilter) (types.ApplicationSet, types.ApplicationFilter, error)
- LookupApplicationByID(ctx context.Context, id uint64) (*types.Application, error)
-
- CreateApplication(ctx context.Context, rr ...*types.Application) error
-
- UpdateApplication(ctx context.Context, rr ...*types.Application) error
-
- UpsertApplication(ctx context.Context, rr ...*types.Application) error
-
- DeleteApplication(ctx context.Context, rr ...*types.Application) error
- DeleteApplicationByID(ctx context.Context, ID uint64) error
-
- TruncateApplications(ctx context.Context) error
-
- // Additional custom functions
-
- // ApplicationMetrics (custom function)
- ApplicationMetrics(ctx context.Context) (*types.ApplicationMetrics, error)
-
- // ReorderApplications (custom function)
- ReorderApplications(ctx context.Context, _order []uint64) error
- }
-)
-
-var _ *types.Application
-var _ context.Context
-
-// SearchApplications returns all matching Applications from store
-func SearchApplications(ctx context.Context, s Applications, f types.ApplicationFilter) (types.ApplicationSet, types.ApplicationFilter, error) {
- return s.SearchApplications(ctx, f)
-}
-
-// LookupApplicationByID searches for application by ID
-//
-// It returns application even if deleted
-func LookupApplicationByID(ctx context.Context, s Applications, id uint64) (*types.Application, error) {
- return s.LookupApplicationByID(ctx, id)
-}
-
-// CreateApplication creates one or more Applications in store
-func CreateApplication(ctx context.Context, s Applications, rr ...*types.Application) error {
- return s.CreateApplication(ctx, rr...)
-}
-
-// UpdateApplication updates one or more (existing) Applications in store
-func UpdateApplication(ctx context.Context, s Applications, rr ...*types.Application) error {
- return s.UpdateApplication(ctx, rr...)
-}
-
-// UpsertApplication creates new or updates existing one or more Applications in store
-func UpsertApplication(ctx context.Context, s Applications, rr ...*types.Application) error {
- return s.UpsertApplication(ctx, rr...)
-}
-
-// DeleteApplication Deletes one or more Applications from store
-func DeleteApplication(ctx context.Context, s Applications, rr ...*types.Application) error {
- return s.DeleteApplication(ctx, rr...)
-}
-
-// DeleteApplicationByID Deletes Application from store
-func DeleteApplicationByID(ctx context.Context, s Applications, ID uint64) error {
- return s.DeleteApplicationByID(ctx, ID)
-}
-
-// TruncateApplications Deletes all Applications from store
-func TruncateApplications(ctx context.Context, s Applications) error {
- return s.TruncateApplications(ctx)
-}
-
-func ApplicationMetrics(ctx context.Context, s Applications) (*types.ApplicationMetrics, error) {
- return s.ApplicationMetrics(ctx)
-}
-
-func ReorderApplications(ctx context.Context, s Applications, _order []uint64) error {
- return s.ReorderApplications(ctx, _order)
-}
diff --git a/store/applications.yaml b/store/applications.yaml
deleted file mode 100644
index e19ae4769..000000000
--- a/store/applications.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Name, sortable: true }
- - { field: OwnerID }
- - { field: Enabled }
- - { field: Weight, sortable: true }
- - { field: Unify }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for application by ID
-
- It returns application even if deleted
-
-functions:
- - name: ApplicationMetrics
- return: [ "*types.ApplicationMetrics", "error" ]
-
- - name: ReorderApplications
- arguments:
- - { name: order, type: "[]uint64" }
- return: [ "error" ]
-
-
-rdbms:
- alias: app
- table: applications
- customFilterConverter: true
diff --git a/store/attachments.gen.go b/store/attachments.gen.go
deleted file mode 100644
index 108ec21a3..000000000
--- a/store/attachments.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/attachments.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Attachments interface {
- SearchAttachments(ctx context.Context, f types.AttachmentFilter) (types.AttachmentSet, types.AttachmentFilter, error)
- LookupAttachmentByID(ctx context.Context, id uint64) (*types.Attachment, error)
-
- CreateAttachment(ctx context.Context, rr ...*types.Attachment) error
-
- UpdateAttachment(ctx context.Context, rr ...*types.Attachment) error
-
- UpsertAttachment(ctx context.Context, rr ...*types.Attachment) error
-
- DeleteAttachment(ctx context.Context, rr ...*types.Attachment) error
- DeleteAttachmentByID(ctx context.Context, ID uint64) error
-
- TruncateAttachments(ctx context.Context) error
- }
-)
-
-var _ *types.Attachment
-var _ context.Context
-
-// SearchAttachments returns all matching Attachments from store
-func SearchAttachments(ctx context.Context, s Attachments, f types.AttachmentFilter) (types.AttachmentSet, types.AttachmentFilter, error) {
- return s.SearchAttachments(ctx, f)
-}
-
-// LookupAttachmentByID searches for attachment by its ID
-//
-// It returns attachment even if deleted
-func LookupAttachmentByID(ctx context.Context, s Attachments, id uint64) (*types.Attachment, error) {
- return s.LookupAttachmentByID(ctx, id)
-}
-
-// CreateAttachment creates one or more Attachments in store
-func CreateAttachment(ctx context.Context, s Attachments, rr ...*types.Attachment) error {
- return s.CreateAttachment(ctx, rr...)
-}
-
-// UpdateAttachment updates one or more (existing) Attachments in store
-func UpdateAttachment(ctx context.Context, s Attachments, rr ...*types.Attachment) error {
- return s.UpdateAttachment(ctx, rr...)
-}
-
-// UpsertAttachment creates new or updates existing one or more Attachments in store
-func UpsertAttachment(ctx context.Context, s Attachments, rr ...*types.Attachment) error {
- return s.UpsertAttachment(ctx, rr...)
-}
-
-// DeleteAttachment Deletes one or more Attachments from store
-func DeleteAttachment(ctx context.Context, s Attachments, rr ...*types.Attachment) error {
- return s.DeleteAttachment(ctx, rr...)
-}
-
-// DeleteAttachmentByID Deletes Attachment from store
-func DeleteAttachmentByID(ctx context.Context, s Attachments, ID uint64) error {
- return s.DeleteAttachmentByID(ctx, ID)
-}
-
-// TruncateAttachments Deletes all Attachments from store
-func TruncateAttachments(ctx context.Context, s Attachments) error {
- return s.TruncateAttachments(ctx)
-}
diff --git a/store/attachments.yaml b/store/attachments.yaml
deleted file mode 100644
index 457d19731..000000000
--- a/store/attachments.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-types:
- base: Attachment
-
-fields:
- - { field: ID }
- - { field: OwnerID }
- - { field: Kind }
- - { field: Url }
- - { field: PreviewUrl }
- - { field: Name }
- - { field: Meta }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for attachment by its ID
-
- It returns attachment even if deleted
-
-search:
- enableSorting: false
- enablePaging: false
-
-rdbms:
- alias: att
- table: attachments
- customFilterConverter: true
diff --git a/store/auth_clients.gen.go b/store/auth_clients.gen.go
deleted file mode 100644
index e7bcb7f22..000000000
--- a/store/auth_clients.gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/auth_clients.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- AuthClients interface {
- SearchAuthClients(ctx context.Context, f types.AuthClientFilter) (types.AuthClientSet, types.AuthClientFilter, error)
- LookupAuthClientByID(ctx context.Context, id uint64) (*types.AuthClient, error)
- LookupAuthClientByHandle(ctx context.Context, handle string) (*types.AuthClient, error)
-
- CreateAuthClient(ctx context.Context, rr ...*types.AuthClient) error
-
- UpdateAuthClient(ctx context.Context, rr ...*types.AuthClient) error
-
- UpsertAuthClient(ctx context.Context, rr ...*types.AuthClient) error
-
- DeleteAuthClient(ctx context.Context, rr ...*types.AuthClient) error
- DeleteAuthClientByID(ctx context.Context, ID uint64) error
-
- TruncateAuthClients(ctx context.Context) error
- }
-)
-
-var _ *types.AuthClient
-var _ context.Context
-
-// SearchAuthClients returns all matching AuthClients from store
-func SearchAuthClients(ctx context.Context, s AuthClients, f types.AuthClientFilter) (types.AuthClientSet, types.AuthClientFilter, error) {
- return s.SearchAuthClients(ctx, f)
-}
-
-// LookupAuthClientByID searches for auth client by ID
-//
-// It returns auth client even if deleted
-func LookupAuthClientByID(ctx context.Context, s AuthClients, id uint64) (*types.AuthClient, error) {
- return s.LookupAuthClientByID(ctx, id)
-}
-
-// LookupAuthClientByHandle searches for auth client by ID
-//
-// It returns auth client even if deleted
-func LookupAuthClientByHandle(ctx context.Context, s AuthClients, handle string) (*types.AuthClient, error) {
- return s.LookupAuthClientByHandle(ctx, handle)
-}
-
-// CreateAuthClient creates one or more AuthClients in store
-func CreateAuthClient(ctx context.Context, s AuthClients, rr ...*types.AuthClient) error {
- return s.CreateAuthClient(ctx, rr...)
-}
-
-// UpdateAuthClient updates one or more (existing) AuthClients in store
-func UpdateAuthClient(ctx context.Context, s AuthClients, rr ...*types.AuthClient) error {
- return s.UpdateAuthClient(ctx, rr...)
-}
-
-// UpsertAuthClient creates new or updates existing one or more AuthClients in store
-func UpsertAuthClient(ctx context.Context, s AuthClients, rr ...*types.AuthClient) error {
- return s.UpsertAuthClient(ctx, rr...)
-}
-
-// DeleteAuthClient Deletes one or more AuthClients from store
-func DeleteAuthClient(ctx context.Context, s AuthClients, rr ...*types.AuthClient) error {
- return s.DeleteAuthClient(ctx, rr...)
-}
-
-// DeleteAuthClientByID Deletes AuthClient from store
-func DeleteAuthClientByID(ctx context.Context, s AuthClients, ID uint64) error {
- return s.DeleteAuthClientByID(ctx, ID)
-}
-
-// TruncateAuthClients Deletes all AuthClients from store
-func TruncateAuthClients(ctx context.Context, s AuthClients) error {
- return s.TruncateAuthClients(ctx)
-}
diff --git a/store/auth_clients.yaml b/store/auth_clients.yaml
deleted file mode 100644
index 82571e52f..000000000
--- a/store/auth_clients.yaml
+++ /dev/null
@@ -1,45 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Handle, sortable: true }
- - { field: Meta, type: '*AuthClientMeta' }
- - { field: Secret }
- - { field: Scope }
- - { field: ValidGrant }
- - { field: RedirectURI }
- - { field: Trusted }
- - { field: Enabled }
- - { field: ValidFrom, type: timestamp }
- - { field: ExpiresAt, type: timestamp }
- - { field: Security, type: '*AuthClientSecurity' }
- - { field: OwnedBy }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for auth client by ID
-
- It returns auth client even if deleted
-
- - fields: [ Handle ]
- uniqueConstraintCheck: true
- filter: { DeletedAt: nil }
- description: |-
- searches for auth client by ID
-
- It returns auth client even if deleted
-
-rdbms:
- alias: ac
- table: auth_clients
- customFilterConverter: true
- mapFields:
- RedirectURI: { column: redirect_uri }
diff --git a/store/auth_confirmed_clients.gen.go b/store/auth_confirmed_clients.gen.go
deleted file mode 100644
index b7547f688..000000000
--- a/store/auth_confirmed_clients.gen.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/auth_confirmed_clients.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- AuthConfirmedClients interface {
- SearchAuthConfirmedClients(ctx context.Context, f types.AuthConfirmedClientFilter) (types.AuthConfirmedClientSet, types.AuthConfirmedClientFilter, error)
- LookupAuthConfirmedClientByUserIDClientID(ctx context.Context, user_id uint64, client_id uint64) (*types.AuthConfirmedClient, error)
-
- CreateAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) error
-
- UpdateAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) error
-
- UpsertAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) error
-
- DeleteAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) error
- DeleteAuthConfirmedClientByUserIDClientID(ctx context.Context, userID uint64, clientID uint64) error
-
- TruncateAuthConfirmedClients(ctx context.Context) error
- }
-)
-
-var _ *types.AuthConfirmedClient
-var _ context.Context
-
-// SearchAuthConfirmedClients returns all matching AuthConfirmedClients from store
-func SearchAuthConfirmedClients(ctx context.Context, s AuthConfirmedClients, f types.AuthConfirmedClientFilter) (types.AuthConfirmedClientSet, types.AuthConfirmedClientFilter, error) {
- return s.SearchAuthConfirmedClients(ctx, f)
-}
-
-// LookupAuthConfirmedClientByUserIDClientID
-func LookupAuthConfirmedClientByUserIDClientID(ctx context.Context, s AuthConfirmedClients, user_id uint64, client_id uint64) (*types.AuthConfirmedClient, error) {
- return s.LookupAuthConfirmedClientByUserIDClientID(ctx, user_id, client_id)
-}
-
-// CreateAuthConfirmedClient creates one or more AuthConfirmedClients in store
-func CreateAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*types.AuthConfirmedClient) error {
- return s.CreateAuthConfirmedClient(ctx, rr...)
-}
-
-// UpdateAuthConfirmedClient updates one or more (existing) AuthConfirmedClients in store
-func UpdateAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*types.AuthConfirmedClient) error {
- return s.UpdateAuthConfirmedClient(ctx, rr...)
-}
-
-// UpsertAuthConfirmedClient creates new or updates existing one or more AuthConfirmedClients in store
-func UpsertAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*types.AuthConfirmedClient) error {
- return s.UpsertAuthConfirmedClient(ctx, rr...)
-}
-
-// DeleteAuthConfirmedClient Deletes one or more AuthConfirmedClients from store
-func DeleteAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*types.AuthConfirmedClient) error {
- return s.DeleteAuthConfirmedClient(ctx, rr...)
-}
-
-// DeleteAuthConfirmedClientByUserIDClientID Deletes AuthConfirmedClient from store
-func DeleteAuthConfirmedClientByUserIDClientID(ctx context.Context, s AuthConfirmedClients, userID uint64, clientID uint64) error {
- return s.DeleteAuthConfirmedClientByUserIDClientID(ctx, userID, clientID)
-}
-
-// TruncateAuthConfirmedClients Deletes all AuthConfirmedClients from store
-func TruncateAuthConfirmedClients(ctx context.Context, s AuthConfirmedClients) error {
- return s.TruncateAuthConfirmedClients(ctx)
-}
diff --git a/store/auth_confirmed_clients.yaml b/store/auth_confirmed_clients.yaml
deleted file mode 100644
index 39b979933..000000000
--- a/store/auth_confirmed_clients.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: UserID, isPrimaryKey: true }
- - { field: ClientID, isPrimaryKey: true }
- - { field: ConfirmedAt }
-
-rdbms:
- alias: acc
- table: auth_confirmed_clients
- customFilterConverter: true
-
-lookups:
- - fields: [ UserID, ClientID ]
- uniqueConstraintCheck: true
-
-search:
- enableSorting: false
- enablePaging: false
- enableFilterCheckFunction: false
diff --git a/store/auth_oa2tokens.gen.go b/store/auth_oa2tokens.gen.go
deleted file mode 100644
index 52f9641bb..000000000
--- a/store/auth_oa2tokens.gen.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/auth_oa2tokens.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- AuthOa2tokens interface {
- SearchAuthOa2tokens(ctx context.Context, f types.AuthOa2tokenFilter) (types.AuthOa2tokenSet, types.AuthOa2tokenFilter, error)
- LookupAuthOa2tokenByID(ctx context.Context, id uint64) (*types.AuthOa2token, error)
- LookupAuthOa2tokenByCode(ctx context.Context, code string) (*types.AuthOa2token, error)
- LookupAuthOa2tokenByAccess(ctx context.Context, access string) (*types.AuthOa2token, error)
- LookupAuthOa2tokenByRefresh(ctx context.Context, refresh string) (*types.AuthOa2token, error)
-
- CreateAuthOa2token(ctx context.Context, rr ...*types.AuthOa2token) error
-
- DeleteAuthOa2token(ctx context.Context, rr ...*types.AuthOa2token) error
- DeleteAuthOa2tokenByID(ctx context.Context, ID uint64) error
-
- TruncateAuthOa2tokens(ctx context.Context) error
-
- // Additional custom functions
-
- // DeleteExpiredAuthOA2Tokens (custom function)
- DeleteExpiredAuthOA2Tokens(ctx context.Context) error
-
- // DeleteAuthOA2TokenByCode (custom function)
- DeleteAuthOA2TokenByCode(ctx context.Context, _code string) error
-
- // DeleteAuthOA2TokenByAccess (custom function)
- DeleteAuthOA2TokenByAccess(ctx context.Context, _access string) error
-
- // DeleteAuthOA2TokenByRefresh (custom function)
- DeleteAuthOA2TokenByRefresh(ctx context.Context, _refresh string) error
-
- // DeleteAuthOA2TokenByUserID (custom function)
- DeleteAuthOA2TokenByUserID(ctx context.Context, _userID uint64) error
- }
-)
-
-var _ *types.AuthOa2token
-var _ context.Context
-
-// SearchAuthOa2tokens returns all matching AuthOa2tokens from store
-func SearchAuthOa2tokens(ctx context.Context, s AuthOa2tokens, f types.AuthOa2tokenFilter) (types.AuthOa2tokenSet, types.AuthOa2tokenFilter, error) {
- return s.SearchAuthOa2tokens(ctx, f)
-}
-
-// LookupAuthOa2tokenByID
-func LookupAuthOa2tokenByID(ctx context.Context, s AuthOa2tokens, id uint64) (*types.AuthOa2token, error) {
- return s.LookupAuthOa2tokenByID(ctx, id)
-}
-
-// LookupAuthOa2tokenByCode
-func LookupAuthOa2tokenByCode(ctx context.Context, s AuthOa2tokens, code string) (*types.AuthOa2token, error) {
- return s.LookupAuthOa2tokenByCode(ctx, code)
-}
-
-// LookupAuthOa2tokenByAccess
-func LookupAuthOa2tokenByAccess(ctx context.Context, s AuthOa2tokens, access string) (*types.AuthOa2token, error) {
- return s.LookupAuthOa2tokenByAccess(ctx, access)
-}
-
-// LookupAuthOa2tokenByRefresh
-func LookupAuthOa2tokenByRefresh(ctx context.Context, s AuthOa2tokens, refresh string) (*types.AuthOa2token, error) {
- return s.LookupAuthOa2tokenByRefresh(ctx, refresh)
-}
-
-// CreateAuthOa2token creates one or more AuthOa2tokens in store
-func CreateAuthOa2token(ctx context.Context, s AuthOa2tokens, rr ...*types.AuthOa2token) error {
- return s.CreateAuthOa2token(ctx, rr...)
-}
-
-// DeleteAuthOa2token Deletes one or more AuthOa2tokens from store
-func DeleteAuthOa2token(ctx context.Context, s AuthOa2tokens, rr ...*types.AuthOa2token) error {
- return s.DeleteAuthOa2token(ctx, rr...)
-}
-
-// DeleteAuthOa2tokenByID Deletes AuthOa2token from store
-func DeleteAuthOa2tokenByID(ctx context.Context, s AuthOa2tokens, ID uint64) error {
- return s.DeleteAuthOa2tokenByID(ctx, ID)
-}
-
-// TruncateAuthOa2tokens Deletes all AuthOa2tokens from store
-func TruncateAuthOa2tokens(ctx context.Context, s AuthOa2tokens) error {
- return s.TruncateAuthOa2tokens(ctx)
-}
-
-func DeleteExpiredAuthOA2Tokens(ctx context.Context, s AuthOa2tokens) error {
- return s.DeleteExpiredAuthOA2Tokens(ctx)
-}
-
-func DeleteAuthOA2TokenByCode(ctx context.Context, s AuthOa2tokens, _code string) error {
- return s.DeleteAuthOA2TokenByCode(ctx, _code)
-}
-
-func DeleteAuthOA2TokenByAccess(ctx context.Context, s AuthOa2tokens, _access string) error {
- return s.DeleteAuthOA2TokenByAccess(ctx, _access)
-}
-
-func DeleteAuthOA2TokenByRefresh(ctx context.Context, s AuthOa2tokens, _refresh string) error {
- return s.DeleteAuthOA2TokenByRefresh(ctx, _refresh)
-}
-
-func DeleteAuthOA2TokenByUserID(ctx context.Context, s AuthOa2tokens, _userID uint64) error {
- return s.DeleteAuthOA2TokenByUserID(ctx, _userID)
-}
diff --git a/store/auth_oa2tokens.yaml b/store/auth_oa2tokens.yaml
deleted file mode 100644
index 58a4ea28b..000000000
--- a/store/auth_oa2tokens.yaml
+++ /dev/null
@@ -1,61 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Code }
- - { field: Access }
- - { field: Refresh }
- - { field: ExpiresAt }
- - { field: CreatedAt }
- - { field: Data }
- - { field: ClientID }
- - { field: UserID }
- - { field: RemoteAddr }
- - { field: UserAgent }
-
-rdbms:
- alias: tkn
- table: auth_oa2tokens
- customFilterConverter: true
-
-lookups:
- - fields: [ ID ]
- - fields: [ Code ]
- uniqueConstraintCheck: true
- - fields: [ Access ]
- uniqueConstraintCheck: true
- - fields: [ Refresh ]
- uniqueConstraintCheck: true
-
-functions:
- - name: DeleteExpiredAuthOA2Tokens
- return: [ error ]
-
- - name: DeleteAuthOA2TokenByCode
- return: [ error ]
- arguments:
- - { name: code, type: string }
-
- - name: DeleteAuthOA2TokenByAccess
- return: [ error ]
- arguments:
- - { name: access, type: string }
-
- - name: DeleteAuthOA2TokenByRefresh
- return: [ error ]
- arguments:
- - { name: refresh, type: string }
-
- - name: DeleteAuthOA2TokenByUserID
- return: [ error ]
- arguments:
- - { name: userID, type: uint64 }
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
-
-update: { enable: false }
-upsert: { enable: false }
diff --git a/store/auth_sessions.gen.go b/store/auth_sessions.gen.go
deleted file mode 100644
index 8cd024e8d..000000000
--- a/store/auth_sessions.gen.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/auth_sessions.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- AuthSessions interface {
- SearchAuthSessions(ctx context.Context, f types.AuthSessionFilter) (types.AuthSessionSet, types.AuthSessionFilter, error)
- LookupAuthSessionByID(ctx context.Context, id string) (*types.AuthSession, error)
-
- CreateAuthSession(ctx context.Context, rr ...*types.AuthSession) error
-
- UpdateAuthSession(ctx context.Context, rr ...*types.AuthSession) error
-
- UpsertAuthSession(ctx context.Context, rr ...*types.AuthSession) error
-
- DeleteAuthSession(ctx context.Context, rr ...*types.AuthSession) error
- DeleteAuthSessionByID(ctx context.Context, ID string) error
-
- TruncateAuthSessions(ctx context.Context) error
-
- // Additional custom functions
-
- // DeleteExpiredAuthSessions (custom function)
- DeleteExpiredAuthSessions(ctx context.Context) error
-
- // DeleteAuthSessionsByUserID (custom function)
- DeleteAuthSessionsByUserID(ctx context.Context, _userID uint64) error
- }
-)
-
-var _ *types.AuthSession
-var _ context.Context
-
-// SearchAuthSessions returns all matching AuthSessions from store
-func SearchAuthSessions(ctx context.Context, s AuthSessions, f types.AuthSessionFilter) (types.AuthSessionSet, types.AuthSessionFilter, error) {
- return s.SearchAuthSessions(ctx, f)
-}
-
-// LookupAuthSessionByID
-func LookupAuthSessionByID(ctx context.Context, s AuthSessions, id string) (*types.AuthSession, error) {
- return s.LookupAuthSessionByID(ctx, id)
-}
-
-// CreateAuthSession creates one or more AuthSessions in store
-func CreateAuthSession(ctx context.Context, s AuthSessions, rr ...*types.AuthSession) error {
- return s.CreateAuthSession(ctx, rr...)
-}
-
-// UpdateAuthSession updates one or more (existing) AuthSessions in store
-func UpdateAuthSession(ctx context.Context, s AuthSessions, rr ...*types.AuthSession) error {
- return s.UpdateAuthSession(ctx, rr...)
-}
-
-// UpsertAuthSession creates new or updates existing one or more AuthSessions in store
-func UpsertAuthSession(ctx context.Context, s AuthSessions, rr ...*types.AuthSession) error {
- return s.UpsertAuthSession(ctx, rr...)
-}
-
-// DeleteAuthSession Deletes one or more AuthSessions from store
-func DeleteAuthSession(ctx context.Context, s AuthSessions, rr ...*types.AuthSession) error {
- return s.DeleteAuthSession(ctx, rr...)
-}
-
-// DeleteAuthSessionByID Deletes AuthSession from store
-func DeleteAuthSessionByID(ctx context.Context, s AuthSessions, ID string) error {
- return s.DeleteAuthSessionByID(ctx, ID)
-}
-
-// TruncateAuthSessions Deletes all AuthSessions from store
-func TruncateAuthSessions(ctx context.Context, s AuthSessions) error {
- return s.TruncateAuthSessions(ctx)
-}
-
-func DeleteExpiredAuthSessions(ctx context.Context, s AuthSessions) error {
- return s.DeleteExpiredAuthSessions(ctx)
-}
-
-func DeleteAuthSessionsByUserID(ctx context.Context, s AuthSessions, _userID uint64) error {
- return s.DeleteAuthSessionsByUserID(ctx, _userID)
-}
diff --git a/store/auth_sessions.yaml b/store/auth_sessions.yaml
deleted file mode 100644
index 552e8af45..000000000
--- a/store/auth_sessions.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID, type: string, isPrimaryKey: true }
- - { field: Data }
- - { field: UserID }
- - { field: RemoteAddr }
- - { field: UserAgent }
- - { field: CreatedAt }
- - { field: ExpiresAt }
-
-rdbms:
- alias: ses
- table: auth_sessions
- customFilterConverter: true
-
-lookups:
- - fields: [ ID ]
- uniqueConstraintCheck: true
-
-functions:
- - name: DeleteExpiredAuthSessions
- return: [ error ]
- - name: DeleteAuthSessionsByUserID
- return: [ error ]
- arguments:
- - { name: userID, type: uint64 }
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
diff --git a/store/automation_sessions.gen.go b/store/automation_sessions.gen.go
deleted file mode 100644
index f26b7e157..000000000
--- a/store/automation_sessions.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/automation_sessions.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/automation/types"
-)
-
-type (
- AutomationSessions interface {
- SearchAutomationSessions(ctx context.Context, f types.SessionFilter) (types.SessionSet, types.SessionFilter, error)
- LookupAutomationSessionByID(ctx context.Context, id uint64) (*types.Session, error)
-
- CreateAutomationSession(ctx context.Context, rr ...*types.Session) error
-
- UpdateAutomationSession(ctx context.Context, rr ...*types.Session) error
-
- UpsertAutomationSession(ctx context.Context, rr ...*types.Session) error
-
- DeleteAutomationSession(ctx context.Context, rr ...*types.Session) error
- DeleteAutomationSessionByID(ctx context.Context, ID uint64) error
-
- TruncateAutomationSessions(ctx context.Context) error
- }
-)
-
-var _ *types.Session
-var _ context.Context
-
-// SearchAutomationSessions returns all matching AutomationSessions from store
-func SearchAutomationSessions(ctx context.Context, s AutomationSessions, f types.SessionFilter) (types.SessionSet, types.SessionFilter, error) {
- return s.SearchAutomationSessions(ctx, f)
-}
-
-// LookupAutomationSessionByID searches for session by ID
-//
-// It returns session even if deleted
-func LookupAutomationSessionByID(ctx context.Context, s AutomationSessions, id uint64) (*types.Session, error) {
- return s.LookupAutomationSessionByID(ctx, id)
-}
-
-// CreateAutomationSession creates one or more AutomationSessions in store
-func CreateAutomationSession(ctx context.Context, s AutomationSessions, rr ...*types.Session) error {
- return s.CreateAutomationSession(ctx, rr...)
-}
-
-// UpdateAutomationSession updates one or more (existing) AutomationSessions in store
-func UpdateAutomationSession(ctx context.Context, s AutomationSessions, rr ...*types.Session) error {
- return s.UpdateAutomationSession(ctx, rr...)
-}
-
-// UpsertAutomationSession creates new or updates existing one or more AutomationSessions in store
-func UpsertAutomationSession(ctx context.Context, s AutomationSessions, rr ...*types.Session) error {
- return s.UpsertAutomationSession(ctx, rr...)
-}
-
-// DeleteAutomationSession Deletes one or more AutomationSessions from store
-func DeleteAutomationSession(ctx context.Context, s AutomationSessions, rr ...*types.Session) error {
- return s.DeleteAutomationSession(ctx, rr...)
-}
-
-// DeleteAutomationSessionByID Deletes AutomationSession from store
-func DeleteAutomationSessionByID(ctx context.Context, s AutomationSessions, ID uint64) error {
- return s.DeleteAutomationSessionByID(ctx, ID)
-}
-
-// TruncateAutomationSessions Deletes all AutomationSessions from store
-func TruncateAutomationSessions(ctx context.Context, s AutomationSessions) error {
- return s.TruncateAutomationSessions(ctx)
-}
diff --git a/store/automation_sessions.yaml b/store/automation_sessions.yaml
deleted file mode 100644
index a40618c4c..000000000
--- a/store/automation_sessions.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/automation/types
-
-types:
- type: types.Session
-
-fields:
- - { field: ID }
- - { field: WorkflowID }
- - { field: EventType, sortable: true }
- - { field: ResourceType, sortable: true }
- - { field: Status, type: int, sortable: true }
- - { field: Input, type: "expr.Vars" }
- - { field: Output, type: "expr.Vars" }
- - { field: Stacktrace, type: "types.Stacktrace" }
- - { field: CreatedBy }
- - { field: CreatedAt, sortable: true }
- - { field: PurgeAt }
- - { field: CompletedAt, sortable: true }
- - { field: SuspendedAt, sortable: true }
- - { field: Error }
-
-rdbms:
- alias: atms
- table: automation_sessions
- customFilterConverter: true
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for session by ID
-
- It returns session even if deleted
diff --git a/store/automation_triggers.gen.go b/store/automation_triggers.gen.go
deleted file mode 100644
index c32554790..000000000
--- a/store/automation_triggers.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/automation_triggers.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/automation/types"
-)
-
-type (
- AutomationTriggers interface {
- SearchAutomationTriggers(ctx context.Context, f types.TriggerFilter) (types.TriggerSet, types.TriggerFilter, error)
- LookupAutomationTriggerByID(ctx context.Context, id uint64) (*types.Trigger, error)
-
- CreateAutomationTrigger(ctx context.Context, rr ...*types.Trigger) error
-
- UpdateAutomationTrigger(ctx context.Context, rr ...*types.Trigger) error
-
- UpsertAutomationTrigger(ctx context.Context, rr ...*types.Trigger) error
-
- DeleteAutomationTrigger(ctx context.Context, rr ...*types.Trigger) error
- DeleteAutomationTriggerByID(ctx context.Context, ID uint64) error
-
- TruncateAutomationTriggers(ctx context.Context) error
- }
-)
-
-var _ *types.Trigger
-var _ context.Context
-
-// SearchAutomationTriggers returns all matching AutomationTriggers from store
-func SearchAutomationTriggers(ctx context.Context, s AutomationTriggers, f types.TriggerFilter) (types.TriggerSet, types.TriggerFilter, error) {
- return s.SearchAutomationTriggers(ctx, f)
-}
-
-// LookupAutomationTriggerByID searches for trigger by ID
-//
-// It returns trigger even if deleted
-func LookupAutomationTriggerByID(ctx context.Context, s AutomationTriggers, id uint64) (*types.Trigger, error) {
- return s.LookupAutomationTriggerByID(ctx, id)
-}
-
-// CreateAutomationTrigger creates one or more AutomationTriggers in store
-func CreateAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*types.Trigger) error {
- return s.CreateAutomationTrigger(ctx, rr...)
-}
-
-// UpdateAutomationTrigger updates one or more (existing) AutomationTriggers in store
-func UpdateAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*types.Trigger) error {
- return s.UpdateAutomationTrigger(ctx, rr...)
-}
-
-// UpsertAutomationTrigger creates new or updates existing one or more AutomationTriggers in store
-func UpsertAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*types.Trigger) error {
- return s.UpsertAutomationTrigger(ctx, rr...)
-}
-
-// DeleteAutomationTrigger Deletes one or more AutomationTriggers from store
-func DeleteAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*types.Trigger) error {
- return s.DeleteAutomationTrigger(ctx, rr...)
-}
-
-// DeleteAutomationTriggerByID Deletes AutomationTrigger from store
-func DeleteAutomationTriggerByID(ctx context.Context, s AutomationTriggers, ID uint64) error {
- return s.DeleteAutomationTriggerByID(ctx, ID)
-}
-
-// TruncateAutomationTriggers Deletes all AutomationTriggers from store
-func TruncateAutomationTriggers(ctx context.Context, s AutomationTriggers) error {
- return s.TruncateAutomationTriggers(ctx)
-}
diff --git a/store/automation_triggers.yaml b/store/automation_triggers.yaml
deleted file mode 100644
index 838c6fca5..000000000
--- a/store/automation_triggers.yaml
+++ /dev/null
@@ -1,35 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/automation/types
-
-types:
- type: types.Trigger
-
-fields:
- - { field: ID }
- - { field: WorkflowID }
- - { field: StepID }
- - { field: Enabled, type: bool }
- - { field: ResourceType }
- - { field: EventType }
- - { field: Meta, type: "types.TriggerMeta" }
- - { field: Constraints, type: "json.Text" }
- - { field: Input, type: "expr.Vars" }
- - { field: OwnedBy }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-rdbms:
- alias: atmt
- table: automation_triggers
- customFilterConverter: true
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for trigger by ID
-
- It returns trigger even if deleted
diff --git a/store/automation_workflows.gen.go b/store/automation_workflows.gen.go
deleted file mode 100644
index 753c05c54..000000000
--- a/store/automation_workflows.gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/automation_workflows.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/automation/types"
-)
-
-type (
- AutomationWorkflows interface {
- SearchAutomationWorkflows(ctx context.Context, f types.WorkflowFilter) (types.WorkflowSet, types.WorkflowFilter, error)
- LookupAutomationWorkflowByID(ctx context.Context, id uint64) (*types.Workflow, error)
- LookupAutomationWorkflowByHandle(ctx context.Context, handle string) (*types.Workflow, error)
-
- CreateAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) error
-
- UpdateAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) error
-
- UpsertAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) error
-
- DeleteAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) error
- DeleteAutomationWorkflowByID(ctx context.Context, ID uint64) error
-
- TruncateAutomationWorkflows(ctx context.Context) error
- }
-)
-
-var _ *types.Workflow
-var _ context.Context
-
-// SearchAutomationWorkflows returns all matching AutomationWorkflows from store
-func SearchAutomationWorkflows(ctx context.Context, s AutomationWorkflows, f types.WorkflowFilter) (types.WorkflowSet, types.WorkflowFilter, error) {
- return s.SearchAutomationWorkflows(ctx, f)
-}
-
-// LookupAutomationWorkflowByID searches for workflow by ID
-//
-// It returns workflow even if deleted
-func LookupAutomationWorkflowByID(ctx context.Context, s AutomationWorkflows, id uint64) (*types.Workflow, error) {
- return s.LookupAutomationWorkflowByID(ctx, id)
-}
-
-// LookupAutomationWorkflowByHandle searches for workflow by their handle
-//
-// It returns only valid workflows
-func LookupAutomationWorkflowByHandle(ctx context.Context, s AutomationWorkflows, handle string) (*types.Workflow, error) {
- return s.LookupAutomationWorkflowByHandle(ctx, handle)
-}
-
-// CreateAutomationWorkflow creates one or more AutomationWorkflows in store
-func CreateAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*types.Workflow) error {
- return s.CreateAutomationWorkflow(ctx, rr...)
-}
-
-// UpdateAutomationWorkflow updates one or more (existing) AutomationWorkflows in store
-func UpdateAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*types.Workflow) error {
- return s.UpdateAutomationWorkflow(ctx, rr...)
-}
-
-// UpsertAutomationWorkflow creates new or updates existing one or more AutomationWorkflows in store
-func UpsertAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*types.Workflow) error {
- return s.UpsertAutomationWorkflow(ctx, rr...)
-}
-
-// DeleteAutomationWorkflow Deletes one or more AutomationWorkflows from store
-func DeleteAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*types.Workflow) error {
- return s.DeleteAutomationWorkflow(ctx, rr...)
-}
-
-// DeleteAutomationWorkflowByID Deletes AutomationWorkflow from store
-func DeleteAutomationWorkflowByID(ctx context.Context, s AutomationWorkflows, ID uint64) error {
- return s.DeleteAutomationWorkflowByID(ctx, ID)
-}
-
-// TruncateAutomationWorkflows Deletes all AutomationWorkflows from store
-func TruncateAutomationWorkflows(ctx context.Context, s AutomationWorkflows) error {
- return s.TruncateAutomationWorkflows(ctx)
-}
diff --git a/store/automation_workflows.yaml b/store/automation_workflows.yaml
deleted file mode 100644
index 3ca91a7ff..000000000
--- a/store/automation_workflows.yaml
+++ /dev/null
@@ -1,44 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/automation/types
-
-types:
- type: types.Workflow
-
-fields:
- - { field: ID }
- - { field: Handle, unique: true, lookupFilterPreprocessor: lower, sortable: true }
- - { field: Meta, type: "types.WorkflowMeta" }
- - { field: Enabled, type: bool, sortable: true }
- - { field: Trace, type: bool }
- - { field: KeepSessions, type: "time.Duration" }
- - { field: Scope, type: "expr.Vars" }
- - { field: Steps, type: "expr.Vars" }
- - { field: Paths, type: "expr.Vars" }
- - { field: Issues, type: "WorkflowIssueSet" }
- - { field: RunAs, type: "uint64" }
- - { field: OwnedBy }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-rdbms:
- alias: atmwf
- table: automation_workflows
- customFilterConverter: true
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for workflow by ID
-
- It returns workflow even if deleted
- - fields: [ Handle ]
- filter: { DeletedAt: nil }
- uniqueConstraintCheck: true
- description: |-
- searches for workflow by their handle
-
- It returns only valid workflows
diff --git a/store/cockroach/cockroach.go b/store/cockroach/cockroach.go
deleted file mode 100644
index 62be3e5ce..000000000
--- a/store/cockroach/cockroach.go
+++ /dev/null
@@ -1,116 +0,0 @@
-package cockroach
-
-import (
- "context"
- "database/sql"
- "fmt"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/instrumentation"
- "github.com/lib/pq"
- "github.com/ngrok/sqlmw"
- "go.uber.org/zap"
- "net/url"
- "strings"
-)
-
-type (
- Store struct {
- *rdbms.Store
- }
-)
-
-const (
- storeTypeName = "cockroachdb"
- storeTypeWithDebug = "cockroachdb+debug"
-)
-
-// For now, CockroachDB implementation is disabled due to some limitation from cockroachDB!
-//
-// Here is why could not work on this further:
-// * Prefix/Expression Indexes.
-// I.e. we are not able to use "lower" expression while creating/updating indexes
-// * Not able to use Prefix/Expression into upsert.
-// I.e. also not able to use "lower"(for most case) expression in upsert
-//
-// @note we could enable this once cockroachDB overcome above limitations :)
-func init() {
- store.Register(Connect, storeTypeName, storeTypeWithDebug)
- sql.Register(storeTypeWithDebug, sqlmw.Driver(new(pq.Driver), instrumentation.Debug()))
-}
-
-func Connect(ctx context.Context, dsn string) (store.Storer, error) {
- var (
- err error
- cfg *rdbms.Config
-
- s = new(Store)
- )
-
- if cfg, err = ProcDataSourceName(dsn); err != nil {
- return nil, err
- }
-
- cfg.PlaceholderFormat = squirrel.Dollar
- cfg.ErrorHandler = errorHandler
- cfg.SqlFunctionHandler = sqlFunctionHandler
- cfg.CastModuleFieldToColumnType = fieldToColumnTypeCaster
-
- if s.Store, err = rdbms.Connect(ctx, cfg); err != nil {
- return nil, err
- }
-
- ql.QueryEncoder = &QueryEncoder{}
-
- return s, nil
-}
-
-func (s *Store) Upgrade(ctx context.Context, log *zap.Logger) (err error) {
- if err = (&rdbms.Schema{}).Upgrade(ctx, NewUpgrader(log, s)); err != nil {
- return fmt.Errorf("can not upgrade cockroach schema: %w", err)
- }
-
- return nil
-}
-
-// ProcDataSourceName validates given DSN and ensures
-// params are present and correct
-func ProcDataSourceName(dsn string) (c *rdbms.Config, err error) {
- const (
- validScheme = "postgres"
- )
- var (
- scheme string
- u *url.URL
- )
-
- if u, err = url.Parse(dsn); err != nil {
- return nil, err
- }
-
- if strings.HasPrefix(dsn, storeTypeName) {
- scheme = validScheme
- u.Scheme = validScheme
- }
-
- return &rdbms.Config{
- DriverName: scheme,
- DataSourceName: u.String(),
- DBName: strings.Trim(u.Path, "/"),
- }, nil
-}
-
-func errorHandler(err error) error {
- if err != nil {
- if implErr, ok := err.(*pq.Error); ok {
- switch implErr.Code.Name() {
- case "unique_violation":
- return store.ErrNotUnique.Wrap(implErr)
- }
- }
- }
-
- return err
-}
diff --git a/store/cockroach/encoder.go b/store/cockroach/encoder.go
deleted file mode 100644
index d3686801c..000000000
--- a/store/cockroach/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package cockroach
-
-import "github.com/cortezaproject/corteza-server/pkg/ql"
-
-type (
- // QueryEncoder provides query parts encoding rules for CockroachDB
- // see ql.QueryEncoder for mor info
- QueryEncoder struct{}
-)
-
-var _ ql.Encoder = &QueryEncoder{}
-
-func (QueryEncoder) CaseInsensitiveLike(neg bool) string {
- if neg {
- return "NOT ILIKE"
- } else {
- return "ILIKE"
- }
-}
diff --git a/store/cockroach/sql_functions.go b/store/cockroach/sql_functions.go
deleted file mode 100644
index f44bc97e9..000000000
--- a/store/cockroach/sql_functions.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package cockroach
-
-import (
- "fmt"
- "strings"
-
- "github.com/cortezaproject/corteza-server/pkg/ql"
-)
-
-func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) {
- switch strings.ToUpper(f.Name) {
- case "QUARTER", "YEAR":
- return ql.MakeFormattedNode(fmt.Sprintf("EXTRACT(%s FROM %%s::date)", f.Name), f.Arguments...), nil
- case "DATE_FORMAT":
- return ql.MakeFormattedNode("TO_CHAR(%s::TIMESTAMPTZ, %s::TEXT)", f.Arguments...), nil
- case "DATE":
- return ql.MakeFormattedNode("%s::DATE", f.Arguments...), nil
- case "DATE_ADD", "DATE_SUB", "STD":
- return nil, fmt.Errorf("%q function is currently unsupported in PostgreSQL store backend", f.Name)
- }
-
- return f, nil
-}
diff --git a/store/cockroach/sql_typecasters.go b/store/cockroach/sql_typecasters.go
deleted file mode 100644
index 79f1e01ac..000000000
--- a/store/cockroach/sql_typecasters.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package cockroach
-
-import (
- "fmt"
-
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-// fieldToColumnTypeCaster handles special ComposeModule field query representations
-// @todo Not as elegant as it should be but it'll do the trick until the #2 store iteration
-//
-// Return parameters:
-// * full cast: query column + datatype cast
-// * field cast tpl: fmt template to get query column
-// * type cast tpl: fmt template to cast the compared to value
-func fieldToColumnTypeCaster(field rdbms.ModuleFieldTypeDetector, ident string) (string, string, string, error) {
- fcp := "rv_%s.value"
- fcpRef := "rv_%s.ref"
-
- switch true {
- case field.IsBoolean():
- tcp := "%s NOT IN ('', '0', 'false', 'f', 'FALSE', 'F')"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsNumeric():
- tcp := "CAST('0' || %s AS NUMERIC)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsDateTime():
- tcp := "CAST(%s AS TIMESTAMP)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsDateOnly():
- tcp := "CAST(%s AS DATE)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsTimeOnly():
- tcp := "CAST(%s AS TIME)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsRef():
- tcp := "%s"
- fc := fmt.Sprintf(fcpRef, ident)
- return fmt.Sprintf(tcp, fc), fcpRef, tcp, nil
- }
- tcp := "%s"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
-}
diff --git a/store/cockroach/upgrade.go b/store/cockroach/upgrade.go
deleted file mode 100644
index c085e8787..000000000
--- a/store/cockroach/upgrade.go
+++ /dev/null
@@ -1,267 +0,0 @@
-package cockroach
-
-// PostgreSQL specific prefixes, sql
-// templates, functions and other helpers
-
-import (
- "context"
- "fmt"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
- "go.uber.org/zap"
-)
-
-type (
- upgrader struct {
- s *Store
- log *zap.Logger
- ddl *ddl.Generator
- }
-)
-
-// NewUpgrader returns PostgreSQL schema upgrader
-func NewUpgrader(log *zap.Logger, store *Store) *upgrader {
- var g = &upgrader{store, log, ddl.NewGenerator(log)}
-
- // All modifications we need for the DDL generator
- // to properly support CockroachDB dialect
-
- g.ddl.AddTemplate("index-fields", `
- ({{ range $n, $f := . -}}
- {{ if $n }}, {{ end }}
- {{- .Field | trimExpression}}
- {{- if .Desc }} DESC{{ end }}
- {{- end }})
- `)
- g.ddl.AddTemplate("if-not-exists-clause", "IF NOT EXISTS")
-
- return g
-}
-
-// Before runs before all tables are upgraded
-func (u upgrader) Before(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).Before(ctx)
-}
-
-// After runs after all tables are upgraded
-func (u upgrader) After(ctx context.Context) error {
- return rdbms.GenericUpgrades(u.log, u).After(ctx)
-}
-
-// CreateTable is triggered for every table defined in the rdbms package
-//
-// It checks if table is missing and creates it, otherwise
-// it runs
-func (u upgrader) CreateTable(ctx context.Context, t *ddl.Table) (err error) {
- var exists bool
- if exists, err = u.TableExists(ctx, t.Name); err != nil {
- return
- }
-
- if !exists {
- if err = u.Exec(ctx, u.ddl.CreateTable(t)); err != nil {
- return err
- }
-
- for _, i := range t.Indexes {
- if err = u.Exec(ctx, u.ddl.CreateIndex(i)); err != nil {
- return fmt.Errorf("could not create index %s on table %s: %w", i.Name, i.Table, err)
- }
- }
- } else {
- return u.upgradeTable(ctx, t)
- }
-
- return nil
-}
-
-func (u upgrader) Exec(ctx context.Context, sql string, aa ...interface{}) error {
- _, err := u.s.DB().ExecContext(ctx, sql, aa...)
- return err
-}
-
-// upgradeTable applies any necessary changes connected to that specific table
-func (u upgrader) upgradeTable(ctx context.Context, t *ddl.Table) error {
- g := rdbms.GenericUpgrades(u.log, u)
-
- switch t.Name {
- default:
- return g.Upgrade(ctx, t)
- }
-}
-
-func (u upgrader) TableExists(ctx context.Context, table string) (bool, error) {
- //const tableSchemaName = "public"
- var exists bool
- // @todo use pq.NewError(regex?!) -> ADDED IF NOT EXISTS
- //if err := u.s.DB().GetContext(ctx, &exists, fmt.Sprintf("SELECT * FROM %[1]s.%[2]s", tableSchemaName, table)); err != nil {
- // if err.Error() == fmt.Sprintf("pq: relation \"%[1]s.%[2]s\" does not exist", tableSchemaName, table) {
- // exists = false
- // } else {
- // return false, fmt.Errorf("could not check if table exists: %w", err)
- // }
- //}
-
- return exists, nil
-}
-
-func (u upgrader) DropTable(ctx context.Context, table string) (dropped bool, err error) {
- var exists bool
- exists, err = u.TableExists(ctx, table)
- if err != nil || !exists {
- return false, err
- }
-
- err = u.Exec(ctx, fmt.Sprintf(`DROP TABLE %s`, table))
- if err != nil {
- return false, err
- }
-
- return true, nil
-}
-
-func (u upgrader) TableSchema(ctx context.Context, table string) (ddl.Columns, error) {
- return nil, fmt.Errorf("pending implementation")
-}
-
-// AddColumn adds column to table
-func (u upgrader) AddColumn(ctx context.Context, table string, col *ddl.Column) (added bool, err error) {
- err = func() error {
- var columns ddl.Columns
- if columns, err = u.getColumns(ctx, table); err != nil {
- return err
- }
-
- if columns.Get(col.Name) != nil {
- return nil
- }
-
- if err = u.Exec(ctx, u.ddl.AddColumn(table, col)); err != nil {
- return err
- }
-
- added = true
- return nil
- }()
-
- if err != nil {
- return false, fmt.Errorf("could not add column %q to %q: %w", col.Name, table, err)
- }
-
- return
-}
-
-// DropColumn drops column from table
-func (u upgrader) DropColumn(ctx context.Context, table, column string) (dropped bool, err error) {
- err = func() error {
- var columns ddl.Columns
- if columns, err = u.getColumns(ctx, table); err != nil {
- return err
- }
-
- if columns.Get(column) == nil {
- return nil
- }
-
- if err = u.Exec(ctx, u.ddl.DropColumn(table, column)); err != nil {
- return err
- }
-
- dropped = true
- return nil
- }()
-
- if err != nil {
- return false, fmt.Errorf("could not drop column %q from %q: %w", column, table, err)
- }
-
- return
-}
-
-// RenameColumn renames column on a table
-func (u upgrader) RenameColumn(ctx context.Context, table, oldName, newName string) (changed bool, err error) {
- err = func() error {
- if oldName == newName {
- return nil
- }
-
- var columns ddl.Columns
- if columns, err = u.getColumns(ctx, table); err != nil {
- return err
- }
-
- if columns.Get(oldName) == nil {
- // Old column does not exist anymore
-
- if columns.Get(newName) == nil {
- return fmt.Errorf("old and new columns are missing")
- }
-
- return nil
- }
-
- if columns.Get(newName) != nil {
- return fmt.Errorf("new column already exists")
-
- }
-
- if err = u.Exec(ctx, u.ddl.RenameColumn(table, oldName, newName)); err != nil {
- return err
- }
-
- changed = true
- return nil
- }()
-
- if err != nil {
- return false, fmt.Errorf("could not rename column %q on table %q to %q: %w", oldName, table, newName, err)
- }
-
- return
-}
-
-func (u upgrader) AddPrimaryKey(ctx context.Context, table string, ind *ddl.Index) (added bool, err error) {
- if err = u.Exec(ctx, u.ddl.AddPrimaryKey(table, ind)); err != nil {
- return false, fmt.Errorf("could not add primary key to table %s: %w", table, err)
- }
-
- return true, nil
-}
-
-// loads and returns all tables columns
-func (u upgrader) getColumns(ctx context.Context, table string) (out ddl.Columns, err error) {
- type (
- col struct {
- Name string `db:"column_name"`
- IsNullable bool `db:"is_nullable"`
- DataType string `db:"data_type"`
- }
- )
-
- var (
- lookup = `SELECT column_name,
- is_nullable = 'YES' AS is_nullable,
- data_type
- FROM information_schema.columns
- WHERE table_catalog = $1
- AND table_name = $2`
-
- cols []*col
- )
-
- if err = u.s.DB().SelectContext(ctx, &cols, lookup, u.s.Config().DBName, table); err != nil {
- return nil, err
- }
-
- out = make([]*ddl.Column, len(cols))
- for i := range cols {
- out[i] = &ddl.Column{
- Name: cols[i].Name,
- //Type: ddl.ColumnType{},
- IsNull: cols[i].IsNullable,
- //DefaultValue: "",
- }
- }
-
- return out, nil
-}
diff --git a/store/compose_attachments.gen.go b/store/compose_attachments.gen.go
deleted file mode 100644
index b7132e486..000000000
--- a/store/compose_attachments.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_attachments.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposeAttachments interface {
- SearchComposeAttachments(ctx context.Context, f types.AttachmentFilter) (types.AttachmentSet, types.AttachmentFilter, error)
- LookupComposeAttachmentByID(ctx context.Context, id uint64) (*types.Attachment, error)
-
- CreateComposeAttachment(ctx context.Context, rr ...*types.Attachment) error
-
- UpdateComposeAttachment(ctx context.Context, rr ...*types.Attachment) error
-
- UpsertComposeAttachment(ctx context.Context, rr ...*types.Attachment) error
-
- DeleteComposeAttachment(ctx context.Context, rr ...*types.Attachment) error
- DeleteComposeAttachmentByID(ctx context.Context, ID uint64) error
-
- TruncateComposeAttachments(ctx context.Context) error
- }
-)
-
-var _ *types.Attachment
-var _ context.Context
-
-// SearchComposeAttachments returns all matching ComposeAttachments from store
-func SearchComposeAttachments(ctx context.Context, s ComposeAttachments, f types.AttachmentFilter) (types.AttachmentSet, types.AttachmentFilter, error) {
- return s.SearchComposeAttachments(ctx, f)
-}
-
-// LookupComposeAttachmentByID searches for attachment by its ID
-//
-// It returns attachment even if deleted
-func LookupComposeAttachmentByID(ctx context.Context, s ComposeAttachments, id uint64) (*types.Attachment, error) {
- return s.LookupComposeAttachmentByID(ctx, id)
-}
-
-// CreateComposeAttachment creates one or more ComposeAttachments in store
-func CreateComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*types.Attachment) error {
- return s.CreateComposeAttachment(ctx, rr...)
-}
-
-// UpdateComposeAttachment updates one or more (existing) ComposeAttachments in store
-func UpdateComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*types.Attachment) error {
- return s.UpdateComposeAttachment(ctx, rr...)
-}
-
-// UpsertComposeAttachment creates new or updates existing one or more ComposeAttachments in store
-func UpsertComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*types.Attachment) error {
- return s.UpsertComposeAttachment(ctx, rr...)
-}
-
-// DeleteComposeAttachment Deletes one or more ComposeAttachments from store
-func DeleteComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*types.Attachment) error {
- return s.DeleteComposeAttachment(ctx, rr...)
-}
-
-// DeleteComposeAttachmentByID Deletes ComposeAttachment from store
-func DeleteComposeAttachmentByID(ctx context.Context, s ComposeAttachments, ID uint64) error {
- return s.DeleteComposeAttachmentByID(ctx, ID)
-}
-
-// TruncateComposeAttachments Deletes all ComposeAttachments from store
-func TruncateComposeAttachments(ctx context.Context, s ComposeAttachments) error {
- return s.TruncateComposeAttachments(ctx)
-}
diff --git a/store/compose_attachments.yaml b/store/compose_attachments.yaml
deleted file mode 100644
index 258b6ea04..000000000
--- a/store/compose_attachments.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.Attachment
-
-fields:
- - { field: ID }
- - { field: NamespaceID }
- - { field: Kind }
- - { field: Url }
- - { field: PreviewUrl }
- - { field: Name }
- - { field: Meta }
- - { field: OwnerID }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for attachment by its ID
-
- It returns attachment even if deleted
-
-search:
- enableSorting: false
- enablePaging: false
-
-rdbms:
- alias: att
- table: compose_attachment
- customFilterConverter: true
diff --git a/store/compose_charts.gen.go b/store/compose_charts.gen.go
deleted file mode 100644
index 8182416b0..000000000
--- a/store/compose_charts.gen.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_charts.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposeCharts interface {
- SearchComposeCharts(ctx context.Context, f types.ChartFilter) (types.ChartSet, types.ChartFilter, error)
- LookupComposeChartByID(ctx context.Context, id uint64) (*types.Chart, error)
- LookupComposeChartByNamespaceIDHandle(ctx context.Context, namespace_id uint64, handle string) (*types.Chart, error)
-
- CreateComposeChart(ctx context.Context, rr ...*types.Chart) error
-
- UpdateComposeChart(ctx context.Context, rr ...*types.Chart) error
-
- UpsertComposeChart(ctx context.Context, rr ...*types.Chart) error
-
- DeleteComposeChart(ctx context.Context, rr ...*types.Chart) error
- DeleteComposeChartByID(ctx context.Context, ID uint64) error
-
- TruncateComposeCharts(ctx context.Context) error
- }
-)
-
-var _ *types.Chart
-var _ context.Context
-
-// SearchComposeCharts returns all matching ComposeCharts from store
-func SearchComposeCharts(ctx context.Context, s ComposeCharts, f types.ChartFilter) (types.ChartSet, types.ChartFilter, error) {
- return s.SearchComposeCharts(ctx, f)
-}
-
-// LookupComposeChartByID searches for compose chart by ID
-//
-// It returns compose chart even if deleted
-func LookupComposeChartByID(ctx context.Context, s ComposeCharts, id uint64) (*types.Chart, error) {
- return s.LookupComposeChartByID(ctx, id)
-}
-
-// LookupComposeChartByNamespaceIDHandle searches for compose chart by handle (case-insensitive)
-func LookupComposeChartByNamespaceIDHandle(ctx context.Context, s ComposeCharts, namespace_id uint64, handle string) (*types.Chart, error) {
- return s.LookupComposeChartByNamespaceIDHandle(ctx, namespace_id, handle)
-}
-
-// CreateComposeChart creates one or more ComposeCharts in store
-func CreateComposeChart(ctx context.Context, s ComposeCharts, rr ...*types.Chart) error {
- return s.CreateComposeChart(ctx, rr...)
-}
-
-// UpdateComposeChart updates one or more (existing) ComposeCharts in store
-func UpdateComposeChart(ctx context.Context, s ComposeCharts, rr ...*types.Chart) error {
- return s.UpdateComposeChart(ctx, rr...)
-}
-
-// UpsertComposeChart creates new or updates existing one or more ComposeCharts in store
-func UpsertComposeChart(ctx context.Context, s ComposeCharts, rr ...*types.Chart) error {
- return s.UpsertComposeChart(ctx, rr...)
-}
-
-// DeleteComposeChart Deletes one or more ComposeCharts from store
-func DeleteComposeChart(ctx context.Context, s ComposeCharts, rr ...*types.Chart) error {
- return s.DeleteComposeChart(ctx, rr...)
-}
-
-// DeleteComposeChartByID Deletes ComposeChart from store
-func DeleteComposeChartByID(ctx context.Context, s ComposeCharts, ID uint64) error {
- return s.DeleteComposeChartByID(ctx, ID)
-}
-
-// TruncateComposeCharts Deletes all ComposeCharts from store
-func TruncateComposeCharts(ctx context.Context, s ComposeCharts) error {
- return s.TruncateComposeCharts(ctx)
-}
diff --git a/store/compose_charts.yaml b/store/compose_charts.yaml
deleted file mode 100644
index 52dac3078..000000000
--- a/store/compose_charts.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.Chart
-
-fields:
- - { field: ID }
- - { field: Handle, lookupFilterPreprocessor: lower, sortable: true, unique: true }
- - { field: Name, sortable: true }
- - { field: Config, type: "types.ChartConfig" }
- - { field: NamespaceID }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for compose chart by ID
-
- It returns compose chart even if deleted
- - fields: [ NamespaceID, Handle ]
- filter: { DeletedAt: nil }
- description: |-
- searches for compose chart by handle (case-insensitive)
-
-rdbms:
- alias: cch
- table: compose_chart
- customFilterConverter: true
diff --git a/store/compose_module_fields.gen.go b/store/compose_module_fields.gen.go
deleted file mode 100644
index 68bcb247c..000000000
--- a/store/compose_module_fields.gen.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_module_fields.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposeModuleFields interface {
- SearchComposeModuleFields(ctx context.Context, f types.ModuleFieldFilter) (types.ModuleFieldSet, types.ModuleFieldFilter, error)
- LookupComposeModuleFieldByModuleIDName(ctx context.Context, module_id uint64, name string) (*types.ModuleField, error)
-
- CreateComposeModuleField(ctx context.Context, rr ...*types.ModuleField) error
-
- UpdateComposeModuleField(ctx context.Context, rr ...*types.ModuleField) error
-
- UpsertComposeModuleField(ctx context.Context, rr ...*types.ModuleField) error
-
- DeleteComposeModuleField(ctx context.Context, rr ...*types.ModuleField) error
- DeleteComposeModuleFieldByID(ctx context.Context, ID uint64) error
-
- TruncateComposeModuleFields(ctx context.Context) error
- }
-)
-
-var _ *types.ModuleField
-var _ context.Context
-
-// SearchComposeModuleFields returns all matching ComposeModuleFields from store
-func SearchComposeModuleFields(ctx context.Context, s ComposeModuleFields, f types.ModuleFieldFilter) (types.ModuleFieldSet, types.ModuleFieldFilter, error) {
- return s.SearchComposeModuleFields(ctx, f)
-}
-
-// LookupComposeModuleFieldByModuleIDName searches for compose module field by name (case-insensitive)
-func LookupComposeModuleFieldByModuleIDName(ctx context.Context, s ComposeModuleFields, module_id uint64, name string) (*types.ModuleField, error) {
- return s.LookupComposeModuleFieldByModuleIDName(ctx, module_id, name)
-}
-
-// CreateComposeModuleField creates one or more ComposeModuleFields in store
-func CreateComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*types.ModuleField) error {
- return s.CreateComposeModuleField(ctx, rr...)
-}
-
-// UpdateComposeModuleField updates one or more (existing) ComposeModuleFields in store
-func UpdateComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*types.ModuleField) error {
- return s.UpdateComposeModuleField(ctx, rr...)
-}
-
-// UpsertComposeModuleField creates new or updates existing one or more ComposeModuleFields in store
-func UpsertComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*types.ModuleField) error {
- return s.UpsertComposeModuleField(ctx, rr...)
-}
-
-// DeleteComposeModuleField Deletes one or more ComposeModuleFields from store
-func DeleteComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*types.ModuleField) error {
- return s.DeleteComposeModuleField(ctx, rr...)
-}
-
-// DeleteComposeModuleFieldByID Deletes ComposeModuleField from store
-func DeleteComposeModuleFieldByID(ctx context.Context, s ComposeModuleFields, ID uint64) error {
- return s.DeleteComposeModuleFieldByID(ctx, ID)
-}
-
-// TruncateComposeModuleFields Deletes all ComposeModuleFields from store
-func TruncateComposeModuleFields(ctx context.Context, s ComposeModuleFields) error {
- return s.TruncateComposeModuleFields(ctx)
-}
diff --git a/store/compose_module_fields.yaml b/store/compose_module_fields.yaml
deleted file mode 100644
index 730763124..000000000
--- a/store/compose_module_fields.yaml
+++ /dev/null
@@ -1,46 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.ModuleField
-
-fields:
- - { field: ID }
- - { field: Name, lookupFilterPreprocessor: lower, unique: true}
- - { field: ModuleID }
- - { field: Place, type: int }
- - { field: Kind }
- - { field: Label }
- - { field: Options, type: "types.ModuleFieldOptions" }
- - { field: Private, type: bool }
- - { field: Required, type: bool }
- - { field: Visible, type: bool }
- - { field: Multi, type: bool }
- - { field: DefaultValue, type: "types.RecordValueSet" }
- - { field: Expressions, type: "types.ModuleFieldExpr" }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ ModuleID, Name ]
- uniqueConstraintCheck: true
- filter: { DeletedAt: nil }
- description: |-
- searches for compose module field by name (case-insensitive)
-
-rdbms:
- alias: cmf
- table: compose_module_field
- customFilterConverter: true
- mapFields:
- Private: { column: is_private }
- Required: { column: is_required }
- Visible: { column: is_visible }
- Multi: { column: is_multi }
-
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
diff --git a/store/compose_modules.gen.go b/store/compose_modules.gen.go
deleted file mode 100644
index 8823e819a..000000000
--- a/store/compose_modules.gen.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_modules.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposeModules interface {
- SearchComposeModules(ctx context.Context, f types.ModuleFilter) (types.ModuleSet, types.ModuleFilter, error)
- LookupComposeModuleByNamespaceIDHandle(ctx context.Context, namespace_id uint64, handle string) (*types.Module, error)
- LookupComposeModuleByNamespaceIDName(ctx context.Context, namespace_id uint64, name string) (*types.Module, error)
- LookupComposeModuleByID(ctx context.Context, id uint64) (*types.Module, error)
-
- CreateComposeModule(ctx context.Context, rr ...*types.Module) error
-
- UpdateComposeModule(ctx context.Context, rr ...*types.Module) error
-
- UpsertComposeModule(ctx context.Context, rr ...*types.Module) error
-
- DeleteComposeModule(ctx context.Context, rr ...*types.Module) error
- DeleteComposeModuleByID(ctx context.Context, ID uint64) error
-
- TruncateComposeModules(ctx context.Context) error
- }
-)
-
-var _ *types.Module
-var _ context.Context
-
-// SearchComposeModules returns all matching ComposeModules from store
-func SearchComposeModules(ctx context.Context, s ComposeModules, f types.ModuleFilter) (types.ModuleSet, types.ModuleFilter, error) {
- return s.SearchComposeModules(ctx, f)
-}
-
-// LookupComposeModuleByNamespaceIDHandle searches for compose module by handle (case-insensitive)
-func LookupComposeModuleByNamespaceIDHandle(ctx context.Context, s ComposeModules, namespace_id uint64, handle string) (*types.Module, error) {
- return s.LookupComposeModuleByNamespaceIDHandle(ctx, namespace_id, handle)
-}
-
-// LookupComposeModuleByNamespaceIDName searches for compose module by name (case-insensitive)
-func LookupComposeModuleByNamespaceIDName(ctx context.Context, s ComposeModules, namespace_id uint64, name string) (*types.Module, error) {
- return s.LookupComposeModuleByNamespaceIDName(ctx, namespace_id, name)
-}
-
-// LookupComposeModuleByID searches for compose module by ID
-//
-// It returns compose module even if deleted
-func LookupComposeModuleByID(ctx context.Context, s ComposeModules, id uint64) (*types.Module, error) {
- return s.LookupComposeModuleByID(ctx, id)
-}
-
-// CreateComposeModule creates one or more ComposeModules in store
-func CreateComposeModule(ctx context.Context, s ComposeModules, rr ...*types.Module) error {
- return s.CreateComposeModule(ctx, rr...)
-}
-
-// UpdateComposeModule updates one or more (existing) ComposeModules in store
-func UpdateComposeModule(ctx context.Context, s ComposeModules, rr ...*types.Module) error {
- return s.UpdateComposeModule(ctx, rr...)
-}
-
-// UpsertComposeModule creates new or updates existing one or more ComposeModules in store
-func UpsertComposeModule(ctx context.Context, s ComposeModules, rr ...*types.Module) error {
- return s.UpsertComposeModule(ctx, rr...)
-}
-
-// DeleteComposeModule Deletes one or more ComposeModules from store
-func DeleteComposeModule(ctx context.Context, s ComposeModules, rr ...*types.Module) error {
- return s.DeleteComposeModule(ctx, rr...)
-}
-
-// DeleteComposeModuleByID Deletes ComposeModule from store
-func DeleteComposeModuleByID(ctx context.Context, s ComposeModules, ID uint64) error {
- return s.DeleteComposeModuleByID(ctx, ID)
-}
-
-// TruncateComposeModules Deletes all ComposeModules from store
-func TruncateComposeModules(ctx context.Context, s ComposeModules) error {
- return s.TruncateComposeModules(ctx)
-}
diff --git a/store/compose_modules.yaml b/store/compose_modules.yaml
deleted file mode 100644
index 3e0741eef..000000000
--- a/store/compose_modules.yaml
+++ /dev/null
@@ -1,39 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.Module
-
-fields:
- - { field: ID }
- - { field: Handle, lookupFilterPreprocessor: lower, unique: true, sortable: true }
- - { field: Name, lookupFilterPreprocessor: lower, sortable: true }
- - { field: Meta, type: "types.JSONText" }
- - { field: NamespaceID }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-
-lookups:
- - fields: [ NamespaceID, Handle ]
- uniqueConstraintCheck: true
- filter: { DeletedAt: nil }
- description: |-
- searches for compose module by handle (case-insensitive)
-
- - fields: [ NamespaceID, Name ]
- filter: { DeletedAt: nil }
- description: |-
- searches for compose module by name (case-insensitive)
-
- - fields: [ ID ]
- description: |-
- searches for compose module by ID
-
- It returns compose module even if deleted
-
-rdbms:
- alias: cmd
- table: compose_module
- customFilterConverter: true
diff --git a/store/compose_namespaces.gen.go b/store/compose_namespaces.gen.go
deleted file mode 100644
index 505039d87..000000000
--- a/store/compose_namespaces.gen.go
+++ /dev/null
@@ -1,83 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_namespaces.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposeNamespaces interface {
- SearchComposeNamespaces(ctx context.Context, f types.NamespaceFilter) (types.NamespaceSet, types.NamespaceFilter, error)
- LookupComposeNamespaceBySlug(ctx context.Context, slug string) (*types.Namespace, error)
- LookupComposeNamespaceByID(ctx context.Context, id uint64) (*types.Namespace, error)
-
- CreateComposeNamespace(ctx context.Context, rr ...*types.Namespace) error
-
- UpdateComposeNamespace(ctx context.Context, rr ...*types.Namespace) error
-
- UpsertComposeNamespace(ctx context.Context, rr ...*types.Namespace) error
-
- DeleteComposeNamespace(ctx context.Context, rr ...*types.Namespace) error
- DeleteComposeNamespaceByID(ctx context.Context, ID uint64) error
-
- TruncateComposeNamespaces(ctx context.Context) error
- }
-)
-
-var _ *types.Namespace
-var _ context.Context
-
-// SearchComposeNamespaces returns all matching ComposeNamespaces from store
-func SearchComposeNamespaces(ctx context.Context, s ComposeNamespaces, f types.NamespaceFilter) (types.NamespaceSet, types.NamespaceFilter, error) {
- return s.SearchComposeNamespaces(ctx, f)
-}
-
-// LookupComposeNamespaceBySlug searches for namespace by slug (case-insensitive)
-func LookupComposeNamespaceBySlug(ctx context.Context, s ComposeNamespaces, slug string) (*types.Namespace, error) {
- return s.LookupComposeNamespaceBySlug(ctx, slug)
-}
-
-// LookupComposeNamespaceByID searches for compose namespace by ID
-//
-// It returns compose namespace even if deleted
-func LookupComposeNamespaceByID(ctx context.Context, s ComposeNamespaces, id uint64) (*types.Namespace, error) {
- return s.LookupComposeNamespaceByID(ctx, id)
-}
-
-// CreateComposeNamespace creates one or more ComposeNamespaces in store
-func CreateComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*types.Namespace) error {
- return s.CreateComposeNamespace(ctx, rr...)
-}
-
-// UpdateComposeNamespace updates one or more (existing) ComposeNamespaces in store
-func UpdateComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*types.Namespace) error {
- return s.UpdateComposeNamespace(ctx, rr...)
-}
-
-// UpsertComposeNamespace creates new or updates existing one or more ComposeNamespaces in store
-func UpsertComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*types.Namespace) error {
- return s.UpsertComposeNamespace(ctx, rr...)
-}
-
-// DeleteComposeNamespace Deletes one or more ComposeNamespaces from store
-func DeleteComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*types.Namespace) error {
- return s.DeleteComposeNamespace(ctx, rr...)
-}
-
-// DeleteComposeNamespaceByID Deletes ComposeNamespace from store
-func DeleteComposeNamespaceByID(ctx context.Context, s ComposeNamespaces, ID uint64) error {
- return s.DeleteComposeNamespaceByID(ctx, ID)
-}
-
-// TruncateComposeNamespaces Deletes all ComposeNamespaces from store
-func TruncateComposeNamespaces(ctx context.Context, s ComposeNamespaces) error {
- return s.TruncateComposeNamespaces(ctx)
-}
diff --git a/store/compose_namespaces.yaml b/store/compose_namespaces.yaml
deleted file mode 100644
index 14c9c7e5f..000000000
--- a/store/compose_namespaces.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.Namespace
-
-fields:
- - { field: ID }
- - { field: Name, sortable: true }
- - { field: Slug, lookupFilterPreprocessor: lower, sortable: true, unique: true }
- - { field: Enabled }
- - { field: Meta, type: "*types.NamespaceMeta" }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ Slug ]
- uniqueConstraintCheck: true
- filter: { DeletedAt: nil }
- description: |-
- searches for namespace by slug (case-insensitive)
-
- - fields: [ ID ]
- description: |-
- searches for compose namespace by ID
-
- It returns compose namespace even if deleted
-
-rdbms:
- alias: cns
- table: compose_namespace
- customFilterConverter: true
-
diff --git a/store/compose_pages.gen.go b/store/compose_pages.gen.go
deleted file mode 100644
index e383dbc70..000000000
--- a/store/compose_pages.gen.go
+++ /dev/null
@@ -1,98 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_pages.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposePages interface {
- SearchComposePages(ctx context.Context, f types.PageFilter) (types.PageSet, types.PageFilter, error)
- LookupComposePageByNamespaceIDHandle(ctx context.Context, namespace_id uint64, handle string) (*types.Page, error)
- LookupComposePageByNamespaceIDModuleID(ctx context.Context, namespace_id uint64, module_id uint64) (*types.Page, error)
- LookupComposePageByID(ctx context.Context, id uint64) (*types.Page, error)
-
- CreateComposePage(ctx context.Context, rr ...*types.Page) error
-
- UpdateComposePage(ctx context.Context, rr ...*types.Page) error
-
- UpsertComposePage(ctx context.Context, rr ...*types.Page) error
-
- DeleteComposePage(ctx context.Context, rr ...*types.Page) error
- DeleteComposePageByID(ctx context.Context, ID uint64) error
-
- TruncateComposePages(ctx context.Context) error
-
- // Additional custom functions
-
- // ReorderComposePages (custom function)
- ReorderComposePages(ctx context.Context, _namespaceID uint64, _parentID uint64, _pageIDs []uint64) error
- }
-)
-
-var _ *types.Page
-var _ context.Context
-
-// SearchComposePages returns all matching ComposePages from store
-func SearchComposePages(ctx context.Context, s ComposePages, f types.PageFilter) (types.PageSet, types.PageFilter, error) {
- return s.SearchComposePages(ctx, f)
-}
-
-// LookupComposePageByNamespaceIDHandle searches for page by handle (case-insensitive)
-func LookupComposePageByNamespaceIDHandle(ctx context.Context, s ComposePages, namespace_id uint64, handle string) (*types.Page, error) {
- return s.LookupComposePageByNamespaceIDHandle(ctx, namespace_id, handle)
-}
-
-// LookupComposePageByNamespaceIDModuleID searches for page by moduleID
-func LookupComposePageByNamespaceIDModuleID(ctx context.Context, s ComposePages, namespace_id uint64, module_id uint64) (*types.Page, error) {
- return s.LookupComposePageByNamespaceIDModuleID(ctx, namespace_id, module_id)
-}
-
-// LookupComposePageByID searches for compose page by ID
-//
-// It returns compose page even if deleted
-func LookupComposePageByID(ctx context.Context, s ComposePages, id uint64) (*types.Page, error) {
- return s.LookupComposePageByID(ctx, id)
-}
-
-// CreateComposePage creates one or more ComposePages in store
-func CreateComposePage(ctx context.Context, s ComposePages, rr ...*types.Page) error {
- return s.CreateComposePage(ctx, rr...)
-}
-
-// UpdateComposePage updates one or more (existing) ComposePages in store
-func UpdateComposePage(ctx context.Context, s ComposePages, rr ...*types.Page) error {
- return s.UpdateComposePage(ctx, rr...)
-}
-
-// UpsertComposePage creates new or updates existing one or more ComposePages in store
-func UpsertComposePage(ctx context.Context, s ComposePages, rr ...*types.Page) error {
- return s.UpsertComposePage(ctx, rr...)
-}
-
-// DeleteComposePage Deletes one or more ComposePages from store
-func DeleteComposePage(ctx context.Context, s ComposePages, rr ...*types.Page) error {
- return s.DeleteComposePage(ctx, rr...)
-}
-
-// DeleteComposePageByID Deletes ComposePage from store
-func DeleteComposePageByID(ctx context.Context, s ComposePages, ID uint64) error {
- return s.DeleteComposePageByID(ctx, ID)
-}
-
-// TruncateComposePages Deletes all ComposePages from store
-func TruncateComposePages(ctx context.Context, s ComposePages) error {
- return s.TruncateComposePages(ctx)
-}
-
-func ReorderComposePages(ctx context.Context, s ComposePages, _namespaceID uint64, _parentID uint64, _pageIDs []uint64) error {
- return s.ReorderComposePages(ctx, _namespaceID, _parentID, _pageIDs)
-}
diff --git a/store/compose_pages.yaml b/store/compose_pages.yaml
deleted file mode 100644
index 7c863d6e0..000000000
--- a/store/compose_pages.yaml
+++ /dev/null
@@ -1,54 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.Page
-
-fields:
- - { field: ID }
- - { field: SelfID }
- - { field: NamespaceID }
- - { field: ModuleID }
- - { field: Handle, lookupFilterPreprocessor: lower }
- - { field: Title }
- - { field: Description, type: "string" }
- - { field: Config, type: "types.PageConfig" }
- - { field: Blocks, type: "types.PageBlocks" }
- - { field: Visible, type: bool }
- - { field: Weight, type: int, sortable: true }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ NamespaceID, Handle ]
- filter: { DeletedAt: nil }
- description: |-
- searches for page by handle (case-insensitive)
-
- - fields: [ NamespaceID, ModuleID ]
- filter: { DeletedAt: nil }
- description: |-
- searches for page by moduleID
-
- - fields: [ ID ]
- description: |-
- searches for compose page by ID
-
- It returns compose page even if deleted
-
-functions:
- - name: ReorderComposePages
- arguments:
- - { name: namespaceID, type: "uint64" }
- - { name: parentID, type: "uint64" }
- - { name: pageIDs, type: "[]uint64" }
- return: [ "error" ]
-
-rdbms:
- alias: cpg
- table: compose_page
- customFilterConverter: true
- mapFields:
- SelfID: { column: self_id }
-
diff --git a/store/compose_record_values.gen.go b/store/compose_record_values.gen.go
deleted file mode 100644
index 623336c11..000000000
--- a/store/compose_record_values.gen.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_record_values.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-type (
- ComposeRecordValues interface {
-
- // Additional custom functions
-
- // ComposeRecordValueRefLookup (custom function)
- ComposeRecordValueRefLookup(ctx context.Context, _mod *types.Module, _field string, _ref uint64) (uint64, error)
- }
-)
-
-var _ *types.RecordValue
-var _ context.Context
-
-func ComposeRecordValueRefLookup(ctx context.Context, s ComposeRecordValues, _mod *types.Module, _field string, _ref uint64) (uint64, error) {
- return s.ComposeRecordValueRefLookup(ctx, _mod, _field, _ref)
-}
diff --git a/store/compose_record_values.yaml b/store/compose_record_values.yaml
deleted file mode 100644
index 35dd582f8..000000000
--- a/store/compose_record_values.yaml
+++ /dev/null
@@ -1,56 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-publish: false
-
-types:
- type: types.RecordValue
-
-fields:
- - { field: RecordID, isPrimaryKey: true }
- - { field: Name, isPrimaryKey: true }
- - { field: Place, type: uint, isPrimaryKey: true }
- - { field: Value }
- - { field: Ref, type: uint64 }
- - { field: DeletedAt }
-
-functions:
- - name: ComposeRecordValueRefLookup
- arguments:
- - { name: mod, type: "*types.Module" }
- - { name: field, type: string }
- - { name: ref, type: uint64 }
- return: [ uint64, error ]
-
-
-arguments:
- - name: mod
- type: "*types.Module"
-
-rdbms:
- alias: crv
- table: compose_record_value
- customFilterConverter: true
- mapFields:
- RecordID: { column: record_id }
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
- export: false
-
-create:
- export: false
-
-update:
- export: false
-
-upsert:
- export: false
-
-delete:
- export: false
-
-truncate:
- export: false
diff --git a/store/compose_records.gen.go b/store/compose_records.gen.go
deleted file mode 100644
index 1c3de7a1a..000000000
--- a/store/compose_records.gen.go
+++ /dev/null
@@ -1,100 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/compose_records.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/report"
-)
-
-type (
- ComposeRecords interface {
- SearchComposeRecords(ctx context.Context, _mod *types.Module, f types.RecordFilter) (types.RecordSet, types.RecordFilter, error)
- LookupComposeRecordByID(ctx context.Context, _mod *types.Module, id uint64) (*types.Record, error)
-
- CreateComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) error
-
- UpdateComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) error
-
- UpsertComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) error
-
- DeleteComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) error
- DeleteComposeRecordByID(ctx context.Context, _mod *types.Module, ID uint64) error
-
- TruncateComposeRecords(ctx context.Context, _mod *types.Module) error
-
- // Additional custom functions
-
- // ComposeRecordReport (custom function)
- ComposeRecordReport(ctx context.Context, _mod *types.Module, _metrics string, _dimensions string, _filters string) ([]map[string]interface{}, error)
-
- // ComposeRecordDatasource (custom function)
- ComposeRecordDatasource(ctx context.Context, _mod *types.Module, _ld *report.LoadStepDefinition) (report.Datasource, error)
-
- // PartialComposeRecordValueUpdate (custom function)
- PartialComposeRecordValueUpdate(ctx context.Context, _mod *types.Module, _values ...*types.RecordValue) error
- }
-)
-
-var _ *types.Record
-var _ context.Context
-
-// SearchComposeRecords returns all matching ComposeRecords from store
-func SearchComposeRecords(ctx context.Context, s ComposeRecords, _mod *types.Module, f types.RecordFilter) (types.RecordSet, types.RecordFilter, error) {
- return s.SearchComposeRecords(ctx, _mod, f)
-}
-
-// LookupComposeRecordByID searches for compose record by ID
-// It returns compose record even if deleted
-func LookupComposeRecordByID(ctx context.Context, s ComposeRecords, _mod *types.Module, id uint64) (*types.Record, error) {
- return s.LookupComposeRecordByID(ctx, _mod, id)
-}
-
-// CreateComposeRecord creates one or more ComposeRecords in store
-func CreateComposeRecord(ctx context.Context, s ComposeRecords, _mod *types.Module, rr ...*types.Record) error {
- return s.CreateComposeRecord(ctx, _mod, rr...)
-}
-
-// UpdateComposeRecord updates one or more (existing) ComposeRecords in store
-func UpdateComposeRecord(ctx context.Context, s ComposeRecords, _mod *types.Module, rr ...*types.Record) error {
- return s.UpdateComposeRecord(ctx, _mod, rr...)
-}
-
-// UpsertComposeRecord creates new or updates existing one or more ComposeRecords in store
-func UpsertComposeRecord(ctx context.Context, s ComposeRecords, _mod *types.Module, rr ...*types.Record) error {
- return s.UpsertComposeRecord(ctx, _mod, rr...)
-}
-
-// DeleteComposeRecord Deletes one or more ComposeRecords from store
-func DeleteComposeRecord(ctx context.Context, s ComposeRecords, _mod *types.Module, rr ...*types.Record) error {
- return s.DeleteComposeRecord(ctx, _mod, rr...)
-}
-
-// DeleteComposeRecordByID Deletes ComposeRecord from store
-func DeleteComposeRecordByID(ctx context.Context, s ComposeRecords, _mod *types.Module, ID uint64) error {
- return s.DeleteComposeRecordByID(ctx, _mod, ID)
-}
-
-// TruncateComposeRecords Deletes all ComposeRecords from store
-func TruncateComposeRecords(ctx context.Context, s ComposeRecords, _mod *types.Module) error {
- return s.TruncateComposeRecords(ctx, _mod)
-}
-
-func ComposeRecordReport(ctx context.Context, s ComposeRecords, _mod *types.Module, _metrics string, _dimensions string, _filters string) ([]map[string]interface{}, error) {
- return s.ComposeRecordReport(ctx, _mod, _metrics, _dimensions, _filters)
-}
-
-func ComposeRecordDatasource(ctx context.Context, s ComposeRecords, _mod *types.Module, _ld *report.LoadStepDefinition) (report.Datasource, error) {
- return s.ComposeRecordDatasource(ctx, _mod, _ld)
-}
-
-func PartialComposeRecordValueUpdate(ctx context.Context, s ComposeRecords, _mod *types.Module, _values ...*types.RecordValue) error {
- return s.PartialComposeRecordValueUpdate(ctx, _mod, _values...)
-}
diff --git a/store/compose_records.yaml b/store/compose_records.yaml
deleted file mode 100644
index b59f55217..000000000
--- a/store/compose_records.yaml
+++ /dev/null
@@ -1,82 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/compose/types
-
-types:
- type: types.Record
-
-fields:
- - { field: ID }
- - { field: ModuleID }
- - { field: NamespaceID }
- - { field: OwnedBy }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-functions:
- - name: ComposeRecordReport
- arguments:
- - { name: mod, type: "*types.Module" }
- - { name: metrics, type: string }
- - { name: dimensions, type: string }
- - { name: filters, type: string }
- return: [ "[]map[string]interface{}", error ]
-
- - name: ComposeRecordDatasource
- import:
- - github.com/cortezaproject/corteza-server/pkg/report
- arguments:
- - { name: mod, type: "*types.Module" }
- - { name: ld, type: "*report.LoadStepDefinition" }
- return: [ report.Datasource, error ]
-
- - name: PartialComposeRecordValueUpdate
- arguments:
- - { name: mod, type: "*types.Module" }
- - { name: values, type: ...*types.RecordValue }
- return: [ error ]
-
-lookups:
- - fields: [ ID ]
- export: false
- description: |-
- searches for compose record by ID
- It returns compose record even if deleted
-
-arguments:
- - name: mod
- type: "*types.Module"
-
-rdbms:
- alias: crd
- table: compose_record
- customFilterConverter: true
- customSortConverter: true
- customCursorCollector: true
- customPreLoadProcessor: true
- customPostLoadProcessor: true
- mapFields:
- ModuleID: { column: module_id }
-
-search:
- custom: true
- export: false
-
-create:
- export: false
-
-update:
- export: false
-
-upsert:
- export: false
-
-delete:
- export: false
-
-truncate:
- export: false
-
diff --git a/store/connect.go b/store/connect.go
index 6d7270783..d39c52200 100644
--- a/store/connect.go
+++ b/store/connect.go
@@ -3,10 +3,11 @@ package store
import (
"context"
"fmt"
- "go.uber.org/zap"
"os"
"regexp"
"strings"
+
+ "go.uber.org/zap"
)
type (
diff --git a/store/credentials.gen.go b/store/credentials.gen.go
deleted file mode 100644
index dda960760..000000000
--- a/store/credentials.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/credentials.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Credentials interface {
- SearchCredentials(ctx context.Context, f types.CredentialsFilter) (types.CredentialsSet, types.CredentialsFilter, error)
- LookupCredentialsByID(ctx context.Context, id uint64) (*types.Credentials, error)
-
- CreateCredentials(ctx context.Context, rr ...*types.Credentials) error
-
- UpdateCredentials(ctx context.Context, rr ...*types.Credentials) error
-
- UpsertCredentials(ctx context.Context, rr ...*types.Credentials) error
-
- DeleteCredentials(ctx context.Context, rr ...*types.Credentials) error
- DeleteCredentialsByID(ctx context.Context, ID uint64) error
-
- TruncateCredentials(ctx context.Context) error
- }
-)
-
-var _ *types.Credentials
-var _ context.Context
-
-// SearchCredentials returns all matching Credentials from store
-func SearchCredentials(ctx context.Context, s Credentials, f types.CredentialsFilter) (types.CredentialsSet, types.CredentialsFilter, error) {
- return s.SearchCredentials(ctx, f)
-}
-
-// LookupCredentialsByID searches for credentials by ID
-//
-// It returns credentials even if deleted
-func LookupCredentialsByID(ctx context.Context, s Credentials, id uint64) (*types.Credentials, error) {
- return s.LookupCredentialsByID(ctx, id)
-}
-
-// CreateCredentials creates one or more Credentials in store
-func CreateCredentials(ctx context.Context, s Credentials, rr ...*types.Credentials) error {
- return s.CreateCredentials(ctx, rr...)
-}
-
-// UpdateCredentials updates one or more (existing) Credentials in store
-func UpdateCredentials(ctx context.Context, s Credentials, rr ...*types.Credentials) error {
- return s.UpdateCredentials(ctx, rr...)
-}
-
-// UpsertCredentials creates new or updates existing one or more Credentials in store
-func UpsertCredentials(ctx context.Context, s Credentials, rr ...*types.Credentials) error {
- return s.UpsertCredentials(ctx, rr...)
-}
-
-// DeleteCredentials Deletes one or more Credentials from store
-func DeleteCredentials(ctx context.Context, s Credentials, rr ...*types.Credentials) error {
- return s.DeleteCredentials(ctx, rr...)
-}
-
-// DeleteCredentialsByID Deletes Credentials from store
-func DeleteCredentialsByID(ctx context.Context, s Credentials, ID uint64) error {
- return s.DeleteCredentialsByID(ctx, ID)
-}
-
-// TruncateCredentials Deletes all Credentials from store
-func TruncateCredentials(ctx context.Context, s Credentials) error {
- return s.TruncateCredentials(ctx)
-}
diff --git a/store/credentials.yaml b/store/credentials.yaml
deleted file mode 100644
index 4518d3fde..000000000
--- a/store/credentials.yaml
+++ /dev/null
@@ -1,36 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-types:
- singular: Credentials
- plural: Credentials
-
-fields:
- - { field: ID }
- - { field: OwnerID }
- - { field: Kind }
- - { field: Label }
- - { field: Credentials }
- - { field: Meta }
- - { field: LastUsedAt }
- - { field: ExpiresAt }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for credentials by ID
-
- It returns credentials even if deleted
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
-
-rdbms:
- alias: crd
- table: credentials
- customFilterConverter: true
diff --git a/store/federation_exposed_modules.gen.go b/store/federation_exposed_modules.gen.go
deleted file mode 100644
index cc403ae2e..000000000
--- a/store/federation_exposed_modules.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/federation_exposed_modules.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-type (
- FederationExposedModules interface {
- SearchFederationExposedModules(ctx context.Context, f types.ExposedModuleFilter) (types.ExposedModuleSet, types.ExposedModuleFilter, error)
- LookupFederationExposedModuleByID(ctx context.Context, id uint64) (*types.ExposedModule, error)
-
- CreateFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) error
-
- UpdateFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) error
-
- UpsertFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) error
-
- DeleteFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) error
- DeleteFederationExposedModuleByID(ctx context.Context, ID uint64) error
-
- TruncateFederationExposedModules(ctx context.Context) error
- }
-)
-
-var _ *types.ExposedModule
-var _ context.Context
-
-// SearchFederationExposedModules returns all matching FederationExposedModules from store
-func SearchFederationExposedModules(ctx context.Context, s FederationExposedModules, f types.ExposedModuleFilter) (types.ExposedModuleSet, types.ExposedModuleFilter, error) {
- return s.SearchFederationExposedModules(ctx, f)
-}
-
-// LookupFederationExposedModuleByID searches for federation module by ID
-//
-// It returns federation module
-func LookupFederationExposedModuleByID(ctx context.Context, s FederationExposedModules, id uint64) (*types.ExposedModule, error) {
- return s.LookupFederationExposedModuleByID(ctx, id)
-}
-
-// CreateFederationExposedModule creates one or more FederationExposedModules in store
-func CreateFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*types.ExposedModule) error {
- return s.CreateFederationExposedModule(ctx, rr...)
-}
-
-// UpdateFederationExposedModule updates one or more (existing) FederationExposedModules in store
-func UpdateFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*types.ExposedModule) error {
- return s.UpdateFederationExposedModule(ctx, rr...)
-}
-
-// UpsertFederationExposedModule creates new or updates existing one or more FederationExposedModules in store
-func UpsertFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*types.ExposedModule) error {
- return s.UpsertFederationExposedModule(ctx, rr...)
-}
-
-// DeleteFederationExposedModule Deletes one or more FederationExposedModules from store
-func DeleteFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*types.ExposedModule) error {
- return s.DeleteFederationExposedModule(ctx, rr...)
-}
-
-// DeleteFederationExposedModuleByID Deletes FederationExposedModule from store
-func DeleteFederationExposedModuleByID(ctx context.Context, s FederationExposedModules, ID uint64) error {
- return s.DeleteFederationExposedModuleByID(ctx, ID)
-}
-
-// TruncateFederationExposedModules Deletes all FederationExposedModules from store
-func TruncateFederationExposedModules(ctx context.Context, s FederationExposedModules) error {
- return s.TruncateFederationExposedModules(ctx)
-}
diff --git a/store/federation_exposed_modules.yaml b/store/federation_exposed_modules.yaml
deleted file mode 100644
index c95828cb7..000000000
--- a/store/federation_exposed_modules.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/federation/types
-
-types:
- type: types.ExposedModule
-
-fields:
- - { field: ID, isPrimaryKey: true, sortable: true }
- - { field: Handle }
- - { field: Name }
- - { field: NodeID }
- - { field: ComposeModuleID }
- - { field: ComposeNamespaceID }
- - { field: Fields, type: "json.Text" }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ID]
- description: |-
- searches for federation module by ID
-
- It returns federation module
-
-rdbms:
- alias: cmd
- table: federation_module_exposed
- customFilterConverter: true
diff --git a/store/federation_module_mappings.gen.go b/store/federation_module_mappings.gen.go
deleted file mode 100644
index bcbcdc7ce..000000000
--- a/store/federation_module_mappings.gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/federation_module_mappings.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-type (
- FederationModuleMappings interface {
- SearchFederationModuleMappings(ctx context.Context, f types.ModuleMappingFilter) (types.ModuleMappingSet, types.ModuleMappingFilter, error)
- LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, federation_module_id uint64, compose_module_id uint64, compose_namespace_id uint64) (*types.ModuleMapping, error)
- LookupFederationModuleMappingByFederationModuleID(ctx context.Context, federation_module_id uint64) (*types.ModuleMapping, error)
-
- CreateFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) error
-
- UpdateFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) error
-
- UpsertFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) error
-
- DeleteFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) error
- DeleteFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, federationModuleID uint64, composeModuleID uint64, composeNamespaceID uint64) error
-
- TruncateFederationModuleMappings(ctx context.Context) error
- }
-)
-
-var _ *types.ModuleMapping
-var _ context.Context
-
-// SearchFederationModuleMappings returns all matching FederationModuleMappings from store
-func SearchFederationModuleMappings(ctx context.Context, s FederationModuleMappings, f types.ModuleMappingFilter) (types.ModuleMappingSet, types.ModuleMappingFilter, error) {
- return s.SearchFederationModuleMappings(ctx, f)
-}
-
-// LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID searches for module mapping by federation module id and compose module id
-//
-// It returns module mapping
-func LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, s FederationModuleMappings, federation_module_id uint64, compose_module_id uint64, compose_namespace_id uint64) (*types.ModuleMapping, error) {
- return s.LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx, federation_module_id, compose_module_id, compose_namespace_id)
-}
-
-// LookupFederationModuleMappingByFederationModuleID searches for module mapping by federation module id
-//
-// It returns module mapping
-func LookupFederationModuleMappingByFederationModuleID(ctx context.Context, s FederationModuleMappings, federation_module_id uint64) (*types.ModuleMapping, error) {
- return s.LookupFederationModuleMappingByFederationModuleID(ctx, federation_module_id)
-}
-
-// CreateFederationModuleMapping creates one or more FederationModuleMappings in store
-func CreateFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*types.ModuleMapping) error {
- return s.CreateFederationModuleMapping(ctx, rr...)
-}
-
-// UpdateFederationModuleMapping updates one or more (existing) FederationModuleMappings in store
-func UpdateFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*types.ModuleMapping) error {
- return s.UpdateFederationModuleMapping(ctx, rr...)
-}
-
-// UpsertFederationModuleMapping creates new or updates existing one or more FederationModuleMappings in store
-func UpsertFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*types.ModuleMapping) error {
- return s.UpsertFederationModuleMapping(ctx, rr...)
-}
-
-// DeleteFederationModuleMapping Deletes one or more FederationModuleMappings from store
-func DeleteFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*types.ModuleMapping) error {
- return s.DeleteFederationModuleMapping(ctx, rr...)
-}
-
-// DeleteFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID Deletes FederationModuleMapping from store
-func DeleteFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, s FederationModuleMappings, federationModuleID uint64, composeModuleID uint64, composeNamespaceID uint64) error {
- return s.DeleteFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx, federationModuleID, composeModuleID, composeNamespaceID)
-}
-
-// TruncateFederationModuleMappings Deletes all FederationModuleMappings from store
-func TruncateFederationModuleMappings(ctx context.Context, s FederationModuleMappings) error {
- return s.TruncateFederationModuleMappings(ctx)
-}
diff --git a/store/federation_module_mappings.yaml b/store/federation_module_mappings.yaml
deleted file mode 100644
index 8b3ac40f7..000000000
--- a/store/federation_module_mappings.yaml
+++ /dev/null
@@ -1,33 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/federation/types
-
-types:
- type: types.ModuleMapping
-
-fields:
- - { field: FederationModuleID, isPrimaryKey: true, sortable: true }
- - { field: ComposeModuleID, isPrimaryKey: true, sortable: true }
- - { field: ComposeNamespaceID, isPrimaryKey: true, sortable: true }
- - { field: FieldMapping, type: "json.Text" }
-
-lookups:
- - fields: [FederationModuleID, ComposeModuleID, ComposeNamespaceID]
- description: |-
- searches for module mapping by federation module id and compose module id
-
- It returns module mapping
- - fields: [FederationModuleID]
- description: |-
- searches for module mapping by federation module id
-
- It returns module mapping
-
-rdbms:
- alias: cmd
- table: federation_module_mapping
- customFilterConverter: true
- mapFields:
- FederationModuleID: { column: rel_federation_module }
- ComposeModuleID: { column: rel_compose_module }
- ComposeNamespaceID: { column: rel_compose_namespace }
- FieldMapping: { column: field_mapping }
diff --git a/store/federation_nodes.gen.go b/store/federation_nodes.gen.go
deleted file mode 100644
index 36336c9af..000000000
--- a/store/federation_nodes.gen.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/federation_nodes.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-type (
- FederationNodes interface {
- SearchFederationNodes(ctx context.Context, f types.NodeFilter) (types.NodeSet, types.NodeFilter, error)
- LookupFederationNodeByID(ctx context.Context, id uint64) (*types.Node, error)
- LookupFederationNodeByBaseURLSharedNodeID(ctx context.Context, base_url string, shared_node_id uint64) (*types.Node, error)
- LookupFederationNodeBySharedNodeID(ctx context.Context, shared_node_id uint64) (*types.Node, error)
-
- CreateFederationNode(ctx context.Context, rr ...*types.Node) error
-
- UpdateFederationNode(ctx context.Context, rr ...*types.Node) error
-
- UpsertFederationNode(ctx context.Context, rr ...*types.Node) error
-
- DeleteFederationNode(ctx context.Context, rr ...*types.Node) error
- DeleteFederationNodeByID(ctx context.Context, ID uint64) error
-
- TruncateFederationNodes(ctx context.Context) error
- }
-)
-
-var _ *types.Node
-var _ context.Context
-
-// SearchFederationNodes returns all matching FederationNodes from store
-func SearchFederationNodes(ctx context.Context, s FederationNodes, f types.NodeFilter) (types.NodeSet, types.NodeFilter, error) {
- return s.SearchFederationNodes(ctx, f)
-}
-
-// LookupFederationNodeByID searches for federation node by ID
-//
-// It returns federation node
-func LookupFederationNodeByID(ctx context.Context, s FederationNodes, id uint64) (*types.Node, error) {
- return s.LookupFederationNodeByID(ctx, id)
-}
-
-// LookupFederationNodeByBaseURLSharedNodeID searches for node by shared-node-id and base-url
-func LookupFederationNodeByBaseURLSharedNodeID(ctx context.Context, s FederationNodes, base_url string, shared_node_id uint64) (*types.Node, error) {
- return s.LookupFederationNodeByBaseURLSharedNodeID(ctx, base_url, shared_node_id)
-}
-
-// LookupFederationNodeBySharedNodeID searches for node by shared-node-id
-func LookupFederationNodeBySharedNodeID(ctx context.Context, s FederationNodes, shared_node_id uint64) (*types.Node, error) {
- return s.LookupFederationNodeBySharedNodeID(ctx, shared_node_id)
-}
-
-// CreateFederationNode creates one or more FederationNodes in store
-func CreateFederationNode(ctx context.Context, s FederationNodes, rr ...*types.Node) error {
- return s.CreateFederationNode(ctx, rr...)
-}
-
-// UpdateFederationNode updates one or more (existing) FederationNodes in store
-func UpdateFederationNode(ctx context.Context, s FederationNodes, rr ...*types.Node) error {
- return s.UpdateFederationNode(ctx, rr...)
-}
-
-// UpsertFederationNode creates new or updates existing one or more FederationNodes in store
-func UpsertFederationNode(ctx context.Context, s FederationNodes, rr ...*types.Node) error {
- return s.UpsertFederationNode(ctx, rr...)
-}
-
-// DeleteFederationNode Deletes one or more FederationNodes from store
-func DeleteFederationNode(ctx context.Context, s FederationNodes, rr ...*types.Node) error {
- return s.DeleteFederationNode(ctx, rr...)
-}
-
-// DeleteFederationNodeByID Deletes FederationNode from store
-func DeleteFederationNodeByID(ctx context.Context, s FederationNodes, ID uint64) error {
- return s.DeleteFederationNodeByID(ctx, ID)
-}
-
-// TruncateFederationNodes Deletes all FederationNodes from store
-func TruncateFederationNodes(ctx context.Context, s FederationNodes) error {
- return s.TruncateFederationNodes(ctx)
-}
diff --git a/store/federation_nodes.yaml b/store/federation_nodes.yaml
deleted file mode 100644
index 41e433273..000000000
--- a/store/federation_nodes.yaml
+++ /dev/null
@@ -1,49 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/federation/types
-
-types:
- type: types.Node
-
-fields:
- - { field: ID }
- - { field: Name }
- - { field: SharedNodeID }
- - { field: BaseURL }
- - { field: Status }
- - { field: Contact }
- - { field: PairToken }
- - { field: AuthToken }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-
-lookups:
- - fields: [ID]
- description: |-
- searches for federation node by ID
-
- It returns federation node
-
- - fields: [BaseURL, SharedNodeID]
- description: |-
- searches for node by shared-node-id and base-url
-
- - fields: [SharedNodeID]
- description: |-
- searches for node by shared-node-id
-
-search:
- enablePaging: false
- enableSorting: false
-
-rdbms:
- alias: fdn
- table: federation_nodes
- customFilterConverter: true
- mapFields:
- BaseURL: { column: base_url }
- SharedNodeID: { column: shared_node_id }
diff --git a/store/federation_nodes_sync.gen.go b/store/federation_nodes_sync.gen.go
deleted file mode 100644
index b0fdd2231..000000000
--- a/store/federation_nodes_sync.gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/federation_nodes_sync.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-type (
- FederationNodesSyncs interface {
- SearchFederationNodesSyncs(ctx context.Context, f types.NodeSyncFilter) (types.NodeSyncSet, types.NodeSyncFilter, error)
- LookupFederationNodesSyncByNodeID(ctx context.Context, node_id uint64) (*types.NodeSync, error)
- LookupFederationNodesSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx context.Context, node_id uint64, module_id uint64, sync_type string, sync_status string) (*types.NodeSync, error)
-
- CreateFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) error
-
- UpdateFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) error
-
- UpsertFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) error
-
- DeleteFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) error
- DeleteFederationNodesSyncByNodeID(ctx context.Context, nodeID uint64) error
-
- TruncateFederationNodesSyncs(ctx context.Context) error
- }
-)
-
-var _ *types.NodeSync
-var _ context.Context
-
-// SearchFederationNodesSyncs returns all matching FederationNodesSyncs from store
-func SearchFederationNodesSyncs(ctx context.Context, s FederationNodesSyncs, f types.NodeSyncFilter) (types.NodeSyncSet, types.NodeSyncFilter, error) {
- return s.SearchFederationNodesSyncs(ctx, f)
-}
-
-// LookupFederationNodesSyncByNodeID searches for sync activity by node ID
-//
-// It returns sync activity
-func LookupFederationNodesSyncByNodeID(ctx context.Context, s FederationNodesSyncs, node_id uint64) (*types.NodeSync, error) {
- return s.LookupFederationNodesSyncByNodeID(ctx, node_id)
-}
-
-// LookupFederationNodesSyncByNodeIDModuleIDSyncTypeSyncStatus searches for activity by node, type and status
-//
-// It returns sync activity
-func LookupFederationNodesSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx context.Context, s FederationNodesSyncs, node_id uint64, module_id uint64, sync_type string, sync_status string) (*types.NodeSync, error) {
- return s.LookupFederationNodesSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx, node_id, module_id, sync_type, sync_status)
-}
-
-// CreateFederationNodesSync creates one or more FederationNodesSyncs in store
-func CreateFederationNodesSync(ctx context.Context, s FederationNodesSyncs, rr ...*types.NodeSync) error {
- return s.CreateFederationNodesSync(ctx, rr...)
-}
-
-// UpdateFederationNodesSync updates one or more (existing) FederationNodesSyncs in store
-func UpdateFederationNodesSync(ctx context.Context, s FederationNodesSyncs, rr ...*types.NodeSync) error {
- return s.UpdateFederationNodesSync(ctx, rr...)
-}
-
-// UpsertFederationNodesSync creates new or updates existing one or more FederationNodesSyncs in store
-func UpsertFederationNodesSync(ctx context.Context, s FederationNodesSyncs, rr ...*types.NodeSync) error {
- return s.UpsertFederationNodesSync(ctx, rr...)
-}
-
-// DeleteFederationNodesSync Deletes one or more FederationNodesSyncs from store
-func DeleteFederationNodesSync(ctx context.Context, s FederationNodesSyncs, rr ...*types.NodeSync) error {
- return s.DeleteFederationNodesSync(ctx, rr...)
-}
-
-// DeleteFederationNodesSyncByNodeID Deletes FederationNodesSync from store
-func DeleteFederationNodesSyncByNodeID(ctx context.Context, s FederationNodesSyncs, nodeID uint64) error {
- return s.DeleteFederationNodesSyncByNodeID(ctx, nodeID)
-}
-
-// TruncateFederationNodesSyncs Deletes all FederationNodesSyncs from store
-func TruncateFederationNodesSyncs(ctx context.Context, s FederationNodesSyncs) error {
- return s.TruncateFederationNodesSyncs(ctx)
-}
diff --git a/store/federation_nodes_sync.yaml b/store/federation_nodes_sync.yaml
deleted file mode 100644
index 529296e84..000000000
--- a/store/federation_nodes_sync.yaml
+++ /dev/null
@@ -1,40 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/federation/types
-
-types:
- type: types.NodeSync
-
-fields:
- - { field: NodeID, isPrimaryKey: true, sortable: true }
- - { field: ModuleID }
- - { field: SyncType }
- - { field: SyncStatus }
- - { field: TimeOfAction, sortable: true }
-
-lookups:
- - fields: [NodeID]
- description: |-
- searches for sync activity by node ID
-
- It returns sync activity
-
- - fields: [NodeID, ModuleID, SyncType, SyncStatus]
- description: |-
- searches for activity by node, type and status
-
- It returns sync activity
-
-search:
- enablePaging: true
- enableSorting: true
-
-rdbms:
- alias: fdns
- table: federation_nodes_sync
- customFilterConverter: true
- mapFields:
- NodeID: { column: rel_node }
- ModuleID: { column: rel_module }
- SyncType: { column: sync_type }
- SyncStatus: { column: sync_status }
- TimeOfAction: { column: time_action }
diff --git a/store/federation_shared_modules.gen.go b/store/federation_shared_modules.gen.go
deleted file mode 100644
index da7ba5482..000000000
--- a/store/federation_shared_modules.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/federation_shared_modules.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-type (
- FederationSharedModules interface {
- SearchFederationSharedModules(ctx context.Context, f types.SharedModuleFilter) (types.SharedModuleSet, types.SharedModuleFilter, error)
- LookupFederationSharedModuleByID(ctx context.Context, id uint64) (*types.SharedModule, error)
-
- CreateFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) error
-
- UpdateFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) error
-
- UpsertFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) error
-
- DeleteFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) error
- DeleteFederationSharedModuleByID(ctx context.Context, ID uint64) error
-
- TruncateFederationSharedModules(ctx context.Context) error
- }
-)
-
-var _ *types.SharedModule
-var _ context.Context
-
-// SearchFederationSharedModules returns all matching FederationSharedModules from store
-func SearchFederationSharedModules(ctx context.Context, s FederationSharedModules, f types.SharedModuleFilter) (types.SharedModuleSet, types.SharedModuleFilter, error) {
- return s.SearchFederationSharedModules(ctx, f)
-}
-
-// LookupFederationSharedModuleByID searches for shared federation module by ID
-//
-// It returns shared federation module
-func LookupFederationSharedModuleByID(ctx context.Context, s FederationSharedModules, id uint64) (*types.SharedModule, error) {
- return s.LookupFederationSharedModuleByID(ctx, id)
-}
-
-// CreateFederationSharedModule creates one or more FederationSharedModules in store
-func CreateFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*types.SharedModule) error {
- return s.CreateFederationSharedModule(ctx, rr...)
-}
-
-// UpdateFederationSharedModule updates one or more (existing) FederationSharedModules in store
-func UpdateFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*types.SharedModule) error {
- return s.UpdateFederationSharedModule(ctx, rr...)
-}
-
-// UpsertFederationSharedModule creates new or updates existing one or more FederationSharedModules in store
-func UpsertFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*types.SharedModule) error {
- return s.UpsertFederationSharedModule(ctx, rr...)
-}
-
-// DeleteFederationSharedModule Deletes one or more FederationSharedModules from store
-func DeleteFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*types.SharedModule) error {
- return s.DeleteFederationSharedModule(ctx, rr...)
-}
-
-// DeleteFederationSharedModuleByID Deletes FederationSharedModule from store
-func DeleteFederationSharedModuleByID(ctx context.Context, s FederationSharedModules, ID uint64) error {
- return s.DeleteFederationSharedModuleByID(ctx, ID)
-}
-
-// TruncateFederationSharedModules Deletes all FederationSharedModules from store
-func TruncateFederationSharedModules(ctx context.Context, s FederationSharedModules) error {
- return s.TruncateFederationSharedModules(ctx)
-}
diff --git a/store/federation_shared_modules.yaml b/store/federation_shared_modules.yaml
deleted file mode 100644
index 4bd5c2ee5..000000000
--- a/store/federation_shared_modules.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/federation/types
-
-types:
- type: types.SharedModule
-
-fields:
- - { field: ID }
- - { field: NodeID }
- - { field: Handle }
- - { field: Name }
- - { field: ExternalFederationModuleID }
- - { field: Fields, type: "json.Text" }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt }
- - { field: UpdatedAt }
- - { field: DeletedAt }
-
-lookups:
- - fields: [ID]
- description: |-
- searches for shared federation module by ID
-
- It returns shared federation module
-
-rdbms:
- alias: cmd
- table: federation_module_shared
- customFilterConverter: true
- mapFields:
- NodeID: { column: rel_node }
- ExternalFederationModuleID: { column: xref_module }
diff --git a/store/flags.gen.go b/store/flags.gen.go
deleted file mode 100644
index b39d1c658..000000000
--- a/store/flags.gen.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/flags.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/pkg/flag/types"
-)
-
-type (
- Flags interface {
- SearchFlags(ctx context.Context, f types.FlagFilter) (types.FlagSet, types.FlagFilter, error)
- LookupFlagByKindResourceIDName(ctx context.Context, kind string, resource_id uint64, name string) (*types.Flag, error)
- LookupFlagByKindResourceID(ctx context.Context, kind string, resource_id uint64) (*types.Flag, error)
- LookupFlagByKindResourceIDOwnedBy(ctx context.Context, kind string, resource_id uint64, owned_by uint64) (*types.Flag, error)
- LookupFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resource_id uint64, owned_by uint64, name string) (*types.Flag, error)
-
- CreateFlag(ctx context.Context, rr ...*types.Flag) error
-
- UpdateFlag(ctx context.Context, rr ...*types.Flag) error
-
- UpsertFlag(ctx context.Context, rr ...*types.Flag) error
-
- DeleteFlag(ctx context.Context, rr ...*types.Flag) error
- DeleteFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resourceID uint64, ownedBy uint64, name string) error
-
- TruncateFlags(ctx context.Context) error
- }
-)
-
-var _ *types.Flag
-var _ context.Context
-
-// SearchFlags returns all matching Flags from store
-func SearchFlags(ctx context.Context, s Flags, f types.FlagFilter) (types.FlagSet, types.FlagFilter, error) {
- return s.SearchFlags(ctx, f)
-}
-
-// LookupFlagByKindResourceIDName Flag lookup by kind, resource, name
-func LookupFlagByKindResourceIDName(ctx context.Context, s Flags, kind string, resource_id uint64, name string) (*types.Flag, error) {
- return s.LookupFlagByKindResourceIDName(ctx, kind, resource_id, name)
-}
-
-// LookupFlagByKindResourceID Flag lookup by kind, resource
-func LookupFlagByKindResourceID(ctx context.Context, s Flags, kind string, resource_id uint64) (*types.Flag, error) {
- return s.LookupFlagByKindResourceID(ctx, kind, resource_id)
-}
-
-// LookupFlagByKindResourceIDOwnedBy Flag lookup by kind, resource, owner
-func LookupFlagByKindResourceIDOwnedBy(ctx context.Context, s Flags, kind string, resource_id uint64, owned_by uint64) (*types.Flag, error) {
- return s.LookupFlagByKindResourceIDOwnedBy(ctx, kind, resource_id, owned_by)
-}
-
-// LookupFlagByKindResourceIDOwnedByName Flag lookup by kind, resource, owner, name
-func LookupFlagByKindResourceIDOwnedByName(ctx context.Context, s Flags, kind string, resource_id uint64, owned_by uint64, name string) (*types.Flag, error) {
- return s.LookupFlagByKindResourceIDOwnedByName(ctx, kind, resource_id, owned_by, name)
-}
-
-// CreateFlag creates one or more Flags in store
-func CreateFlag(ctx context.Context, s Flags, rr ...*types.Flag) error {
- return s.CreateFlag(ctx, rr...)
-}
-
-// UpdateFlag updates one or more (existing) Flags in store
-func UpdateFlag(ctx context.Context, s Flags, rr ...*types.Flag) error {
- return s.UpdateFlag(ctx, rr...)
-}
-
-// UpsertFlag creates new or updates existing one or more Flags in store
-func UpsertFlag(ctx context.Context, s Flags, rr ...*types.Flag) error {
- return s.UpsertFlag(ctx, rr...)
-}
-
-// DeleteFlag Deletes one or more Flags from store
-func DeleteFlag(ctx context.Context, s Flags, rr ...*types.Flag) error {
- return s.DeleteFlag(ctx, rr...)
-}
-
-// DeleteFlagByKindResourceIDOwnedByName Deletes Flag from store
-func DeleteFlagByKindResourceIDOwnedByName(ctx context.Context, s Flags, kind string, resourceID uint64, ownedBy uint64, name string) error {
- return s.DeleteFlagByKindResourceIDOwnedByName(ctx, kind, resourceID, ownedBy, name)
-}
-
-// TruncateFlags Deletes all Flags from store
-func TruncateFlags(ctx context.Context, s Flags) error {
- return s.TruncateFlags(ctx)
-}
diff --git a/store/flags.yaml b/store/flags.yaml
deleted file mode 100644
index b91b37114..000000000
--- a/store/flags.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/pkg/flag/types
-
-types:
- type: types.Flag
-
-fields:
- - { field: Kind, isPrimaryKey: true }
- - { field: ResourceID, isPrimaryKey: true }
- - { field: OwnedBy, isPrimaryKey: true }
-
- - { field: Name, isPrimaryKey: true, lookupFilterPreprocessor: lower }
- - { field: Active }
-
-
-lookups:
- - fields: [ Kind, ResourceID, Name ]
- uniqueConstraintCheck: true
- description: |-
- Flag lookup by kind, resource, name
-
- - fields: [ Kind, ResourceID ]
- uniqueConstraintCheck: true
- description: |-
- Flag lookup by kind, resource
-
- - fields: [ Kind, ResourceID, OwnedBy ]
- uniqueConstraintCheck: true
- description: |-
- Flag lookup by kind, resource, owner
-
- - fields: [ Kind, ResourceID, OwnedBy, Name ]
- uniqueConstraintCheck: true
- description: |-
- Flag lookup by kind, resource, owner, name
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
-
-upsert:
- enable: true
-
-rdbms:
- alias: flg
- table: flags
- customFilterConverter: true
diff --git a/store/interfaces.gen.go b/store/interfaces.gen.go
index 502ebf2c8..539f420f8 100644
--- a/store/interfaces.gen.go
+++ b/store/interfaces.gen.go
@@ -2,56 +2,43 @@ package store
// This file is auto-generated.
//
-// Template: pkg/codegen/assets/store_interfaces_joined.gen.go.tpl
-// Definitions:
-// - store/actionlog.yaml
-// - store/apigw_filter.yaml
-// - store/apigw_route.yaml
-// - store/applications.yaml
-// - store/attachments.yaml
-// - store/auth_clients.yaml
-// - store/auth_confirmed_clients.yaml
-// - store/auth_oa2tokens.yaml
-// - store/auth_sessions.yaml
-// - store/automation_sessions.yaml
-// - store/automation_triggers.yaml
-// - store/automation_workflows.yaml
-// - store/compose_attachments.yaml
-// - store/compose_charts.yaml
-// - store/compose_module_fields.yaml
-// - store/compose_modules.yaml
-// - store/compose_namespaces.yaml
-// - store/compose_pages.yaml
-// - store/compose_record_values.yaml
-// - store/compose_records.yaml
-// - store/credentials.yaml
-// - store/federation_exposed_modules.yaml
-// - store/federation_module_mappings.yaml
-// - store/federation_nodes.yaml
-// - store/federation_nodes_sync.yaml
-// - store/federation_shared_modules.yaml
-// - store/flags.yaml
-// - store/labels.yaml
-// - store/queue.yaml
-// - store/queue_message.yaml
-// - store/rbac_rules.yaml
-// - store/reminders.yaml
-// - store/reports.yaml
-// - store/resource_activity_log.yaml
-// - store/resource_translation.yaml
-// - store/role_members.yaml
-// - store/roles.yaml
-// - store/settings.yaml
-// - store/templates.yaml
-// - store/users.yaml
-//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
+import (
+ "context"
+ automationType "github.com/cortezaproject/corteza-server/automation/types"
+ composeType "github.com/cortezaproject/corteza-server/compose/types"
+ federationType "github.com/cortezaproject/corteza-server/federation/types"
+ actionlogType "github.com/cortezaproject/corteza-server/pkg/actionlog"
+ discoveryType "github.com/cortezaproject/corteza-server/pkg/discovery/types"
+ flagType "github.com/cortezaproject/corteza-server/pkg/flag/types"
+ labelsType "github.com/cortezaproject/corteza-server/pkg/label/types"
+ "github.com/cortezaproject/corteza-server/pkg/locale"
+ rbacType "github.com/cortezaproject/corteza-server/pkg/rbac"
+ "github.com/cortezaproject/corteza-server/pkg/report"
+ systemType "github.com/cortezaproject/corteza-server/system/types"
+ "go.uber.org/zap"
+ "golang.org/x/text/language"
+)
+
type (
- // Sortable interface combines interfaces of all supported store interfaces
- storerGenerated interface {
+ // Storer interface combines interfaces of all supported store interfaces
+ Storer interface {
+ // SetLogger sets new logging facility
+ //
+ // Store facility should fallback to logger.Default when no logging facility is set
+ //
+ // Intentionally closely coupled with Zap logger since this is not some public lib
+ // and it's highly unlikely we'll support different/multiple logging "backend"
+ SetLogger(*zap.Logger)
+
+ // Tx is a transaction handler
+ Tx(context.Context, func(context.Context, Storer) error) error
+
+ // Upgrade store's schema to the latest version
+ Upgrade(context.Context, *zap.Logger) error
Actionlogs
ApigwFilters
ApigwRoutes
@@ -66,17 +53,17 @@ type (
AutomationWorkflows
ComposeAttachments
ComposeCharts
- ComposeModuleFields
ComposeModules
+ ComposeModuleFields
ComposeNamespaces
ComposePages
- ComposeRecordValues
ComposeRecords
+ ComposeRecordValues
Credentials
FederationExposedModules
FederationModuleMappings
FederationNodes
- FederationNodesSyncs
+ FederationNodeSyncs
FederationSharedModules
Flags
Labels
@@ -85,12 +72,3087 @@ type (
RbacRules
Reminders
Reports
- ResourceActivityLogs
+ ResourceActivitys
ResourceTranslations
- RoleMembers
Roles
- Settings
+ RoleMembers
+ SettingValues
Templates
Users
}
+
+ Actionlogs interface {
+ SearchActionlogs(ctx context.Context, f actionlogType.Filter) (actionlogType.ActionSet, actionlogType.Filter, error)
+ CreateActionlog(ctx context.Context, rr ...*actionlogType.Action) error
+ UpdateActionlog(ctx context.Context, rr ...*actionlogType.Action) error
+ UpsertActionlog(ctx context.Context, rr ...*actionlogType.Action) error
+ DeleteActionlog(ctx context.Context, rr ...*actionlogType.Action) error
+ DeleteActionlogByID(ctx context.Context, id uint64) error
+ TruncateActionlogs(ctx context.Context) error
+ LookupActionlogByID(ctx context.Context, id uint64) (*actionlogType.Action, error)
+ }
+
+ ApigwFilters interface {
+ SearchApigwFilters(ctx context.Context, f systemType.ApigwFilterFilter) (systemType.ApigwFilterSet, systemType.ApigwFilterFilter, error)
+ CreateApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) error
+ UpdateApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) error
+ UpsertApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) error
+ DeleteApigwFilter(ctx context.Context, rr ...*systemType.ApigwFilter) error
+ DeleteApigwFilterByID(ctx context.Context, id uint64) error
+ TruncateApigwFilters(ctx context.Context) error
+ LookupApigwFilterByID(ctx context.Context, id uint64) (*systemType.ApigwFilter, error)
+ LookupApigwFilterByRoute(ctx context.Context, route uint64) (*systemType.ApigwFilter, error)
+ }
+
+ ApigwRoutes interface {
+ SearchApigwRoutes(ctx context.Context, f systemType.ApigwRouteFilter) (systemType.ApigwRouteSet, systemType.ApigwRouteFilter, error)
+ CreateApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) error
+ UpdateApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) error
+ UpsertApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) error
+ DeleteApigwRoute(ctx context.Context, rr ...*systemType.ApigwRoute) error
+ DeleteApigwRouteByID(ctx context.Context, id uint64) error
+ TruncateApigwRoutes(ctx context.Context) error
+ LookupApigwRouteByID(ctx context.Context, id uint64) (*systemType.ApigwRoute, error)
+ LookupApigwRouteByEndpoint(ctx context.Context, endpoint string) (*systemType.ApigwRoute, error)
+ }
+
+ Applications interface {
+ SearchApplications(ctx context.Context, f systemType.ApplicationFilter) (systemType.ApplicationSet, systemType.ApplicationFilter, error)
+ CreateApplication(ctx context.Context, rr ...*systemType.Application) error
+ UpdateApplication(ctx context.Context, rr ...*systemType.Application) error
+ UpsertApplication(ctx context.Context, rr ...*systemType.Application) error
+ DeleteApplication(ctx context.Context, rr ...*systemType.Application) error
+ DeleteApplicationByID(ctx context.Context, id uint64) error
+ TruncateApplications(ctx context.Context) error
+ LookupApplicationByID(ctx context.Context, id uint64) (*systemType.Application, error)
+ ApplicationMetrics(ctx context.Context) (*systemType.ApplicationMetrics, error)
+ ReorderApplications(ctx context.Context, order []uint64) error
+ }
+
+ Attachments interface {
+ SearchAttachments(ctx context.Context, f systemType.AttachmentFilter) (systemType.AttachmentSet, systemType.AttachmentFilter, error)
+ CreateAttachment(ctx context.Context, rr ...*systemType.Attachment) error
+ UpdateAttachment(ctx context.Context, rr ...*systemType.Attachment) error
+ UpsertAttachment(ctx context.Context, rr ...*systemType.Attachment) error
+ DeleteAttachment(ctx context.Context, rr ...*systemType.Attachment) error
+ DeleteAttachmentByID(ctx context.Context, id uint64) error
+ TruncateAttachments(ctx context.Context) error
+ LookupAttachmentByID(ctx context.Context, id uint64) (*systemType.Attachment, error)
+ }
+
+ AuthClients interface {
+ SearchAuthClients(ctx context.Context, f systemType.AuthClientFilter) (systemType.AuthClientSet, systemType.AuthClientFilter, error)
+ CreateAuthClient(ctx context.Context, rr ...*systemType.AuthClient) error
+ UpdateAuthClient(ctx context.Context, rr ...*systemType.AuthClient) error
+ UpsertAuthClient(ctx context.Context, rr ...*systemType.AuthClient) error
+ DeleteAuthClient(ctx context.Context, rr ...*systemType.AuthClient) error
+ DeleteAuthClientByID(ctx context.Context, id uint64) error
+ TruncateAuthClients(ctx context.Context) error
+ LookupAuthClientByID(ctx context.Context, id uint64) (*systemType.AuthClient, error)
+ LookupAuthClientByHandle(ctx context.Context, handle string) (*systemType.AuthClient, error)
+ }
+
+ AuthConfirmedClients interface {
+ SearchAuthConfirmedClients(ctx context.Context, f systemType.AuthConfirmedClientFilter) (systemType.AuthConfirmedClientSet, systemType.AuthConfirmedClientFilter, error)
+ CreateAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) error
+ UpdateAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) error
+ UpsertAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) error
+ DeleteAuthConfirmedClient(ctx context.Context, rr ...*systemType.AuthConfirmedClient) error
+ DeleteAuthConfirmedClientByUserIDClientID(ctx context.Context, userID uint64, clientID uint64) error
+ TruncateAuthConfirmedClients(ctx context.Context) error
+ LookupAuthConfirmedClientByUserIDClientID(ctx context.Context, userID uint64, clientID uint64) (*systemType.AuthConfirmedClient, error)
+ }
+
+ AuthOa2tokens interface {
+ SearchAuthOa2tokens(ctx context.Context, f systemType.AuthOa2tokenFilter) (systemType.AuthOa2tokenSet, systemType.AuthOa2tokenFilter, error)
+ CreateAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) error
+ UpdateAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) error
+ UpsertAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) error
+ DeleteAuthOa2token(ctx context.Context, rr ...*systemType.AuthOa2token) error
+ DeleteAuthOa2tokenByID(ctx context.Context, id uint64) error
+ TruncateAuthOa2tokens(ctx context.Context) error
+ LookupAuthOa2tokenByID(ctx context.Context, id uint64) (*systemType.AuthOa2token, error)
+ LookupAuthOa2tokenByCode(ctx context.Context, code string) (*systemType.AuthOa2token, error)
+ LookupAuthOa2tokenByAccess(ctx context.Context, access string) (*systemType.AuthOa2token, error)
+ LookupAuthOa2tokenByRefresh(ctx context.Context, refresh string) (*systemType.AuthOa2token, error)
+ DeleteExpiredAuthOA2Tokens(ctx context.Context) error
+ DeleteAuthOA2TokenByCode(ctx context.Context, code string) error
+ DeleteAuthOA2TokenByAccess(ctx context.Context, access string) error
+ DeleteAuthOA2TokenByRefresh(ctx context.Context, refresh string) error
+ DeleteAuthOA2TokenByUserID(ctx context.Context, userID uint64) error
+ }
+
+ AuthSessions interface {
+ SearchAuthSessions(ctx context.Context, f systemType.AuthSessionFilter) (systemType.AuthSessionSet, systemType.AuthSessionFilter, error)
+ CreateAuthSession(ctx context.Context, rr ...*systemType.AuthSession) error
+ UpdateAuthSession(ctx context.Context, rr ...*systemType.AuthSession) error
+ UpsertAuthSession(ctx context.Context, rr ...*systemType.AuthSession) error
+ DeleteAuthSession(ctx context.Context, rr ...*systemType.AuthSession) error
+ DeleteAuthSessionByID(ctx context.Context, id string) error
+ TruncateAuthSessions(ctx context.Context) error
+ LookupAuthSessionByID(ctx context.Context, id string) (*systemType.AuthSession, error)
+ DeleteExpiredAuthSessions(ctx context.Context) error
+ DeleteAuthSessionsByUserID(ctx context.Context, userID uint64) error
+ }
+
+ AutomationSessions interface {
+ SearchAutomationSessions(ctx context.Context, f automationType.SessionFilter) (automationType.SessionSet, automationType.SessionFilter, error)
+ CreateAutomationSession(ctx context.Context, rr ...*automationType.Session) error
+ UpdateAutomationSession(ctx context.Context, rr ...*automationType.Session) error
+ UpsertAutomationSession(ctx context.Context, rr ...*automationType.Session) error
+ DeleteAutomationSession(ctx context.Context, rr ...*automationType.Session) error
+ DeleteAutomationSessionByID(ctx context.Context, id uint64) error
+ TruncateAutomationSessions(ctx context.Context) error
+ LookupAutomationSessionByID(ctx context.Context, id uint64) (*automationType.Session, error)
+ }
+
+ AutomationTriggers interface {
+ SearchAutomationTriggers(ctx context.Context, f automationType.TriggerFilter) (automationType.TriggerSet, automationType.TriggerFilter, error)
+ CreateAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) error
+ UpdateAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) error
+ UpsertAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) error
+ DeleteAutomationTrigger(ctx context.Context, rr ...*automationType.Trigger) error
+ DeleteAutomationTriggerByID(ctx context.Context, id uint64) error
+ TruncateAutomationTriggers(ctx context.Context) error
+ LookupAutomationTriggerByID(ctx context.Context, id uint64) (*automationType.Trigger, error)
+ }
+
+ AutomationWorkflows interface {
+ SearchAutomationWorkflows(ctx context.Context, f automationType.WorkflowFilter) (automationType.WorkflowSet, automationType.WorkflowFilter, error)
+ CreateAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) error
+ UpdateAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) error
+ UpsertAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) error
+ DeleteAutomationWorkflow(ctx context.Context, rr ...*automationType.Workflow) error
+ DeleteAutomationWorkflowByID(ctx context.Context, id uint64) error
+ TruncateAutomationWorkflows(ctx context.Context) error
+ LookupAutomationWorkflowByID(ctx context.Context, id uint64) (*automationType.Workflow, error)
+ LookupAutomationWorkflowByHandle(ctx context.Context, handle string) (*automationType.Workflow, error)
+ }
+
+ ComposeAttachments interface {
+ SearchComposeAttachments(ctx context.Context, f composeType.AttachmentFilter) (composeType.AttachmentSet, composeType.AttachmentFilter, error)
+ CreateComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) error
+ UpdateComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) error
+ UpsertComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) error
+ DeleteComposeAttachment(ctx context.Context, rr ...*composeType.Attachment) error
+ DeleteComposeAttachmentByID(ctx context.Context, id uint64) error
+ TruncateComposeAttachments(ctx context.Context) error
+ LookupComposeAttachmentByID(ctx context.Context, id uint64) (*composeType.Attachment, error)
+ }
+
+ ComposeCharts interface {
+ SearchComposeCharts(ctx context.Context, f composeType.ChartFilter) (composeType.ChartSet, composeType.ChartFilter, error)
+ CreateComposeChart(ctx context.Context, rr ...*composeType.Chart) error
+ UpdateComposeChart(ctx context.Context, rr ...*composeType.Chart) error
+ UpsertComposeChart(ctx context.Context, rr ...*composeType.Chart) error
+ DeleteComposeChart(ctx context.Context, rr ...*composeType.Chart) error
+ DeleteComposeChartByID(ctx context.Context, id uint64) error
+ TruncateComposeCharts(ctx context.Context) error
+ LookupComposeChartByID(ctx context.Context, id uint64) (*composeType.Chart, error)
+ LookupComposeChartByNamespaceIDHandle(ctx context.Context, namespaceID uint64, handle string) (*composeType.Chart, error)
+ }
+
+ ComposeModules interface {
+ SearchComposeModules(ctx context.Context, f composeType.ModuleFilter) (composeType.ModuleSet, composeType.ModuleFilter, error)
+ CreateComposeModule(ctx context.Context, rr ...*composeType.Module) error
+ UpdateComposeModule(ctx context.Context, rr ...*composeType.Module) error
+ UpsertComposeModule(ctx context.Context, rr ...*composeType.Module) error
+ DeleteComposeModule(ctx context.Context, rr ...*composeType.Module) error
+ DeleteComposeModuleByID(ctx context.Context, id uint64) error
+ TruncateComposeModules(ctx context.Context) error
+ LookupComposeModuleByNamespaceIDHandle(ctx context.Context, namespaceID uint64, handle string) (*composeType.Module, error)
+ LookupComposeModuleByNamespaceIDName(ctx context.Context, namespaceID uint64, name string) (*composeType.Module, error)
+ LookupComposeModuleByID(ctx context.Context, id uint64) (*composeType.Module, error)
+ }
+
+ ComposeModuleFields interface {
+ SearchComposeModuleFields(ctx context.Context, f composeType.ModuleFieldFilter) (composeType.ModuleFieldSet, composeType.ModuleFieldFilter, error)
+ CreateComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) error
+ UpdateComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) error
+ UpsertComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) error
+ DeleteComposeModuleField(ctx context.Context, rr ...*composeType.ModuleField) error
+ DeleteComposeModuleFieldByID(ctx context.Context, id uint64) error
+ TruncateComposeModuleFields(ctx context.Context) error
+ LookupComposeModuleFieldByModuleIDName(ctx context.Context, moduleID uint64, name string) (*composeType.ModuleField, error)
+ }
+
+ ComposeNamespaces interface {
+ SearchComposeNamespaces(ctx context.Context, f composeType.NamespaceFilter) (composeType.NamespaceSet, composeType.NamespaceFilter, error)
+ CreateComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) error
+ UpdateComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) error
+ UpsertComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) error
+ DeleteComposeNamespace(ctx context.Context, rr ...*composeType.Namespace) error
+ DeleteComposeNamespaceByID(ctx context.Context, id uint64) error
+ TruncateComposeNamespaces(ctx context.Context) error
+ LookupComposeNamespaceBySlug(ctx context.Context, slug string) (*composeType.Namespace, error)
+ LookupComposeNamespaceByID(ctx context.Context, id uint64) (*composeType.Namespace, error)
+ }
+
+ ComposePages interface {
+ SearchComposePages(ctx context.Context, f composeType.PageFilter) (composeType.PageSet, composeType.PageFilter, error)
+ CreateComposePage(ctx context.Context, rr ...*composeType.Page) error
+ UpdateComposePage(ctx context.Context, rr ...*composeType.Page) error
+ UpsertComposePage(ctx context.Context, rr ...*composeType.Page) error
+ DeleteComposePage(ctx context.Context, rr ...*composeType.Page) error
+ DeleteComposePageByID(ctx context.Context, id uint64) error
+ TruncateComposePages(ctx context.Context) error
+ LookupComposePageByNamespaceIDHandle(ctx context.Context, namespaceID uint64, handle string) (*composeType.Page, error)
+ LookupComposePageByNamespaceIDModuleID(ctx context.Context, namespaceID uint64, moduleID uint64) (*composeType.Page, error)
+ LookupComposePageByID(ctx context.Context, id uint64) (*composeType.Page, error)
+ ReorderComposePages(ctx context.Context, namespace_id uint64, parent_id uint64, page_ids []uint64) error
+ }
+
+ ComposeRecords interface {
+ SearchComposeRecords(ctx context.Context, mod *composeType.Module, f composeType.RecordFilter) (composeType.RecordSet, composeType.RecordFilter, error)
+ CreateComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) error
+ UpdateComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) error
+ UpsertComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) error
+ DeleteComposeRecord(ctx context.Context, mod *composeType.Module, rr ...*composeType.Record) error
+ DeleteComposeRecordByID(ctx context.Context, mod *composeType.Module, id uint64) error
+ TruncateComposeRecords(ctx context.Context, mod *composeType.Module) error
+ LookupComposeRecordByID(ctx context.Context, mod *composeType.Module, id uint64) (*composeType.Record, error)
+ ComposeRecordReport(ctx context.Context, mod *composeType.Module, metrics string, dimensions string, filters string) ([]map[string]interface{}, error)
+ ComposeRecordDatasource(ctx context.Context, mod *composeType.Module, ld *report.LoadStepDefinition) (report.Datasource, error)
+ PartialComposeRecordValueUpdate(ctx context.Context, mod *composeType.Module, values ...*composeType.RecordValue) error
+ }
+
+ ComposeRecordValues interface {
+ SearchComposeRecordValues(ctx context.Context, f composeType.RecordValueFilter) (composeType.RecordValueSet, composeType.RecordValueFilter, error)
+ CreateComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) error
+ UpdateComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) error
+ UpsertComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) error
+ DeleteComposeRecordValue(ctx context.Context, rr ...*composeType.RecordValue) error
+ DeleteComposeRecordValueByRecordIDNamePlace(ctx context.Context, recordID uint64, name string, place uint) error
+ TruncateComposeRecordValues(ctx context.Context) error
+ ComposeRecordValueRefLookup(ctx context.Context, mod *composeType.Module, field string, ref uint64) (uint64, error)
+ }
+
+ Credentials interface {
+ SearchCredentials(ctx context.Context, f systemType.CredentialFilter) (systemType.CredentialSet, systemType.CredentialFilter, error)
+ CreateCredential(ctx context.Context, rr ...*systemType.Credential) error
+ UpdateCredential(ctx context.Context, rr ...*systemType.Credential) error
+ UpsertCredential(ctx context.Context, rr ...*systemType.Credential) error
+ DeleteCredential(ctx context.Context, rr ...*systemType.Credential) error
+ DeleteCredentialByID(ctx context.Context, id uint64) error
+ TruncateCredentials(ctx context.Context) error
+ LookupCredentialByID(ctx context.Context, id uint64) (*systemType.Credential, error)
+ }
+
+ FederationExposedModules interface {
+ SearchFederationExposedModules(ctx context.Context, f federationType.ExposedModuleFilter) (federationType.ExposedModuleSet, federationType.ExposedModuleFilter, error)
+ CreateFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) error
+ UpdateFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) error
+ UpsertFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) error
+ DeleteFederationExposedModule(ctx context.Context, rr ...*federationType.ExposedModule) error
+ DeleteFederationExposedModuleByID(ctx context.Context, id uint64) error
+ TruncateFederationExposedModules(ctx context.Context) error
+ LookupFederationExposedModuleByID(ctx context.Context, id uint64) (*federationType.ExposedModule, error)
+ }
+
+ FederationModuleMappings interface {
+ SearchFederationModuleMappings(ctx context.Context, f federationType.ModuleMappingFilter) (federationType.ModuleMappingSet, federationType.ModuleMappingFilter, error)
+ CreateFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) error
+ UpdateFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) error
+ UpsertFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) error
+ DeleteFederationModuleMapping(ctx context.Context, rr ...*federationType.ModuleMapping) error
+ DeleteFederationModuleMappingBy(ctx context.Context) error
+ TruncateFederationModuleMappings(ctx context.Context) error
+ LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, federationModuleID uint64, composeModuleID uint64, composeNamespaceID uint64) (*federationType.ModuleMapping, error)
+ LookupFederationModuleMappingByFederationModuleID(ctx context.Context, federationModuleID uint64) (*federationType.ModuleMapping, error)
+ }
+
+ FederationNodes interface {
+ SearchFederationNodes(ctx context.Context, f federationType.NodeFilter) (federationType.NodeSet, federationType.NodeFilter, error)
+ CreateFederationNode(ctx context.Context, rr ...*federationType.Node) error
+ UpdateFederationNode(ctx context.Context, rr ...*federationType.Node) error
+ UpsertFederationNode(ctx context.Context, rr ...*federationType.Node) error
+ DeleteFederationNode(ctx context.Context, rr ...*federationType.Node) error
+ DeleteFederationNodeByID(ctx context.Context, id uint64) error
+ TruncateFederationNodes(ctx context.Context) error
+ LookupFederationNodeByID(ctx context.Context, id uint64) (*federationType.Node, error)
+ LookupFederationNodeByBaseURLSharedNodeID(ctx context.Context, baseURL string, sharedNodeID uint64) (*federationType.Node, error)
+ LookupFederationNodeBySharedNodeID(ctx context.Context, sharedNodeID uint64) (*federationType.Node, error)
+ }
+
+ FederationNodeSyncs interface {
+ SearchFederationNodeSyncs(ctx context.Context, f federationType.NodeSyncFilter) (federationType.NodeSyncSet, federationType.NodeSyncFilter, error)
+ CreateFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) error
+ UpdateFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) error
+ UpsertFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) error
+ DeleteFederationNodeSync(ctx context.Context, rr ...*federationType.NodeSync) error
+ DeleteFederationNodeSyncByNodeID(ctx context.Context, nodeID uint64) error
+ TruncateFederationNodeSyncs(ctx context.Context) error
+ LookupFederationNodeSyncByNodeID(ctx context.Context, nodeID uint64) (*federationType.NodeSync, error)
+ LookupFederationNodeSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx context.Context, nodeID uint64, moduleID uint64, syncType string, syncStatus string) (*federationType.NodeSync, error)
+ }
+
+ FederationSharedModules interface {
+ SearchFederationSharedModules(ctx context.Context, f federationType.SharedModuleFilter) (federationType.SharedModuleSet, federationType.SharedModuleFilter, error)
+ CreateFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) error
+ UpdateFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) error
+ UpsertFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) error
+ DeleteFederationSharedModule(ctx context.Context, rr ...*federationType.SharedModule) error
+ DeleteFederationSharedModuleByID(ctx context.Context, id uint64) error
+ TruncateFederationSharedModules(ctx context.Context) error
+ LookupFederationSharedModuleByID(ctx context.Context, id uint64) (*federationType.SharedModule, error)
+ }
+
+ Flags interface {
+ SearchFlags(ctx context.Context, f flagType.FlagFilter) (flagType.FlagSet, flagType.FlagFilter, error)
+ CreateFlag(ctx context.Context, rr ...*flagType.Flag) error
+ UpdateFlag(ctx context.Context, rr ...*flagType.Flag) error
+ UpsertFlag(ctx context.Context, rr ...*flagType.Flag) error
+ DeleteFlag(ctx context.Context, rr ...*flagType.Flag) error
+ DeleteFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resourceID uint64, ownedBy uint64, name string) error
+ TruncateFlags(ctx context.Context) error
+ LookupFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resourceID uint64, ownedBy uint64, name string) (*flagType.Flag, error)
+ }
+
+ Labels interface {
+ SearchLabels(ctx context.Context, f labelsType.LabelFilter) (labelsType.LabelSet, labelsType.LabelFilter, error)
+ CreateLabel(ctx context.Context, rr ...*labelsType.Label) error
+ UpdateLabel(ctx context.Context, rr ...*labelsType.Label) error
+ UpsertLabel(ctx context.Context, rr ...*labelsType.Label) error
+ DeleteLabel(ctx context.Context, rr ...*labelsType.Label) error
+ DeleteLabelByKindResourceIDName(ctx context.Context, kind string, resourceID uint64, name string) error
+ TruncateLabels(ctx context.Context) error
+ LookupLabelByKindResourceIDName(ctx context.Context, kind string, resourceID uint64, name string) (*labelsType.Label, error)
+ DeleteExtraLabels(ctx context.Context, kind string, resourceId uint64, name ...string) error
+ }
+
+ Queues interface {
+ SearchQueues(ctx context.Context, f systemType.QueueFilter) (systemType.QueueSet, systemType.QueueFilter, error)
+ CreateQueue(ctx context.Context, rr ...*systemType.Queue) error
+ UpdateQueue(ctx context.Context, rr ...*systemType.Queue) error
+ UpsertQueue(ctx context.Context, rr ...*systemType.Queue) error
+ DeleteQueue(ctx context.Context, rr ...*systemType.Queue) error
+ DeleteQueueByID(ctx context.Context, id uint64) error
+ TruncateQueues(ctx context.Context) error
+ LookupQueueByID(ctx context.Context, id uint64) (*systemType.Queue, error)
+ LookupQueueByQueue(ctx context.Context, queue string) (*systemType.Queue, error)
+ }
+
+ QueueMessages interface {
+ SearchQueueMessages(ctx context.Context, f systemType.QueueMessageFilter) (systemType.QueueMessageSet, systemType.QueueMessageFilter, error)
+ CreateQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) error
+ UpdateQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) error
+ UpsertQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) error
+ DeleteQueueMessage(ctx context.Context, rr ...*systemType.QueueMessage) error
+ DeleteQueueMessageByID(ctx context.Context, id uint64) error
+ TruncateQueueMessages(ctx context.Context) error
+ }
+
+ RbacRules interface {
+ SearchRbacRules(ctx context.Context, f rbacType.RuleFilter) (rbacType.RuleSet, rbacType.RuleFilter, error)
+ CreateRbacRule(ctx context.Context, rr ...*rbacType.Rule) error
+ UpdateRbacRule(ctx context.Context, rr ...*rbacType.Rule) error
+ UpsertRbacRule(ctx context.Context, rr ...*rbacType.Rule) error
+ DeleteRbacRule(ctx context.Context, rr ...*rbacType.Rule) error
+ DeleteRbacRuleByRoleIDResourceOperation(ctx context.Context, roleID uint64, resource string, operation string) error
+ TruncateRbacRules(ctx context.Context) error
+ TransferRbacRules(ctx context.Context, src uint64, dst uint64) error
+ }
+
+ Reminders interface {
+ SearchReminders(ctx context.Context, f systemType.ReminderFilter) (systemType.ReminderSet, systemType.ReminderFilter, error)
+ CreateReminder(ctx context.Context, rr ...*systemType.Reminder) error
+ UpdateReminder(ctx context.Context, rr ...*systemType.Reminder) error
+ UpsertReminder(ctx context.Context, rr ...*systemType.Reminder) error
+ DeleteReminder(ctx context.Context, rr ...*systemType.Reminder) error
+ DeleteReminderByID(ctx context.Context, id uint64) error
+ TruncateReminders(ctx context.Context) error
+ LookupReminderByID(ctx context.Context, id uint64) (*systemType.Reminder, error)
+ }
+
+ Reports interface {
+ SearchReports(ctx context.Context, f systemType.ReportFilter) (systemType.ReportSet, systemType.ReportFilter, error)
+ CreateReport(ctx context.Context, rr ...*systemType.Report) error
+ UpdateReport(ctx context.Context, rr ...*systemType.Report) error
+ UpsertReport(ctx context.Context, rr ...*systemType.Report) error
+ DeleteReport(ctx context.Context, rr ...*systemType.Report) error
+ DeleteReportByID(ctx context.Context, id uint64) error
+ TruncateReports(ctx context.Context) error
+ LookupReportByID(ctx context.Context, id uint64) (*systemType.Report, error)
+ LookupReportByHandle(ctx context.Context, handle string) (*systemType.Report, error)
+ }
+
+ ResourceActivitys interface {
+ SearchResourceActivitys(ctx context.Context, f discoveryType.ResourceActivityFilter) (discoveryType.ResourceActivitySet, discoveryType.ResourceActivityFilter, error)
+ CreateResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) error
+ UpdateResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) error
+ UpsertResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) error
+ DeleteResourceActivity(ctx context.Context, rr ...*discoveryType.ResourceActivity) error
+ DeleteResourceActivityByID(ctx context.Context, id uint64) error
+ TruncateResourceActivitys(ctx context.Context) error
+ }
+
+ ResourceTranslations interface {
+ SearchResourceTranslations(ctx context.Context, f systemType.ResourceTranslationFilter) (systemType.ResourceTranslationSet, systemType.ResourceTranslationFilter, error)
+ CreateResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) error
+ UpdateResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) error
+ UpsertResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) error
+ DeleteResourceTranslation(ctx context.Context, rr ...*systemType.ResourceTranslation) error
+ DeleteResourceTranslationByID(ctx context.Context, id uint64) error
+ TruncateResourceTranslations(ctx context.Context) error
+ LookupResourceTranslationByID(ctx context.Context, id uint64) (*systemType.ResourceTranslation, error)
+ TransformResource(ctx context.Context, lang language.Tag) (map[string]map[string]*locale.ResourceTranslation, error)
+ }
+
+ Roles interface {
+ SearchRoles(ctx context.Context, f systemType.RoleFilter) (systemType.RoleSet, systemType.RoleFilter, error)
+ CreateRole(ctx context.Context, rr ...*systemType.Role) error
+ UpdateRole(ctx context.Context, rr ...*systemType.Role) error
+ UpsertRole(ctx context.Context, rr ...*systemType.Role) error
+ DeleteRole(ctx context.Context, rr ...*systemType.Role) error
+ DeleteRoleByID(ctx context.Context, id uint64) error
+ TruncateRoles(ctx context.Context) error
+ LookupRoleByID(ctx context.Context, id uint64) (*systemType.Role, error)
+ LookupRoleByHandle(ctx context.Context, handle string) (*systemType.Role, error)
+ LookupRoleByName(ctx context.Context, name string) (*systemType.Role, error)
+ RoleMetrics(ctx context.Context) (*systemType.RoleMetrics, error)
+ }
+
+ RoleMembers interface {
+ SearchRoleMembers(ctx context.Context, f systemType.RoleMemberFilter) (systemType.RoleMemberSet, systemType.RoleMemberFilter, error)
+ CreateRoleMember(ctx context.Context, rr ...*systemType.RoleMember) error
+ UpdateRoleMember(ctx context.Context, rr ...*systemType.RoleMember) error
+ UpsertRoleMember(ctx context.Context, rr ...*systemType.RoleMember) error
+ DeleteRoleMember(ctx context.Context, rr ...*systemType.RoleMember) error
+ DeleteRoleMemberByUserIDRoleID(ctx context.Context, userID uint64, roleID uint64) error
+ TruncateRoleMembers(ctx context.Context) error
+ TransferRoleMembers(ctx context.Context, src uint64, dst uint64) error
+ }
+
+ SettingValues interface {
+ SearchSettingValues(ctx context.Context, f systemType.SettingsFilter) (systemType.SettingValueSet, systemType.SettingsFilter, error)
+ CreateSettingValue(ctx context.Context, rr ...*systemType.SettingValue) error
+ UpdateSettingValue(ctx context.Context, rr ...*systemType.SettingValue) error
+ UpsertSettingValue(ctx context.Context, rr ...*systemType.SettingValue) error
+ DeleteSettingValue(ctx context.Context, rr ...*systemType.SettingValue) error
+ DeleteSettingValueByNameOwnedBy(ctx context.Context, name string, ownedBy uint64) error
+ TruncateSettingValues(ctx context.Context) error
+ LookupSettingValueByNameOwnedBy(ctx context.Context, name string, ownedBy uint64) (*systemType.SettingValue, error)
+ }
+
+ Templates interface {
+ SearchTemplates(ctx context.Context, f systemType.TemplateFilter) (systemType.TemplateSet, systemType.TemplateFilter, error)
+ CreateTemplate(ctx context.Context, rr ...*systemType.Template) error
+ UpdateTemplate(ctx context.Context, rr ...*systemType.Template) error
+ UpsertTemplate(ctx context.Context, rr ...*systemType.Template) error
+ DeleteTemplate(ctx context.Context, rr ...*systemType.Template) error
+ DeleteTemplateByID(ctx context.Context, id uint64) error
+ TruncateTemplates(ctx context.Context) error
+ LookupTemplateByID(ctx context.Context, id uint64) (*systemType.Template, error)
+ LookupTemplateByHandle(ctx context.Context, handle string) (*systemType.Template, error)
+ }
+
+ Users interface {
+ SearchUsers(ctx context.Context, f systemType.UserFilter) (systemType.UserSet, systemType.UserFilter, error)
+ CreateUser(ctx context.Context, rr ...*systemType.User) error
+ UpdateUser(ctx context.Context, rr ...*systemType.User) error
+ UpsertUser(ctx context.Context, rr ...*systemType.User) error
+ DeleteUser(ctx context.Context, rr ...*systemType.User) error
+ DeleteUserByID(ctx context.Context, id uint64) error
+ TruncateUsers(ctx context.Context) error
+ LookupUserByID(ctx context.Context, id uint64) (*systemType.User, error)
+ LookupUserByEmail(ctx context.Context, email string) (*systemType.User, error)
+ LookupUserByHandle(ctx context.Context, handle string) (*systemType.User, error)
+ LookupUserByUsername(ctx context.Context, username string) (*systemType.User, error)
+ CountUsers(ctx context.Context, u systemType.UserFilter) (uint, error)
+ UserMetrics(ctx context.Context) (*systemType.UserMetrics, error)
+ }
)
+
+// SearchActionlogs returns all matching Actionlogs from store
+//
+// This function is auto-generated
+func SearchActionlogs(ctx context.Context, s Actionlogs, f actionlogType.Filter) (actionlogType.ActionSet, actionlogType.Filter, error) {
+ return s.SearchActionlogs(ctx, f)
+}
+
+// CreateActionlog creates one or more Actionlogs in store
+//
+// This function is auto-generated
+func CreateActionlog(ctx context.Context, s Actionlogs, rr ...*actionlogType.Action) error {
+ return s.CreateActionlog(ctx, rr...)
+}
+
+// UpdateActionlog updates one or more (existing) Actionlogs in store
+//
+// This function is auto-generated
+func UpdateActionlog(ctx context.Context, s Actionlogs, rr ...*actionlogType.Action) error {
+ return s.UpdateActionlog(ctx, rr...)
+}
+
+// UpsertActionlog creates new or updates existing one or more Actionlogs in store
+//
+// This function is auto-generated
+func UpsertActionlog(ctx context.Context, s Actionlogs, rr ...*actionlogType.Action) error {
+ return s.UpsertActionlog(ctx, rr...)
+}
+
+// DeleteActionlog deletes one or more Actionlogs from store
+//
+// This function is auto-generated
+func DeleteActionlog(ctx context.Context, s Actionlogs, rr ...*actionlogType.Action) error {
+ return s.DeleteActionlog(ctx, rr...)
+}
+
+// DeleteActionlogByID deletes one or more Actionlogs from store
+//
+// This function is auto-generated
+func DeleteActionlogByID(ctx context.Context, s Actionlogs, id uint64) error {
+ return s.DeleteActionlogByID(ctx, id)
+}
+
+// TruncateActionlogs Deletes all Actionlogs from store
+//
+// This function is auto-generated
+func TruncateActionlogs(ctx context.Context, s Actionlogs) error {
+ return s.TruncateActionlogs(ctx)
+}
+
+// LookupActionlogByID searches for action log by ID
+//
+// This function is auto-generated
+func LookupActionlogByID(ctx context.Context, s Actionlogs, id uint64) (*actionlogType.Action, error) {
+ return s.LookupActionlogByID(ctx, id)
+}
+
+// SearchApigwFilters returns all matching ApigwFilters from store
+//
+// This function is auto-generated
+func SearchApigwFilters(ctx context.Context, s ApigwFilters, f systemType.ApigwFilterFilter) (systemType.ApigwFilterSet, systemType.ApigwFilterFilter, error) {
+ return s.SearchApigwFilters(ctx, f)
+}
+
+// CreateApigwFilter creates one or more ApigwFilters in store
+//
+// This function is auto-generated
+func CreateApigwFilter(ctx context.Context, s ApigwFilters, rr ...*systemType.ApigwFilter) error {
+ return s.CreateApigwFilter(ctx, rr...)
+}
+
+// UpdateApigwFilter updates one or more (existing) ApigwFilters in store
+//
+// This function is auto-generated
+func UpdateApigwFilter(ctx context.Context, s ApigwFilters, rr ...*systemType.ApigwFilter) error {
+ return s.UpdateApigwFilter(ctx, rr...)
+}
+
+// UpsertApigwFilter creates new or updates existing one or more ApigwFilters in store
+//
+// This function is auto-generated
+func UpsertApigwFilter(ctx context.Context, s ApigwFilters, rr ...*systemType.ApigwFilter) error {
+ return s.UpsertApigwFilter(ctx, rr...)
+}
+
+// DeleteApigwFilter deletes one or more ApigwFilters from store
+//
+// This function is auto-generated
+func DeleteApigwFilter(ctx context.Context, s ApigwFilters, rr ...*systemType.ApigwFilter) error {
+ return s.DeleteApigwFilter(ctx, rr...)
+}
+
+// DeleteApigwFilterByID deletes one or more ApigwFilters from store
+//
+// This function is auto-generated
+func DeleteApigwFilterByID(ctx context.Context, s ApigwFilters, id uint64) error {
+ return s.DeleteApigwFilterByID(ctx, id)
+}
+
+// TruncateApigwFilters Deletes all ApigwFilters from store
+//
+// This function is auto-generated
+func TruncateApigwFilters(ctx context.Context, s ApigwFilters) error {
+ return s.TruncateApigwFilters(ctx)
+}
+
+// LookupApigwFilterByID searches for filter by ID
+//
+// This function is auto-generated
+func LookupApigwFilterByID(ctx context.Context, s ApigwFilters, id uint64) (*systemType.ApigwFilter, error) {
+ return s.LookupApigwFilterByID(ctx, id)
+}
+
+// LookupApigwFilterByRoute searches for filter by route
+//
+// This function is auto-generated
+func LookupApigwFilterByRoute(ctx context.Context, s ApigwFilters, route uint64) (*systemType.ApigwFilter, error) {
+ return s.LookupApigwFilterByRoute(ctx, route)
+}
+
+// SearchApigwRoutes returns all matching ApigwRoutes from store
+//
+// This function is auto-generated
+func SearchApigwRoutes(ctx context.Context, s ApigwRoutes, f systemType.ApigwRouteFilter) (systemType.ApigwRouteSet, systemType.ApigwRouteFilter, error) {
+ return s.SearchApigwRoutes(ctx, f)
+}
+
+// CreateApigwRoute creates one or more ApigwRoutes in store
+//
+// This function is auto-generated
+func CreateApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*systemType.ApigwRoute) error {
+ return s.CreateApigwRoute(ctx, rr...)
+}
+
+// UpdateApigwRoute updates one or more (existing) ApigwRoutes in store
+//
+// This function is auto-generated
+func UpdateApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*systemType.ApigwRoute) error {
+ return s.UpdateApigwRoute(ctx, rr...)
+}
+
+// UpsertApigwRoute creates new or updates existing one or more ApigwRoutes in store
+//
+// This function is auto-generated
+func UpsertApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*systemType.ApigwRoute) error {
+ return s.UpsertApigwRoute(ctx, rr...)
+}
+
+// DeleteApigwRoute deletes one or more ApigwRoutes from store
+//
+// This function is auto-generated
+func DeleteApigwRoute(ctx context.Context, s ApigwRoutes, rr ...*systemType.ApigwRoute) error {
+ return s.DeleteApigwRoute(ctx, rr...)
+}
+
+// DeleteApigwRouteByID deletes one or more ApigwRoutes from store
+//
+// This function is auto-generated
+func DeleteApigwRouteByID(ctx context.Context, s ApigwRoutes, id uint64) error {
+ return s.DeleteApigwRouteByID(ctx, id)
+}
+
+// TruncateApigwRoutes Deletes all ApigwRoutes from store
+//
+// This function is auto-generated
+func TruncateApigwRoutes(ctx context.Context, s ApigwRoutes) error {
+ return s.TruncateApigwRoutes(ctx)
+}
+
+// LookupApigwRouteByID searches for route by ID
+//
+// It returns route even if deleted or suspended
+//
+// This function is auto-generated
+func LookupApigwRouteByID(ctx context.Context, s ApigwRoutes, id uint64) (*systemType.ApigwRoute, error) {
+ return s.LookupApigwRouteByID(ctx, id)
+}
+
+// LookupApigwRouteByEndpoint searches for route by endpoint
+//
+// It returns route even if deleted or suspended
+//
+// This function is auto-generated
+func LookupApigwRouteByEndpoint(ctx context.Context, s ApigwRoutes, endpoint string) (*systemType.ApigwRoute, error) {
+ return s.LookupApigwRouteByEndpoint(ctx, endpoint)
+}
+
+// SearchApplications returns all matching Applications from store
+//
+// This function is auto-generated
+func SearchApplications(ctx context.Context, s Applications, f systemType.ApplicationFilter) (systemType.ApplicationSet, systemType.ApplicationFilter, error) {
+ return s.SearchApplications(ctx, f)
+}
+
+// CreateApplication creates one or more Applications in store
+//
+// This function is auto-generated
+func CreateApplication(ctx context.Context, s Applications, rr ...*systemType.Application) error {
+ return s.CreateApplication(ctx, rr...)
+}
+
+// UpdateApplication updates one or more (existing) Applications in store
+//
+// This function is auto-generated
+func UpdateApplication(ctx context.Context, s Applications, rr ...*systemType.Application) error {
+ return s.UpdateApplication(ctx, rr...)
+}
+
+// UpsertApplication creates new or updates existing one or more Applications in store
+//
+// This function is auto-generated
+func UpsertApplication(ctx context.Context, s Applications, rr ...*systemType.Application) error {
+ return s.UpsertApplication(ctx, rr...)
+}
+
+// DeleteApplication deletes one or more Applications from store
+//
+// This function is auto-generated
+func DeleteApplication(ctx context.Context, s Applications, rr ...*systemType.Application) error {
+ return s.DeleteApplication(ctx, rr...)
+}
+
+// DeleteApplicationByID deletes one or more Applications from store
+//
+// This function is auto-generated
+func DeleteApplicationByID(ctx context.Context, s Applications, id uint64) error {
+ return s.DeleteApplicationByID(ctx, id)
+}
+
+// TruncateApplications Deletes all Applications from store
+//
+// This function is auto-generated
+func TruncateApplications(ctx context.Context, s Applications) error {
+ return s.TruncateApplications(ctx)
+}
+
+// LookupApplicationByID searches for role by ID
+//
+// It returns role even if deleted or suspended
+//
+// This function is auto-generated
+func LookupApplicationByID(ctx context.Context, s Applications, id uint64) (*systemType.Application, error) {
+ return s.LookupApplicationByID(ctx, id)
+}
+
+// ApplicationMetrics
+//
+// This function is auto-generated
+func ApplicationMetrics(ctx context.Context, s Applications) (*systemType.ApplicationMetrics, error) {
+ return s.ApplicationMetrics(ctx)
+}
+
+// ReorderApplications
+//
+// This function is auto-generated
+func ReorderApplications(ctx context.Context, s Applications, order []uint64) error {
+ return s.ReorderApplications(ctx, order)
+}
+
+// SearchAttachments returns all matching Attachments from store
+//
+// This function is auto-generated
+func SearchAttachments(ctx context.Context, s Attachments, f systemType.AttachmentFilter) (systemType.AttachmentSet, systemType.AttachmentFilter, error) {
+ return s.SearchAttachments(ctx, f)
+}
+
+// CreateAttachment creates one or more Attachments in store
+//
+// This function is auto-generated
+func CreateAttachment(ctx context.Context, s Attachments, rr ...*systemType.Attachment) error {
+ return s.CreateAttachment(ctx, rr...)
+}
+
+// UpdateAttachment updates one or more (existing) Attachments in store
+//
+// This function is auto-generated
+func UpdateAttachment(ctx context.Context, s Attachments, rr ...*systemType.Attachment) error {
+ return s.UpdateAttachment(ctx, rr...)
+}
+
+// UpsertAttachment creates new or updates existing one or more Attachments in store
+//
+// This function is auto-generated
+func UpsertAttachment(ctx context.Context, s Attachments, rr ...*systemType.Attachment) error {
+ return s.UpsertAttachment(ctx, rr...)
+}
+
+// DeleteAttachment deletes one or more Attachments from store
+//
+// This function is auto-generated
+func DeleteAttachment(ctx context.Context, s Attachments, rr ...*systemType.Attachment) error {
+ return s.DeleteAttachment(ctx, rr...)
+}
+
+// DeleteAttachmentByID deletes one or more Attachments from store
+//
+// This function is auto-generated
+func DeleteAttachmentByID(ctx context.Context, s Attachments, id uint64) error {
+ return s.DeleteAttachmentByID(ctx, id)
+}
+
+// TruncateAttachments Deletes all Attachments from store
+//
+// This function is auto-generated
+func TruncateAttachments(ctx context.Context, s Attachments) error {
+ return s.TruncateAttachments(ctx)
+}
+
+// LookupAttachmentByID
+//
+// This function is auto-generated
+func LookupAttachmentByID(ctx context.Context, s Attachments, id uint64) (*systemType.Attachment, error) {
+ return s.LookupAttachmentByID(ctx, id)
+}
+
+// SearchAuthClients returns all matching AuthClients from store
+//
+// This function is auto-generated
+func SearchAuthClients(ctx context.Context, s AuthClients, f systemType.AuthClientFilter) (systemType.AuthClientSet, systemType.AuthClientFilter, error) {
+ return s.SearchAuthClients(ctx, f)
+}
+
+// CreateAuthClient creates one or more AuthClients in store
+//
+// This function is auto-generated
+func CreateAuthClient(ctx context.Context, s AuthClients, rr ...*systemType.AuthClient) error {
+ return s.CreateAuthClient(ctx, rr...)
+}
+
+// UpdateAuthClient updates one or more (existing) AuthClients in store
+//
+// This function is auto-generated
+func UpdateAuthClient(ctx context.Context, s AuthClients, rr ...*systemType.AuthClient) error {
+ return s.UpdateAuthClient(ctx, rr...)
+}
+
+// UpsertAuthClient creates new or updates existing one or more AuthClients in store
+//
+// This function is auto-generated
+func UpsertAuthClient(ctx context.Context, s AuthClients, rr ...*systemType.AuthClient) error {
+ return s.UpsertAuthClient(ctx, rr...)
+}
+
+// DeleteAuthClient deletes one or more AuthClients from store
+//
+// This function is auto-generated
+func DeleteAuthClient(ctx context.Context, s AuthClients, rr ...*systemType.AuthClient) error {
+ return s.DeleteAuthClient(ctx, rr...)
+}
+
+// DeleteAuthClientByID deletes one or more AuthClients from store
+//
+// This function is auto-generated
+func DeleteAuthClientByID(ctx context.Context, s AuthClients, id uint64) error {
+ return s.DeleteAuthClientByID(ctx, id)
+}
+
+// TruncateAuthClients Deletes all AuthClients from store
+//
+// This function is auto-generated
+func TruncateAuthClients(ctx context.Context, s AuthClients) error {
+ return s.TruncateAuthClients(ctx)
+}
+
+// LookupAuthClientByID searches for auth client by ID
+//
+// It returns auth clint even if deleted
+//
+// This function is auto-generated
+func LookupAuthClientByID(ctx context.Context, s AuthClients, id uint64) (*systemType.AuthClient, error) {
+ return s.LookupAuthClientByID(ctx, id)
+}
+
+// LookupAuthClientByHandle searches for auth client by ID
+//
+// It returns auth clint even if deleted
+//
+// This function is auto-generated
+func LookupAuthClientByHandle(ctx context.Context, s AuthClients, handle string) (*systemType.AuthClient, error) {
+ return s.LookupAuthClientByHandle(ctx, handle)
+}
+
+// SearchAuthConfirmedClients returns all matching AuthConfirmedClients from store
+//
+// This function is auto-generated
+func SearchAuthConfirmedClients(ctx context.Context, s AuthConfirmedClients, f systemType.AuthConfirmedClientFilter) (systemType.AuthConfirmedClientSet, systemType.AuthConfirmedClientFilter, error) {
+ return s.SearchAuthConfirmedClients(ctx, f)
+}
+
+// CreateAuthConfirmedClient creates one or more AuthConfirmedClients in store
+//
+// This function is auto-generated
+func CreateAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*systemType.AuthConfirmedClient) error {
+ return s.CreateAuthConfirmedClient(ctx, rr...)
+}
+
+// UpdateAuthConfirmedClient updates one or more (existing) AuthConfirmedClients in store
+//
+// This function is auto-generated
+func UpdateAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*systemType.AuthConfirmedClient) error {
+ return s.UpdateAuthConfirmedClient(ctx, rr...)
+}
+
+// UpsertAuthConfirmedClient creates new or updates existing one or more AuthConfirmedClients in store
+//
+// This function is auto-generated
+func UpsertAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*systemType.AuthConfirmedClient) error {
+ return s.UpsertAuthConfirmedClient(ctx, rr...)
+}
+
+// DeleteAuthConfirmedClient deletes one or more AuthConfirmedClients from store
+//
+// This function is auto-generated
+func DeleteAuthConfirmedClient(ctx context.Context, s AuthConfirmedClients, rr ...*systemType.AuthConfirmedClient) error {
+ return s.DeleteAuthConfirmedClient(ctx, rr...)
+}
+
+// DeleteAuthConfirmedClientByID deletes one or more AuthConfirmedClients from store
+//
+// This function is auto-generated
+func DeleteAuthConfirmedClientByUserIDClientID(ctx context.Context, s AuthConfirmedClients, userID uint64, clientID uint64) error {
+ return s.DeleteAuthConfirmedClientByUserIDClientID(ctx, userID, clientID)
+}
+
+// TruncateAuthConfirmedClients Deletes all AuthConfirmedClients from store
+//
+// This function is auto-generated
+func TruncateAuthConfirmedClients(ctx context.Context, s AuthConfirmedClients) error {
+ return s.TruncateAuthConfirmedClients(ctx)
+}
+
+// LookupAuthConfirmedClientByUserIDClientID
+//
+// This function is auto-generated
+func LookupAuthConfirmedClientByUserIDClientID(ctx context.Context, s AuthConfirmedClients, userID uint64, clientID uint64) (*systemType.AuthConfirmedClient, error) {
+ return s.LookupAuthConfirmedClientByUserIDClientID(ctx, userID, clientID)
+}
+
+// SearchAuthOa2tokens returns all matching AuthOa2tokens from store
+//
+// This function is auto-generated
+func SearchAuthOa2tokens(ctx context.Context, s AuthOa2tokens, f systemType.AuthOa2tokenFilter) (systemType.AuthOa2tokenSet, systemType.AuthOa2tokenFilter, error) {
+ return s.SearchAuthOa2tokens(ctx, f)
+}
+
+// CreateAuthOa2token creates one or more AuthOa2tokens in store
+//
+// This function is auto-generated
+func CreateAuthOa2token(ctx context.Context, s AuthOa2tokens, rr ...*systemType.AuthOa2token) error {
+ return s.CreateAuthOa2token(ctx, rr...)
+}
+
+// UpdateAuthOa2token updates one or more (existing) AuthOa2tokens in store
+//
+// This function is auto-generated
+func UpdateAuthOa2token(ctx context.Context, s AuthOa2tokens, rr ...*systemType.AuthOa2token) error {
+ return s.UpdateAuthOa2token(ctx, rr...)
+}
+
+// UpsertAuthOa2token creates new or updates existing one or more AuthOa2tokens in store
+//
+// This function is auto-generated
+func UpsertAuthOa2token(ctx context.Context, s AuthOa2tokens, rr ...*systemType.AuthOa2token) error {
+ return s.UpsertAuthOa2token(ctx, rr...)
+}
+
+// DeleteAuthOa2token deletes one or more AuthOa2tokens from store
+//
+// This function is auto-generated
+func DeleteAuthOa2token(ctx context.Context, s AuthOa2tokens, rr ...*systemType.AuthOa2token) error {
+ return s.DeleteAuthOa2token(ctx, rr...)
+}
+
+// DeleteAuthOa2tokenByID deletes one or more AuthOa2tokens from store
+//
+// This function is auto-generated
+func DeleteAuthOa2tokenByID(ctx context.Context, s AuthOa2tokens, id uint64) error {
+ return s.DeleteAuthOa2tokenByID(ctx, id)
+}
+
+// TruncateAuthOa2tokens Deletes all AuthOa2tokens from store
+//
+// This function is auto-generated
+func TruncateAuthOa2tokens(ctx context.Context, s AuthOa2tokens) error {
+ return s.TruncateAuthOa2tokens(ctx)
+}
+
+// LookupAuthOa2tokenByID
+//
+// This function is auto-generated
+func LookupAuthOa2tokenByID(ctx context.Context, s AuthOa2tokens, id uint64) (*systemType.AuthOa2token, error) {
+ return s.LookupAuthOa2tokenByID(ctx, id)
+}
+
+// LookupAuthOa2tokenByCode
+//
+// This function is auto-generated
+func LookupAuthOa2tokenByCode(ctx context.Context, s AuthOa2tokens, code string) (*systemType.AuthOa2token, error) {
+ return s.LookupAuthOa2tokenByCode(ctx, code)
+}
+
+// LookupAuthOa2tokenByAccess
+//
+// This function is auto-generated
+func LookupAuthOa2tokenByAccess(ctx context.Context, s AuthOa2tokens, access string) (*systemType.AuthOa2token, error) {
+ return s.LookupAuthOa2tokenByAccess(ctx, access)
+}
+
+// LookupAuthOa2tokenByRefresh
+//
+// This function is auto-generated
+func LookupAuthOa2tokenByRefresh(ctx context.Context, s AuthOa2tokens, refresh string) (*systemType.AuthOa2token, error) {
+ return s.LookupAuthOa2tokenByRefresh(ctx, refresh)
+}
+
+// DeleteExpiredAuthOA2Tokens
+//
+// This function is auto-generated
+func DeleteExpiredAuthOA2Tokens(ctx context.Context, s AuthOa2tokens) error {
+ return s.DeleteExpiredAuthOA2Tokens(ctx)
+}
+
+// DeleteAuthOA2TokenByCode
+//
+// This function is auto-generated
+func DeleteAuthOA2TokenByCode(ctx context.Context, s AuthOa2tokens, code string) error {
+ return s.DeleteAuthOA2TokenByCode(ctx, code)
+}
+
+// DeleteAuthOA2TokenByAccess
+//
+// This function is auto-generated
+func DeleteAuthOA2TokenByAccess(ctx context.Context, s AuthOa2tokens, access string) error {
+ return s.DeleteAuthOA2TokenByAccess(ctx, access)
+}
+
+// DeleteAuthOA2TokenByRefresh
+//
+// This function is auto-generated
+func DeleteAuthOA2TokenByRefresh(ctx context.Context, s AuthOa2tokens, refresh string) error {
+ return s.DeleteAuthOA2TokenByRefresh(ctx, refresh)
+}
+
+// DeleteAuthOA2TokenByUserID
+//
+// This function is auto-generated
+func DeleteAuthOA2TokenByUserID(ctx context.Context, s AuthOa2tokens, userID uint64) error {
+ return s.DeleteAuthOA2TokenByUserID(ctx, userID)
+}
+
+// SearchAuthSessions returns all matching AuthSessions from store
+//
+// This function is auto-generated
+func SearchAuthSessions(ctx context.Context, s AuthSessions, f systemType.AuthSessionFilter) (systemType.AuthSessionSet, systemType.AuthSessionFilter, error) {
+ return s.SearchAuthSessions(ctx, f)
+}
+
+// CreateAuthSession creates one or more AuthSessions in store
+//
+// This function is auto-generated
+func CreateAuthSession(ctx context.Context, s AuthSessions, rr ...*systemType.AuthSession) error {
+ return s.CreateAuthSession(ctx, rr...)
+}
+
+// UpdateAuthSession updates one or more (existing) AuthSessions in store
+//
+// This function is auto-generated
+func UpdateAuthSession(ctx context.Context, s AuthSessions, rr ...*systemType.AuthSession) error {
+ return s.UpdateAuthSession(ctx, rr...)
+}
+
+// UpsertAuthSession creates new or updates existing one or more AuthSessions in store
+//
+// This function is auto-generated
+func UpsertAuthSession(ctx context.Context, s AuthSessions, rr ...*systemType.AuthSession) error {
+ return s.UpsertAuthSession(ctx, rr...)
+}
+
+// DeleteAuthSession deletes one or more AuthSessions from store
+//
+// This function is auto-generated
+func DeleteAuthSession(ctx context.Context, s AuthSessions, rr ...*systemType.AuthSession) error {
+ return s.DeleteAuthSession(ctx, rr...)
+}
+
+// DeleteAuthSessionByID deletes one or more AuthSessions from store
+//
+// This function is auto-generated
+func DeleteAuthSessionByID(ctx context.Context, s AuthSessions, id string) error {
+ return s.DeleteAuthSessionByID(ctx, id)
+}
+
+// TruncateAuthSessions Deletes all AuthSessions from store
+//
+// This function is auto-generated
+func TruncateAuthSessions(ctx context.Context, s AuthSessions) error {
+ return s.TruncateAuthSessions(ctx)
+}
+
+// LookupAuthSessionByID
+//
+// This function is auto-generated
+func LookupAuthSessionByID(ctx context.Context, s AuthSessions, id string) (*systemType.AuthSession, error) {
+ return s.LookupAuthSessionByID(ctx, id)
+}
+
+// DeleteExpiredAuthSessions
+//
+// This function is auto-generated
+func DeleteExpiredAuthSessions(ctx context.Context, s AuthSessions) error {
+ return s.DeleteExpiredAuthSessions(ctx)
+}
+
+// DeleteAuthSessionsByUserID
+//
+// This function is auto-generated
+func DeleteAuthSessionsByUserID(ctx context.Context, s AuthSessions, userID uint64) error {
+ return s.DeleteAuthSessionsByUserID(ctx, userID)
+}
+
+// SearchAutomationSessions returns all matching AutomationSessions from store
+//
+// This function is auto-generated
+func SearchAutomationSessions(ctx context.Context, s AutomationSessions, f automationType.SessionFilter) (automationType.SessionSet, automationType.SessionFilter, error) {
+ return s.SearchAutomationSessions(ctx, f)
+}
+
+// CreateAutomationSession creates one or more AutomationSessions in store
+//
+// This function is auto-generated
+func CreateAutomationSession(ctx context.Context, s AutomationSessions, rr ...*automationType.Session) error {
+ return s.CreateAutomationSession(ctx, rr...)
+}
+
+// UpdateAutomationSession updates one or more (existing) AutomationSessions in store
+//
+// This function is auto-generated
+func UpdateAutomationSession(ctx context.Context, s AutomationSessions, rr ...*automationType.Session) error {
+ return s.UpdateAutomationSession(ctx, rr...)
+}
+
+// UpsertAutomationSession creates new or updates existing one or more AutomationSessions in store
+//
+// This function is auto-generated
+func UpsertAutomationSession(ctx context.Context, s AutomationSessions, rr ...*automationType.Session) error {
+ return s.UpsertAutomationSession(ctx, rr...)
+}
+
+// DeleteAutomationSession deletes one or more AutomationSessions from store
+//
+// This function is auto-generated
+func DeleteAutomationSession(ctx context.Context, s AutomationSessions, rr ...*automationType.Session) error {
+ return s.DeleteAutomationSession(ctx, rr...)
+}
+
+// DeleteAutomationSessionByID deletes one or more AutomationSessions from store
+//
+// This function is auto-generated
+func DeleteAutomationSessionByID(ctx context.Context, s AutomationSessions, id uint64) error {
+ return s.DeleteAutomationSessionByID(ctx, id)
+}
+
+// TruncateAutomationSessions Deletes all AutomationSessions from store
+//
+// This function is auto-generated
+func TruncateAutomationSessions(ctx context.Context, s AutomationSessions) error {
+ return s.TruncateAutomationSessions(ctx)
+}
+
+// LookupAutomationSessionByID searches for session by ID
+//
+// It returns session even if deleted
+//
+// This function is auto-generated
+func LookupAutomationSessionByID(ctx context.Context, s AutomationSessions, id uint64) (*automationType.Session, error) {
+ return s.LookupAutomationSessionByID(ctx, id)
+}
+
+// SearchAutomationTriggers returns all matching AutomationTriggers from store
+//
+// This function is auto-generated
+func SearchAutomationTriggers(ctx context.Context, s AutomationTriggers, f automationType.TriggerFilter) (automationType.TriggerSet, automationType.TriggerFilter, error) {
+ return s.SearchAutomationTriggers(ctx, f)
+}
+
+// CreateAutomationTrigger creates one or more AutomationTriggers in store
+//
+// This function is auto-generated
+func CreateAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*automationType.Trigger) error {
+ return s.CreateAutomationTrigger(ctx, rr...)
+}
+
+// UpdateAutomationTrigger updates one or more (existing) AutomationTriggers in store
+//
+// This function is auto-generated
+func UpdateAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*automationType.Trigger) error {
+ return s.UpdateAutomationTrigger(ctx, rr...)
+}
+
+// UpsertAutomationTrigger creates new or updates existing one or more AutomationTriggers in store
+//
+// This function is auto-generated
+func UpsertAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*automationType.Trigger) error {
+ return s.UpsertAutomationTrigger(ctx, rr...)
+}
+
+// DeleteAutomationTrigger deletes one or more AutomationTriggers from store
+//
+// This function is auto-generated
+func DeleteAutomationTrigger(ctx context.Context, s AutomationTriggers, rr ...*automationType.Trigger) error {
+ return s.DeleteAutomationTrigger(ctx, rr...)
+}
+
+// DeleteAutomationTriggerByID deletes one or more AutomationTriggers from store
+//
+// This function is auto-generated
+func DeleteAutomationTriggerByID(ctx context.Context, s AutomationTriggers, id uint64) error {
+ return s.DeleteAutomationTriggerByID(ctx, id)
+}
+
+// TruncateAutomationTriggers Deletes all AutomationTriggers from store
+//
+// This function is auto-generated
+func TruncateAutomationTriggers(ctx context.Context, s AutomationTriggers) error {
+ return s.TruncateAutomationTriggers(ctx)
+}
+
+// LookupAutomationTriggerByID searches for trigger by ID
+//
+// It returns trigger even if deleted
+//
+// This function is auto-generated
+func LookupAutomationTriggerByID(ctx context.Context, s AutomationTriggers, id uint64) (*automationType.Trigger, error) {
+ return s.LookupAutomationTriggerByID(ctx, id)
+}
+
+// SearchAutomationWorkflows returns all matching AutomationWorkflows from store
+//
+// This function is auto-generated
+func SearchAutomationWorkflows(ctx context.Context, s AutomationWorkflows, f automationType.WorkflowFilter) (automationType.WorkflowSet, automationType.WorkflowFilter, error) {
+ return s.SearchAutomationWorkflows(ctx, f)
+}
+
+// CreateAutomationWorkflow creates one or more AutomationWorkflows in store
+//
+// This function is auto-generated
+func CreateAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*automationType.Workflow) error {
+ return s.CreateAutomationWorkflow(ctx, rr...)
+}
+
+// UpdateAutomationWorkflow updates one or more (existing) AutomationWorkflows in store
+//
+// This function is auto-generated
+func UpdateAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*automationType.Workflow) error {
+ return s.UpdateAutomationWorkflow(ctx, rr...)
+}
+
+// UpsertAutomationWorkflow creates new or updates existing one or more AutomationWorkflows in store
+//
+// This function is auto-generated
+func UpsertAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*automationType.Workflow) error {
+ return s.UpsertAutomationWorkflow(ctx, rr...)
+}
+
+// DeleteAutomationWorkflow deletes one or more AutomationWorkflows from store
+//
+// This function is auto-generated
+func DeleteAutomationWorkflow(ctx context.Context, s AutomationWorkflows, rr ...*automationType.Workflow) error {
+ return s.DeleteAutomationWorkflow(ctx, rr...)
+}
+
+// DeleteAutomationWorkflowByID deletes one or more AutomationWorkflows from store
+//
+// This function is auto-generated
+func DeleteAutomationWorkflowByID(ctx context.Context, s AutomationWorkflows, id uint64) error {
+ return s.DeleteAutomationWorkflowByID(ctx, id)
+}
+
+// TruncateAutomationWorkflows Deletes all AutomationWorkflows from store
+//
+// This function is auto-generated
+func TruncateAutomationWorkflows(ctx context.Context, s AutomationWorkflows) error {
+ return s.TruncateAutomationWorkflows(ctx)
+}
+
+// LookupAutomationWorkflowByID searches for workflow by ID
+//
+// It returns workflow even if deleted
+//
+// This function is auto-generated
+func LookupAutomationWorkflowByID(ctx context.Context, s AutomationWorkflows, id uint64) (*automationType.Workflow, error) {
+ return s.LookupAutomationWorkflowByID(ctx, id)
+}
+
+// LookupAutomationWorkflowByHandle searches for workflow by their handle
+//
+// It returns only valid workflows
+//
+// This function is auto-generated
+func LookupAutomationWorkflowByHandle(ctx context.Context, s AutomationWorkflows, handle string) (*automationType.Workflow, error) {
+ return s.LookupAutomationWorkflowByHandle(ctx, handle)
+}
+
+// SearchComposeAttachments returns all matching ComposeAttachments from store
+//
+// This function is auto-generated
+func SearchComposeAttachments(ctx context.Context, s ComposeAttachments, f composeType.AttachmentFilter) (composeType.AttachmentSet, composeType.AttachmentFilter, error) {
+ return s.SearchComposeAttachments(ctx, f)
+}
+
+// CreateComposeAttachment creates one or more ComposeAttachments in store
+//
+// This function is auto-generated
+func CreateComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*composeType.Attachment) error {
+ return s.CreateComposeAttachment(ctx, rr...)
+}
+
+// UpdateComposeAttachment updates one or more (existing) ComposeAttachments in store
+//
+// This function is auto-generated
+func UpdateComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*composeType.Attachment) error {
+ return s.UpdateComposeAttachment(ctx, rr...)
+}
+
+// UpsertComposeAttachment creates new or updates existing one or more ComposeAttachments in store
+//
+// This function is auto-generated
+func UpsertComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*composeType.Attachment) error {
+ return s.UpsertComposeAttachment(ctx, rr...)
+}
+
+// DeleteComposeAttachment deletes one or more ComposeAttachments from store
+//
+// This function is auto-generated
+func DeleteComposeAttachment(ctx context.Context, s ComposeAttachments, rr ...*composeType.Attachment) error {
+ return s.DeleteComposeAttachment(ctx, rr...)
+}
+
+// DeleteComposeAttachmentByID deletes one or more ComposeAttachments from store
+//
+// This function is auto-generated
+func DeleteComposeAttachmentByID(ctx context.Context, s ComposeAttachments, id uint64) error {
+ return s.DeleteComposeAttachmentByID(ctx, id)
+}
+
+// TruncateComposeAttachments Deletes all ComposeAttachments from store
+//
+// This function is auto-generated
+func TruncateComposeAttachments(ctx context.Context, s ComposeAttachments) error {
+ return s.TruncateComposeAttachments(ctx)
+}
+
+// LookupComposeAttachmentByID
+//
+// This function is auto-generated
+func LookupComposeAttachmentByID(ctx context.Context, s ComposeAttachments, id uint64) (*composeType.Attachment, error) {
+ return s.LookupComposeAttachmentByID(ctx, id)
+}
+
+// SearchComposeCharts returns all matching ComposeCharts from store
+//
+// This function is auto-generated
+func SearchComposeCharts(ctx context.Context, s ComposeCharts, f composeType.ChartFilter) (composeType.ChartSet, composeType.ChartFilter, error) {
+ return s.SearchComposeCharts(ctx, f)
+}
+
+// CreateComposeChart creates one or more ComposeCharts in store
+//
+// This function is auto-generated
+func CreateComposeChart(ctx context.Context, s ComposeCharts, rr ...*composeType.Chart) error {
+ return s.CreateComposeChart(ctx, rr...)
+}
+
+// UpdateComposeChart updates one or more (existing) ComposeCharts in store
+//
+// This function is auto-generated
+func UpdateComposeChart(ctx context.Context, s ComposeCharts, rr ...*composeType.Chart) error {
+ return s.UpdateComposeChart(ctx, rr...)
+}
+
+// UpsertComposeChart creates new or updates existing one or more ComposeCharts in store
+//
+// This function is auto-generated
+func UpsertComposeChart(ctx context.Context, s ComposeCharts, rr ...*composeType.Chart) error {
+ return s.UpsertComposeChart(ctx, rr...)
+}
+
+// DeleteComposeChart deletes one or more ComposeCharts from store
+//
+// This function is auto-generated
+func DeleteComposeChart(ctx context.Context, s ComposeCharts, rr ...*composeType.Chart) error {
+ return s.DeleteComposeChart(ctx, rr...)
+}
+
+// DeleteComposeChartByID deletes one or more ComposeCharts from store
+//
+// This function is auto-generated
+func DeleteComposeChartByID(ctx context.Context, s ComposeCharts, id uint64) error {
+ return s.DeleteComposeChartByID(ctx, id)
+}
+
+// TruncateComposeCharts Deletes all ComposeCharts from store
+//
+// This function is auto-generated
+func TruncateComposeCharts(ctx context.Context, s ComposeCharts) error {
+ return s.TruncateComposeCharts(ctx)
+}
+
+// LookupComposeChartByID searches for compose chart by ID
+//
+// It returns compose chart even if deleted
+//
+// This function is auto-generated
+func LookupComposeChartByID(ctx context.Context, s ComposeCharts, id uint64) (*composeType.Chart, error) {
+ return s.LookupComposeChartByID(ctx, id)
+}
+
+// LookupComposeChartByNamespaceIDHandle searches for compose chart by handle (case-insensitive)
+//
+// This function is auto-generated
+func LookupComposeChartByNamespaceIDHandle(ctx context.Context, s ComposeCharts, namespaceID uint64, handle string) (*composeType.Chart, error) {
+ return s.LookupComposeChartByNamespaceIDHandle(ctx, namespaceID, handle)
+}
+
+// SearchComposeModules returns all matching ComposeModules from store
+//
+// This function is auto-generated
+func SearchComposeModules(ctx context.Context, s ComposeModules, f composeType.ModuleFilter) (composeType.ModuleSet, composeType.ModuleFilter, error) {
+ return s.SearchComposeModules(ctx, f)
+}
+
+// CreateComposeModule creates one or more ComposeModules in store
+//
+// This function is auto-generated
+func CreateComposeModule(ctx context.Context, s ComposeModules, rr ...*composeType.Module) error {
+ return s.CreateComposeModule(ctx, rr...)
+}
+
+// UpdateComposeModule updates one or more (existing) ComposeModules in store
+//
+// This function is auto-generated
+func UpdateComposeModule(ctx context.Context, s ComposeModules, rr ...*composeType.Module) error {
+ return s.UpdateComposeModule(ctx, rr...)
+}
+
+// UpsertComposeModule creates new or updates existing one or more ComposeModules in store
+//
+// This function is auto-generated
+func UpsertComposeModule(ctx context.Context, s ComposeModules, rr ...*composeType.Module) error {
+ return s.UpsertComposeModule(ctx, rr...)
+}
+
+// DeleteComposeModule deletes one or more ComposeModules from store
+//
+// This function is auto-generated
+func DeleteComposeModule(ctx context.Context, s ComposeModules, rr ...*composeType.Module) error {
+ return s.DeleteComposeModule(ctx, rr...)
+}
+
+// DeleteComposeModuleByID deletes one or more ComposeModules from store
+//
+// This function is auto-generated
+func DeleteComposeModuleByID(ctx context.Context, s ComposeModules, id uint64) error {
+ return s.DeleteComposeModuleByID(ctx, id)
+}
+
+// TruncateComposeModules Deletes all ComposeModules from store
+//
+// This function is auto-generated
+func TruncateComposeModules(ctx context.Context, s ComposeModules) error {
+ return s.TruncateComposeModules(ctx)
+}
+
+// LookupComposeModuleByNamespaceIDHandle searches for compose module by handle (case-insensitive)
+//
+// This function is auto-generated
+func LookupComposeModuleByNamespaceIDHandle(ctx context.Context, s ComposeModules, namespaceID uint64, handle string) (*composeType.Module, error) {
+ return s.LookupComposeModuleByNamespaceIDHandle(ctx, namespaceID, handle)
+}
+
+// LookupComposeModuleByNamespaceIDName searches for compose module by name (case-insensitive)
+//
+// This function is auto-generated
+func LookupComposeModuleByNamespaceIDName(ctx context.Context, s ComposeModules, namespaceID uint64, name string) (*composeType.Module, error) {
+ return s.LookupComposeModuleByNamespaceIDName(ctx, namespaceID, name)
+}
+
+// LookupComposeModuleByID searches for compose module by ID
+//
+// It returns compose module even if deleted
+//
+// This function is auto-generated
+func LookupComposeModuleByID(ctx context.Context, s ComposeModules, id uint64) (*composeType.Module, error) {
+ return s.LookupComposeModuleByID(ctx, id)
+}
+
+// SearchComposeModuleFields returns all matching ComposeModuleFields from store
+//
+// This function is auto-generated
+func SearchComposeModuleFields(ctx context.Context, s ComposeModuleFields, f composeType.ModuleFieldFilter) (composeType.ModuleFieldSet, composeType.ModuleFieldFilter, error) {
+ return s.SearchComposeModuleFields(ctx, f)
+}
+
+// CreateComposeModuleField creates one or more ComposeModuleFields in store
+//
+// This function is auto-generated
+func CreateComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*composeType.ModuleField) error {
+ return s.CreateComposeModuleField(ctx, rr...)
+}
+
+// UpdateComposeModuleField updates one or more (existing) ComposeModuleFields in store
+//
+// This function is auto-generated
+func UpdateComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*composeType.ModuleField) error {
+ return s.UpdateComposeModuleField(ctx, rr...)
+}
+
+// UpsertComposeModuleField creates new or updates existing one or more ComposeModuleFields in store
+//
+// This function is auto-generated
+func UpsertComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*composeType.ModuleField) error {
+ return s.UpsertComposeModuleField(ctx, rr...)
+}
+
+// DeleteComposeModuleField deletes one or more ComposeModuleFields from store
+//
+// This function is auto-generated
+func DeleteComposeModuleField(ctx context.Context, s ComposeModuleFields, rr ...*composeType.ModuleField) error {
+ return s.DeleteComposeModuleField(ctx, rr...)
+}
+
+// DeleteComposeModuleFieldByID deletes one or more ComposeModuleFields from store
+//
+// This function is auto-generated
+func DeleteComposeModuleFieldByID(ctx context.Context, s ComposeModuleFields, id uint64) error {
+ return s.DeleteComposeModuleFieldByID(ctx, id)
+}
+
+// TruncateComposeModuleFields Deletes all ComposeModuleFields from store
+//
+// This function is auto-generated
+func TruncateComposeModuleFields(ctx context.Context, s ComposeModuleFields) error {
+ return s.TruncateComposeModuleFields(ctx)
+}
+
+// LookupComposeModuleFieldByModuleIDName searches for compose module field by name (case-insensitive)
+//
+// This function is auto-generated
+func LookupComposeModuleFieldByModuleIDName(ctx context.Context, s ComposeModuleFields, moduleID uint64, name string) (*composeType.ModuleField, error) {
+ return s.LookupComposeModuleFieldByModuleIDName(ctx, moduleID, name)
+}
+
+// SearchComposeNamespaces returns all matching ComposeNamespaces from store
+//
+// This function is auto-generated
+func SearchComposeNamespaces(ctx context.Context, s ComposeNamespaces, f composeType.NamespaceFilter) (composeType.NamespaceSet, composeType.NamespaceFilter, error) {
+ return s.SearchComposeNamespaces(ctx, f)
+}
+
+// CreateComposeNamespace creates one or more ComposeNamespaces in store
+//
+// This function is auto-generated
+func CreateComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*composeType.Namespace) error {
+ return s.CreateComposeNamespace(ctx, rr...)
+}
+
+// UpdateComposeNamespace updates one or more (existing) ComposeNamespaces in store
+//
+// This function is auto-generated
+func UpdateComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*composeType.Namespace) error {
+ return s.UpdateComposeNamespace(ctx, rr...)
+}
+
+// UpsertComposeNamespace creates new or updates existing one or more ComposeNamespaces in store
+//
+// This function is auto-generated
+func UpsertComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*composeType.Namespace) error {
+ return s.UpsertComposeNamespace(ctx, rr...)
+}
+
+// DeleteComposeNamespace deletes one or more ComposeNamespaces from store
+//
+// This function is auto-generated
+func DeleteComposeNamespace(ctx context.Context, s ComposeNamespaces, rr ...*composeType.Namespace) error {
+ return s.DeleteComposeNamespace(ctx, rr...)
+}
+
+// DeleteComposeNamespaceByID deletes one or more ComposeNamespaces from store
+//
+// This function is auto-generated
+func DeleteComposeNamespaceByID(ctx context.Context, s ComposeNamespaces, id uint64) error {
+ return s.DeleteComposeNamespaceByID(ctx, id)
+}
+
+// TruncateComposeNamespaces Deletes all ComposeNamespaces from store
+//
+// This function is auto-generated
+func TruncateComposeNamespaces(ctx context.Context, s ComposeNamespaces) error {
+ return s.TruncateComposeNamespaces(ctx)
+}
+
+// LookupComposeNamespaceBySlug searches for namespace by slug (case-insensitive)
+//
+// This function is auto-generated
+func LookupComposeNamespaceBySlug(ctx context.Context, s ComposeNamespaces, slug string) (*composeType.Namespace, error) {
+ return s.LookupComposeNamespaceBySlug(ctx, slug)
+}
+
+// LookupComposeNamespaceByID searches for compose namespace by ID
+//
+// It returns compose namespace even if deleted
+//
+// This function is auto-generated
+func LookupComposeNamespaceByID(ctx context.Context, s ComposeNamespaces, id uint64) (*composeType.Namespace, error) {
+ return s.LookupComposeNamespaceByID(ctx, id)
+}
+
+// SearchComposePages returns all matching ComposePages from store
+//
+// This function is auto-generated
+func SearchComposePages(ctx context.Context, s ComposePages, f composeType.PageFilter) (composeType.PageSet, composeType.PageFilter, error) {
+ return s.SearchComposePages(ctx, f)
+}
+
+// CreateComposePage creates one or more ComposePages in store
+//
+// This function is auto-generated
+func CreateComposePage(ctx context.Context, s ComposePages, rr ...*composeType.Page) error {
+ return s.CreateComposePage(ctx, rr...)
+}
+
+// UpdateComposePage updates one or more (existing) ComposePages in store
+//
+// This function is auto-generated
+func UpdateComposePage(ctx context.Context, s ComposePages, rr ...*composeType.Page) error {
+ return s.UpdateComposePage(ctx, rr...)
+}
+
+// UpsertComposePage creates new or updates existing one or more ComposePages in store
+//
+// This function is auto-generated
+func UpsertComposePage(ctx context.Context, s ComposePages, rr ...*composeType.Page) error {
+ return s.UpsertComposePage(ctx, rr...)
+}
+
+// DeleteComposePage deletes one or more ComposePages from store
+//
+// This function is auto-generated
+func DeleteComposePage(ctx context.Context, s ComposePages, rr ...*composeType.Page) error {
+ return s.DeleteComposePage(ctx, rr...)
+}
+
+// DeleteComposePageByID deletes one or more ComposePages from store
+//
+// This function is auto-generated
+func DeleteComposePageByID(ctx context.Context, s ComposePages, id uint64) error {
+ return s.DeleteComposePageByID(ctx, id)
+}
+
+// TruncateComposePages Deletes all ComposePages from store
+//
+// This function is auto-generated
+func TruncateComposePages(ctx context.Context, s ComposePages) error {
+ return s.TruncateComposePages(ctx)
+}
+
+// LookupComposePageByNamespaceIDHandle searches for page by handle (case-insensitive)
+//
+// This function is auto-generated
+func LookupComposePageByNamespaceIDHandle(ctx context.Context, s ComposePages, namespaceID uint64, handle string) (*composeType.Page, error) {
+ return s.LookupComposePageByNamespaceIDHandle(ctx, namespaceID, handle)
+}
+
+// LookupComposePageByNamespaceIDModuleID searches for page by moduleID
+//
+// This function is auto-generated
+func LookupComposePageByNamespaceIDModuleID(ctx context.Context, s ComposePages, namespaceID uint64, moduleID uint64) (*composeType.Page, error) {
+ return s.LookupComposePageByNamespaceIDModuleID(ctx, namespaceID, moduleID)
+}
+
+// LookupComposePageByID searches for compose page by ID
+//
+// It returns compose page even if deleted
+//
+// This function is auto-generated
+func LookupComposePageByID(ctx context.Context, s ComposePages, id uint64) (*composeType.Page, error) {
+ return s.LookupComposePageByID(ctx, id)
+}
+
+// ReorderComposePages
+//
+// This function is auto-generated
+func ReorderComposePages(ctx context.Context, s ComposePages, namespace_id uint64, parent_id uint64, page_ids []uint64) error {
+ return s.ReorderComposePages(ctx, namespace_id, parent_id, page_ids)
+}
+
+// SearchComposeRecords returns all matching ComposeRecords from store
+//
+// This function is auto-generated
+func SearchComposeRecords(ctx context.Context, s ComposeRecords, mod *composeType.Module, f composeType.RecordFilter) (composeType.RecordSet, composeType.RecordFilter, error) {
+ return s.SearchComposeRecords(ctx, mod, f)
+}
+
+// CreateComposeRecord creates one or more ComposeRecords in store
+//
+// This function is auto-generated
+func CreateComposeRecord(ctx context.Context, s ComposeRecords, mod *composeType.Module, rr ...*composeType.Record) error {
+ return s.CreateComposeRecord(ctx, mod, rr...)
+}
+
+// UpdateComposeRecord updates one or more (existing) ComposeRecords in store
+//
+// This function is auto-generated
+func UpdateComposeRecord(ctx context.Context, s ComposeRecords, mod *composeType.Module, rr ...*composeType.Record) error {
+ return s.UpdateComposeRecord(ctx, mod, rr...)
+}
+
+// UpsertComposeRecord creates new or updates existing one or more ComposeRecords in store
+//
+// This function is auto-generated
+func UpsertComposeRecord(ctx context.Context, s ComposeRecords, mod *composeType.Module, rr ...*composeType.Record) error {
+ return s.UpsertComposeRecord(ctx, mod, rr...)
+}
+
+// DeleteComposeRecord deletes one or more ComposeRecords from store
+//
+// This function is auto-generated
+func DeleteComposeRecord(ctx context.Context, s ComposeRecords, mod *composeType.Module, rr ...*composeType.Record) error {
+ return s.DeleteComposeRecord(ctx, mod, rr...)
+}
+
+// DeleteComposeRecordByID deletes one or more ComposeRecords from store
+//
+// This function is auto-generated
+func DeleteComposeRecordByID(ctx context.Context, s ComposeRecords, mod *composeType.Module, id uint64) error {
+ return s.DeleteComposeRecordByID(ctx, mod, id)
+}
+
+// TruncateComposeRecords Deletes all ComposeRecords from store
+//
+// This function is auto-generated
+func TruncateComposeRecords(ctx context.Context, s ComposeRecords, mod *composeType.Module) error {
+ return s.TruncateComposeRecords(ctx, mod)
+}
+
+// LookupComposeRecordByID searches for compose record by ID
+//
+// It returns compose record even if deleted
+//
+// This function is auto-generated
+func LookupComposeRecordByID(ctx context.Context, s ComposeRecords, mod *composeType.Module, id uint64) (*composeType.Record, error) {
+ return s.LookupComposeRecordByID(ctx, mod, id)
+}
+
+// ComposeRecordReport
+//
+// This function is auto-generated
+func ComposeRecordReport(ctx context.Context, s ComposeRecords, mod *composeType.Module, metrics string, dimensions string, filters string) ([]map[string]interface{}, error) {
+ return s.ComposeRecordReport(ctx, mod, metrics, dimensions, filters)
+}
+
+// ComposeRecordDatasource
+//
+// This function is auto-generated
+func ComposeRecordDatasource(ctx context.Context, s ComposeRecords, mod *composeType.Module, ld *report.LoadStepDefinition) (report.Datasource, error) {
+ return s.ComposeRecordDatasource(ctx, mod, ld)
+}
+
+// PartialComposeRecordValueUpdate
+//
+// This function is auto-generated
+func PartialComposeRecordValueUpdate(ctx context.Context, s ComposeRecords, mod *composeType.Module, values ...*composeType.RecordValue) error {
+ return s.PartialComposeRecordValueUpdate(ctx, mod, values...)
+}
+
+// SearchComposeRecordValues returns all matching ComposeRecordValues from store
+//
+// This function is auto-generated
+func SearchComposeRecordValues(ctx context.Context, s ComposeRecordValues, f composeType.RecordValueFilter) (composeType.RecordValueSet, composeType.RecordValueFilter, error) {
+ return s.SearchComposeRecordValues(ctx, f)
+}
+
+// CreateComposeRecordValue creates one or more ComposeRecordValues in store
+//
+// This function is auto-generated
+func CreateComposeRecordValue(ctx context.Context, s ComposeRecordValues, rr ...*composeType.RecordValue) error {
+ return s.CreateComposeRecordValue(ctx, rr...)
+}
+
+// UpdateComposeRecordValue updates one or more (existing) ComposeRecordValues in store
+//
+// This function is auto-generated
+func UpdateComposeRecordValue(ctx context.Context, s ComposeRecordValues, rr ...*composeType.RecordValue) error {
+ return s.UpdateComposeRecordValue(ctx, rr...)
+}
+
+// UpsertComposeRecordValue creates new or updates existing one or more ComposeRecordValues in store
+//
+// This function is auto-generated
+func UpsertComposeRecordValue(ctx context.Context, s ComposeRecordValues, rr ...*composeType.RecordValue) error {
+ return s.UpsertComposeRecordValue(ctx, rr...)
+}
+
+// DeleteComposeRecordValue deletes one or more ComposeRecordValues from store
+//
+// This function is auto-generated
+func DeleteComposeRecordValue(ctx context.Context, s ComposeRecordValues, rr ...*composeType.RecordValue) error {
+ return s.DeleteComposeRecordValue(ctx, rr...)
+}
+
+// DeleteComposeRecordValueByID deletes one or more ComposeRecordValues from store
+//
+// This function is auto-generated
+func DeleteComposeRecordValueByRecordIDNamePlace(ctx context.Context, s ComposeRecordValues, recordID uint64, name string, place uint) error {
+ return s.DeleteComposeRecordValueByRecordIDNamePlace(ctx, recordID, name, place)
+}
+
+// TruncateComposeRecordValues Deletes all ComposeRecordValues from store
+//
+// This function is auto-generated
+func TruncateComposeRecordValues(ctx context.Context, s ComposeRecordValues) error {
+ return s.TruncateComposeRecordValues(ctx)
+}
+
+// ComposeRecordValueRefLookup
+//
+// This function is auto-generated
+func ComposeRecordValueRefLookup(ctx context.Context, s ComposeRecordValues, mod *composeType.Module, field string, ref uint64) (uint64, error) {
+ return s.ComposeRecordValueRefLookup(ctx, mod, field, ref)
+}
+
+// SearchCredentials returns all matching Credentials from store
+//
+// This function is auto-generated
+func SearchCredentials(ctx context.Context, s Credentials, f systemType.CredentialFilter) (systemType.CredentialSet, systemType.CredentialFilter, error) {
+ return s.SearchCredentials(ctx, f)
+}
+
+// CreateCredential creates one or more Credentials in store
+//
+// This function is auto-generated
+func CreateCredential(ctx context.Context, s Credentials, rr ...*systemType.Credential) error {
+ return s.CreateCredential(ctx, rr...)
+}
+
+// UpdateCredential updates one or more (existing) Credentials in store
+//
+// This function is auto-generated
+func UpdateCredential(ctx context.Context, s Credentials, rr ...*systemType.Credential) error {
+ return s.UpdateCredential(ctx, rr...)
+}
+
+// UpsertCredential creates new or updates existing one or more Credentials in store
+//
+// This function is auto-generated
+func UpsertCredential(ctx context.Context, s Credentials, rr ...*systemType.Credential) error {
+ return s.UpsertCredential(ctx, rr...)
+}
+
+// DeleteCredential deletes one or more Credentials from store
+//
+// This function is auto-generated
+func DeleteCredential(ctx context.Context, s Credentials, rr ...*systemType.Credential) error {
+ return s.DeleteCredential(ctx, rr...)
+}
+
+// DeleteCredentialByID deletes one or more Credentials from store
+//
+// This function is auto-generated
+func DeleteCredentialByID(ctx context.Context, s Credentials, id uint64) error {
+ return s.DeleteCredentialByID(ctx, id)
+}
+
+// TruncateCredentials Deletes all Credentials from store
+//
+// This function is auto-generated
+func TruncateCredentials(ctx context.Context, s Credentials) error {
+ return s.TruncateCredentials(ctx)
+}
+
+// LookupCredentialByID searches for credentials by ID
+//
+// It returns credentials even if deleted
+//
+// This function is auto-generated
+func LookupCredentialByID(ctx context.Context, s Credentials, id uint64) (*systemType.Credential, error) {
+ return s.LookupCredentialByID(ctx, id)
+}
+
+// SearchFederationExposedModules returns all matching FederationExposedModules from store
+//
+// This function is auto-generated
+func SearchFederationExposedModules(ctx context.Context, s FederationExposedModules, f federationType.ExposedModuleFilter) (federationType.ExposedModuleSet, federationType.ExposedModuleFilter, error) {
+ return s.SearchFederationExposedModules(ctx, f)
+}
+
+// CreateFederationExposedModule creates one or more FederationExposedModules in store
+//
+// This function is auto-generated
+func CreateFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*federationType.ExposedModule) error {
+ return s.CreateFederationExposedModule(ctx, rr...)
+}
+
+// UpdateFederationExposedModule updates one or more (existing) FederationExposedModules in store
+//
+// This function is auto-generated
+func UpdateFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*federationType.ExposedModule) error {
+ return s.UpdateFederationExposedModule(ctx, rr...)
+}
+
+// UpsertFederationExposedModule creates new or updates existing one or more FederationExposedModules in store
+//
+// This function is auto-generated
+func UpsertFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*federationType.ExposedModule) error {
+ return s.UpsertFederationExposedModule(ctx, rr...)
+}
+
+// DeleteFederationExposedModule deletes one or more FederationExposedModules from store
+//
+// This function is auto-generated
+func DeleteFederationExposedModule(ctx context.Context, s FederationExposedModules, rr ...*federationType.ExposedModule) error {
+ return s.DeleteFederationExposedModule(ctx, rr...)
+}
+
+// DeleteFederationExposedModuleByID deletes one or more FederationExposedModules from store
+//
+// This function is auto-generated
+func DeleteFederationExposedModuleByID(ctx context.Context, s FederationExposedModules, id uint64) error {
+ return s.DeleteFederationExposedModuleByID(ctx, id)
+}
+
+// TruncateFederationExposedModules Deletes all FederationExposedModules from store
+//
+// This function is auto-generated
+func TruncateFederationExposedModules(ctx context.Context, s FederationExposedModules) error {
+ return s.TruncateFederationExposedModules(ctx)
+}
+
+// LookupFederationExposedModuleByID searches for federation module by ID
+//
+// It returns federation module
+//
+// This function is auto-generated
+func LookupFederationExposedModuleByID(ctx context.Context, s FederationExposedModules, id uint64) (*federationType.ExposedModule, error) {
+ return s.LookupFederationExposedModuleByID(ctx, id)
+}
+
+// SearchFederationModuleMappings returns all matching FederationModuleMappings from store
+//
+// This function is auto-generated
+func SearchFederationModuleMappings(ctx context.Context, s FederationModuleMappings, f federationType.ModuleMappingFilter) (federationType.ModuleMappingSet, federationType.ModuleMappingFilter, error) {
+ return s.SearchFederationModuleMappings(ctx, f)
+}
+
+// CreateFederationModuleMapping creates one or more FederationModuleMappings in store
+//
+// This function is auto-generated
+func CreateFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*federationType.ModuleMapping) error {
+ return s.CreateFederationModuleMapping(ctx, rr...)
+}
+
+// UpdateFederationModuleMapping updates one or more (existing) FederationModuleMappings in store
+//
+// This function is auto-generated
+func UpdateFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*federationType.ModuleMapping) error {
+ return s.UpdateFederationModuleMapping(ctx, rr...)
+}
+
+// UpsertFederationModuleMapping creates new or updates existing one or more FederationModuleMappings in store
+//
+// This function is auto-generated
+func UpsertFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*federationType.ModuleMapping) error {
+ return s.UpsertFederationModuleMapping(ctx, rr...)
+}
+
+// DeleteFederationModuleMapping deletes one or more FederationModuleMappings from store
+//
+// This function is auto-generated
+func DeleteFederationModuleMapping(ctx context.Context, s FederationModuleMappings, rr ...*federationType.ModuleMapping) error {
+ return s.DeleteFederationModuleMapping(ctx, rr...)
+}
+
+// DeleteFederationModuleMappingByID deletes one or more FederationModuleMappings from store
+//
+// This function is auto-generated
+func DeleteFederationModuleMappingBy(ctx context.Context, s FederationModuleMappings) error {
+ return s.DeleteFederationModuleMappingBy(ctx)
+}
+
+// TruncateFederationModuleMappings Deletes all FederationModuleMappings from store
+//
+// This function is auto-generated
+func TruncateFederationModuleMappings(ctx context.Context, s FederationModuleMappings) error {
+ return s.TruncateFederationModuleMappings(ctx)
+}
+
+// LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID searches for module mapping by federation module id and compose module id
+//
+// It returns module mapping
+//
+// This function is auto-generated
+func LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, s FederationModuleMappings, federationModuleID uint64, composeModuleID uint64, composeNamespaceID uint64) (*federationType.ModuleMapping, error) {
+ return s.LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx, federationModuleID, composeModuleID, composeNamespaceID)
+}
+
+// LookupFederationModuleMappingByFederationModuleID searches for module mapping by federation module id
+//
+// It returns module mapping
+//
+// This function is auto-generated
+func LookupFederationModuleMappingByFederationModuleID(ctx context.Context, s FederationModuleMappings, federationModuleID uint64) (*federationType.ModuleMapping, error) {
+ return s.LookupFederationModuleMappingByFederationModuleID(ctx, federationModuleID)
+}
+
+// SearchFederationNodes returns all matching FederationNodes from store
+//
+// This function is auto-generated
+func SearchFederationNodes(ctx context.Context, s FederationNodes, f federationType.NodeFilter) (federationType.NodeSet, federationType.NodeFilter, error) {
+ return s.SearchFederationNodes(ctx, f)
+}
+
+// CreateFederationNode creates one or more FederationNodes in store
+//
+// This function is auto-generated
+func CreateFederationNode(ctx context.Context, s FederationNodes, rr ...*federationType.Node) error {
+ return s.CreateFederationNode(ctx, rr...)
+}
+
+// UpdateFederationNode updates one or more (existing) FederationNodes in store
+//
+// This function is auto-generated
+func UpdateFederationNode(ctx context.Context, s FederationNodes, rr ...*federationType.Node) error {
+ return s.UpdateFederationNode(ctx, rr...)
+}
+
+// UpsertFederationNode creates new or updates existing one or more FederationNodes in store
+//
+// This function is auto-generated
+func UpsertFederationNode(ctx context.Context, s FederationNodes, rr ...*federationType.Node) error {
+ return s.UpsertFederationNode(ctx, rr...)
+}
+
+// DeleteFederationNode deletes one or more FederationNodes from store
+//
+// This function is auto-generated
+func DeleteFederationNode(ctx context.Context, s FederationNodes, rr ...*federationType.Node) error {
+ return s.DeleteFederationNode(ctx, rr...)
+}
+
+// DeleteFederationNodeByID deletes one or more FederationNodes from store
+//
+// This function is auto-generated
+func DeleteFederationNodeByID(ctx context.Context, s FederationNodes, id uint64) error {
+ return s.DeleteFederationNodeByID(ctx, id)
+}
+
+// TruncateFederationNodes Deletes all FederationNodes from store
+//
+// This function is auto-generated
+func TruncateFederationNodes(ctx context.Context, s FederationNodes) error {
+ return s.TruncateFederationNodes(ctx)
+}
+
+// LookupFederationNodeByID searches for federation node by ID
+//
+// It returns federation node
+//
+// This function is auto-generated
+func LookupFederationNodeByID(ctx context.Context, s FederationNodes, id uint64) (*federationType.Node, error) {
+ return s.LookupFederationNodeByID(ctx, id)
+}
+
+// LookupFederationNodeByBaseURLSharedNodeID searches for node by shared-node-id and base-url
+//
+// This function is auto-generated
+func LookupFederationNodeByBaseURLSharedNodeID(ctx context.Context, s FederationNodes, baseURL string, sharedNodeID uint64) (*federationType.Node, error) {
+ return s.LookupFederationNodeByBaseURLSharedNodeID(ctx, baseURL, sharedNodeID)
+}
+
+// LookupFederationNodeBySharedNodeID searches for node by shared-node-id
+//
+// This function is auto-generated
+func LookupFederationNodeBySharedNodeID(ctx context.Context, s FederationNodes, sharedNodeID uint64) (*federationType.Node, error) {
+ return s.LookupFederationNodeBySharedNodeID(ctx, sharedNodeID)
+}
+
+// SearchFederationNodeSyncs returns all matching FederationNodeSyncs from store
+//
+// This function is auto-generated
+func SearchFederationNodeSyncs(ctx context.Context, s FederationNodeSyncs, f federationType.NodeSyncFilter) (federationType.NodeSyncSet, federationType.NodeSyncFilter, error) {
+ return s.SearchFederationNodeSyncs(ctx, f)
+}
+
+// CreateFederationNodeSync creates one or more FederationNodeSyncs in store
+//
+// This function is auto-generated
+func CreateFederationNodeSync(ctx context.Context, s FederationNodeSyncs, rr ...*federationType.NodeSync) error {
+ return s.CreateFederationNodeSync(ctx, rr...)
+}
+
+// UpdateFederationNodeSync updates one or more (existing) FederationNodeSyncs in store
+//
+// This function is auto-generated
+func UpdateFederationNodeSync(ctx context.Context, s FederationNodeSyncs, rr ...*federationType.NodeSync) error {
+ return s.UpdateFederationNodeSync(ctx, rr...)
+}
+
+// UpsertFederationNodeSync creates new or updates existing one or more FederationNodeSyncs in store
+//
+// This function is auto-generated
+func UpsertFederationNodeSync(ctx context.Context, s FederationNodeSyncs, rr ...*federationType.NodeSync) error {
+ return s.UpsertFederationNodeSync(ctx, rr...)
+}
+
+// DeleteFederationNodeSync deletes one or more FederationNodeSyncs from store
+//
+// This function is auto-generated
+func DeleteFederationNodeSync(ctx context.Context, s FederationNodeSyncs, rr ...*federationType.NodeSync) error {
+ return s.DeleteFederationNodeSync(ctx, rr...)
+}
+
+// DeleteFederationNodeSyncByID deletes one or more FederationNodeSyncs from store
+//
+// This function is auto-generated
+func DeleteFederationNodeSyncByNodeID(ctx context.Context, s FederationNodeSyncs, nodeID uint64) error {
+ return s.DeleteFederationNodeSyncByNodeID(ctx, nodeID)
+}
+
+// TruncateFederationNodeSyncs Deletes all FederationNodeSyncs from store
+//
+// This function is auto-generated
+func TruncateFederationNodeSyncs(ctx context.Context, s FederationNodeSyncs) error {
+ return s.TruncateFederationNodeSyncs(ctx)
+}
+
+// LookupFederationNodeSyncByNodeID searches for sync activity by node ID
+//
+// It returns sync activity
+//
+// This function is auto-generated
+func LookupFederationNodeSyncByNodeID(ctx context.Context, s FederationNodeSyncs, nodeID uint64) (*federationType.NodeSync, error) {
+ return s.LookupFederationNodeSyncByNodeID(ctx, nodeID)
+}
+
+// LookupFederationNodeSyncByNodeIDModuleIDSyncTypeSyncStatus searches for activity by node, type and status
+//
+// It returns sync activity
+//
+// This function is auto-generated
+func LookupFederationNodeSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx context.Context, s FederationNodeSyncs, nodeID uint64, moduleID uint64, syncType string, syncStatus string) (*federationType.NodeSync, error) {
+ return s.LookupFederationNodeSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx, nodeID, moduleID, syncType, syncStatus)
+}
+
+// SearchFederationSharedModules returns all matching FederationSharedModules from store
+//
+// This function is auto-generated
+func SearchFederationSharedModules(ctx context.Context, s FederationSharedModules, f federationType.SharedModuleFilter) (federationType.SharedModuleSet, federationType.SharedModuleFilter, error) {
+ return s.SearchFederationSharedModules(ctx, f)
+}
+
+// CreateFederationSharedModule creates one or more FederationSharedModules in store
+//
+// This function is auto-generated
+func CreateFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*federationType.SharedModule) error {
+ return s.CreateFederationSharedModule(ctx, rr...)
+}
+
+// UpdateFederationSharedModule updates one or more (existing) FederationSharedModules in store
+//
+// This function is auto-generated
+func UpdateFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*federationType.SharedModule) error {
+ return s.UpdateFederationSharedModule(ctx, rr...)
+}
+
+// UpsertFederationSharedModule creates new or updates existing one or more FederationSharedModules in store
+//
+// This function is auto-generated
+func UpsertFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*federationType.SharedModule) error {
+ return s.UpsertFederationSharedModule(ctx, rr...)
+}
+
+// DeleteFederationSharedModule deletes one or more FederationSharedModules from store
+//
+// This function is auto-generated
+func DeleteFederationSharedModule(ctx context.Context, s FederationSharedModules, rr ...*federationType.SharedModule) error {
+ return s.DeleteFederationSharedModule(ctx, rr...)
+}
+
+// DeleteFederationSharedModuleByID deletes one or more FederationSharedModules from store
+//
+// This function is auto-generated
+func DeleteFederationSharedModuleByID(ctx context.Context, s FederationSharedModules, id uint64) error {
+ return s.DeleteFederationSharedModuleByID(ctx, id)
+}
+
+// TruncateFederationSharedModules Deletes all FederationSharedModules from store
+//
+// This function is auto-generated
+func TruncateFederationSharedModules(ctx context.Context, s FederationSharedModules) error {
+ return s.TruncateFederationSharedModules(ctx)
+}
+
+// LookupFederationSharedModuleByID searches for shared federation module by ID
+//
+// It returns shared federation module
+//
+// This function is auto-generated
+func LookupFederationSharedModuleByID(ctx context.Context, s FederationSharedModules, id uint64) (*federationType.SharedModule, error) {
+ return s.LookupFederationSharedModuleByID(ctx, id)
+}
+
+// SearchFlags returns all matching Flags from store
+//
+// This function is auto-generated
+func SearchFlags(ctx context.Context, s Flags, f flagType.FlagFilter) (flagType.FlagSet, flagType.FlagFilter, error) {
+ return s.SearchFlags(ctx, f)
+}
+
+// CreateFlag creates one or more Flags in store
+//
+// This function is auto-generated
+func CreateFlag(ctx context.Context, s Flags, rr ...*flagType.Flag) error {
+ return s.CreateFlag(ctx, rr...)
+}
+
+// UpdateFlag updates one or more (existing) Flags in store
+//
+// This function is auto-generated
+func UpdateFlag(ctx context.Context, s Flags, rr ...*flagType.Flag) error {
+ return s.UpdateFlag(ctx, rr...)
+}
+
+// UpsertFlag creates new or updates existing one or more Flags in store
+//
+// This function is auto-generated
+func UpsertFlag(ctx context.Context, s Flags, rr ...*flagType.Flag) error {
+ return s.UpsertFlag(ctx, rr...)
+}
+
+// DeleteFlag deletes one or more Flags from store
+//
+// This function is auto-generated
+func DeleteFlag(ctx context.Context, s Flags, rr ...*flagType.Flag) error {
+ return s.DeleteFlag(ctx, rr...)
+}
+
+// DeleteFlagByID deletes one or more Flags from store
+//
+// This function is auto-generated
+func DeleteFlagByKindResourceIDOwnedByName(ctx context.Context, s Flags, kind string, resourceID uint64, ownedBy uint64, name string) error {
+ return s.DeleteFlagByKindResourceIDOwnedByName(ctx, kind, resourceID, ownedBy, name)
+}
+
+// TruncateFlags Deletes all Flags from store
+//
+// This function is auto-generated
+func TruncateFlags(ctx context.Context, s Flags) error {
+ return s.TruncateFlags(ctx)
+}
+
+// LookupFlagByKindResourceIDOwnedByName searches for flag by kind, resource ID, owner and name
+//
+// This function is auto-generated
+func LookupFlagByKindResourceIDOwnedByName(ctx context.Context, s Flags, kind string, resourceID uint64, ownedBy uint64, name string) (*flagType.Flag, error) {
+ return s.LookupFlagByKindResourceIDOwnedByName(ctx, kind, resourceID, ownedBy, name)
+}
+
+// SearchLabels returns all matching Labels from store
+//
+// This function is auto-generated
+func SearchLabels(ctx context.Context, s Labels, f labelsType.LabelFilter) (labelsType.LabelSet, labelsType.LabelFilter, error) {
+ return s.SearchLabels(ctx, f)
+}
+
+// CreateLabel creates one or more Labels in store
+//
+// This function is auto-generated
+func CreateLabel(ctx context.Context, s Labels, rr ...*labelsType.Label) error {
+ return s.CreateLabel(ctx, rr...)
+}
+
+// UpdateLabel updates one or more (existing) Labels in store
+//
+// This function is auto-generated
+func UpdateLabel(ctx context.Context, s Labels, rr ...*labelsType.Label) error {
+ return s.UpdateLabel(ctx, rr...)
+}
+
+// UpsertLabel creates new or updates existing one or more Labels in store
+//
+// This function is auto-generated
+func UpsertLabel(ctx context.Context, s Labels, rr ...*labelsType.Label) error {
+ return s.UpsertLabel(ctx, rr...)
+}
+
+// DeleteLabel deletes one or more Labels from store
+//
+// This function is auto-generated
+func DeleteLabel(ctx context.Context, s Labels, rr ...*labelsType.Label) error {
+ return s.DeleteLabel(ctx, rr...)
+}
+
+// DeleteLabelByID deletes one or more Labels from store
+//
+// This function is auto-generated
+func DeleteLabelByKindResourceIDName(ctx context.Context, s Labels, kind string, resourceID uint64, name string) error {
+ return s.DeleteLabelByKindResourceIDName(ctx, kind, resourceID, name)
+}
+
+// TruncateLabels Deletes all Labels from store
+//
+// This function is auto-generated
+func TruncateLabels(ctx context.Context, s Labels) error {
+ return s.TruncateLabels(ctx)
+}
+
+// LookupLabelByKindResourceIDName searches for label by kind, resource ID and name
+//
+// This function is auto-generated
+func LookupLabelByKindResourceIDName(ctx context.Context, s Labels, kind string, resourceID uint64, name string) (*labelsType.Label, error) {
+ return s.LookupLabelByKindResourceIDName(ctx, kind, resourceID, name)
+}
+
+// DeleteExtraLabels
+//
+// This function is auto-generated
+func DeleteExtraLabels(ctx context.Context, s Labels, kind string, resourceId uint64, name ...string) error {
+ return s.DeleteExtraLabels(ctx, kind, resourceId, name...)
+}
+
+// SearchQueues returns all matching Queues from store
+//
+// This function is auto-generated
+func SearchQueues(ctx context.Context, s Queues, f systemType.QueueFilter) (systemType.QueueSet, systemType.QueueFilter, error) {
+ return s.SearchQueues(ctx, f)
+}
+
+// CreateQueue creates one or more Queues in store
+//
+// This function is auto-generated
+func CreateQueue(ctx context.Context, s Queues, rr ...*systemType.Queue) error {
+ return s.CreateQueue(ctx, rr...)
+}
+
+// UpdateQueue updates one or more (existing) Queues in store
+//
+// This function is auto-generated
+func UpdateQueue(ctx context.Context, s Queues, rr ...*systemType.Queue) error {
+ return s.UpdateQueue(ctx, rr...)
+}
+
+// UpsertQueue creates new or updates existing one or more Queues in store
+//
+// This function is auto-generated
+func UpsertQueue(ctx context.Context, s Queues, rr ...*systemType.Queue) error {
+ return s.UpsertQueue(ctx, rr...)
+}
+
+// DeleteQueue deletes one or more Queues from store
+//
+// This function is auto-generated
+func DeleteQueue(ctx context.Context, s Queues, rr ...*systemType.Queue) error {
+ return s.DeleteQueue(ctx, rr...)
+}
+
+// DeleteQueueByID deletes one or more Queues from store
+//
+// This function is auto-generated
+func DeleteQueueByID(ctx context.Context, s Queues, id uint64) error {
+ return s.DeleteQueueByID(ctx, id)
+}
+
+// TruncateQueues Deletes all Queues from store
+//
+// This function is auto-generated
+func TruncateQueues(ctx context.Context, s Queues) error {
+ return s.TruncateQueues(ctx)
+}
+
+// LookupQueueByID searches for queue by ID
+//
+// This function is auto-generated
+func LookupQueueByID(ctx context.Context, s Queues, id uint64) (*systemType.Queue, error) {
+ return s.LookupQueueByID(ctx, id)
+}
+
+// LookupQueueByQueue searches for queue by queue name
+//
+// This function is auto-generated
+func LookupQueueByQueue(ctx context.Context, s Queues, queue string) (*systemType.Queue, error) {
+ return s.LookupQueueByQueue(ctx, queue)
+}
+
+// SearchQueueMessages returns all matching QueueMessages from store
+//
+// This function is auto-generated
+func SearchQueueMessages(ctx context.Context, s QueueMessages, f systemType.QueueMessageFilter) (systemType.QueueMessageSet, systemType.QueueMessageFilter, error) {
+ return s.SearchQueueMessages(ctx, f)
+}
+
+// CreateQueueMessage creates one or more QueueMessages in store
+//
+// This function is auto-generated
+func CreateQueueMessage(ctx context.Context, s QueueMessages, rr ...*systemType.QueueMessage) error {
+ return s.CreateQueueMessage(ctx, rr...)
+}
+
+// UpdateQueueMessage updates one or more (existing) QueueMessages in store
+//
+// This function is auto-generated
+func UpdateQueueMessage(ctx context.Context, s QueueMessages, rr ...*systemType.QueueMessage) error {
+ return s.UpdateQueueMessage(ctx, rr...)
+}
+
+// UpsertQueueMessage creates new or updates existing one or more QueueMessages in store
+//
+// This function is auto-generated
+func UpsertQueueMessage(ctx context.Context, s QueueMessages, rr ...*systemType.QueueMessage) error {
+ return s.UpsertQueueMessage(ctx, rr...)
+}
+
+// DeleteQueueMessage deletes one or more QueueMessages from store
+//
+// This function is auto-generated
+func DeleteQueueMessage(ctx context.Context, s QueueMessages, rr ...*systemType.QueueMessage) error {
+ return s.DeleteQueueMessage(ctx, rr...)
+}
+
+// DeleteQueueMessageByID deletes one or more QueueMessages from store
+//
+// This function is auto-generated
+func DeleteQueueMessageByID(ctx context.Context, s QueueMessages, id uint64) error {
+ return s.DeleteQueueMessageByID(ctx, id)
+}
+
+// TruncateQueueMessages Deletes all QueueMessages from store
+//
+// This function is auto-generated
+func TruncateQueueMessages(ctx context.Context, s QueueMessages) error {
+ return s.TruncateQueueMessages(ctx)
+}
+
+// SearchRbacRules returns all matching RbacRules from store
+//
+// This function is auto-generated
+func SearchRbacRules(ctx context.Context, s RbacRules, f rbacType.RuleFilter) (rbacType.RuleSet, rbacType.RuleFilter, error) {
+ return s.SearchRbacRules(ctx, f)
+}
+
+// CreateRbacRule creates one or more RbacRules in store
+//
+// This function is auto-generated
+func CreateRbacRule(ctx context.Context, s RbacRules, rr ...*rbacType.Rule) error {
+ return s.CreateRbacRule(ctx, rr...)
+}
+
+// UpdateRbacRule updates one or more (existing) RbacRules in store
+//
+// This function is auto-generated
+func UpdateRbacRule(ctx context.Context, s RbacRules, rr ...*rbacType.Rule) error {
+ return s.UpdateRbacRule(ctx, rr...)
+}
+
+// UpsertRbacRule creates new or updates existing one or more RbacRules in store
+//
+// This function is auto-generated
+func UpsertRbacRule(ctx context.Context, s RbacRules, rr ...*rbacType.Rule) error {
+ return s.UpsertRbacRule(ctx, rr...)
+}
+
+// DeleteRbacRule deletes one or more RbacRules from store
+//
+// This function is auto-generated
+func DeleteRbacRule(ctx context.Context, s RbacRules, rr ...*rbacType.Rule) error {
+ return s.DeleteRbacRule(ctx, rr...)
+}
+
+// DeleteRbacRuleByID deletes one or more RbacRules from store
+//
+// This function is auto-generated
+func DeleteRbacRuleByRoleIDResourceOperation(ctx context.Context, s RbacRules, roleID uint64, resource string, operation string) error {
+ return s.DeleteRbacRuleByRoleIDResourceOperation(ctx, roleID, resource, operation)
+}
+
+// TruncateRbacRules Deletes all RbacRules from store
+//
+// This function is auto-generated
+func TruncateRbacRules(ctx context.Context, s RbacRules) error {
+ return s.TruncateRbacRules(ctx)
+}
+
+// TransferRbacRules
+//
+// This function is auto-generated
+func TransferRbacRules(ctx context.Context, s RbacRules, src uint64, dst uint64) error {
+ return s.TransferRbacRules(ctx, src, dst)
+}
+
+// SearchReminders returns all matching Reminders from store
+//
+// This function is auto-generated
+func SearchReminders(ctx context.Context, s Reminders, f systemType.ReminderFilter) (systemType.ReminderSet, systemType.ReminderFilter, error) {
+ return s.SearchReminders(ctx, f)
+}
+
+// CreateReminder creates one or more Reminders in store
+//
+// This function is auto-generated
+func CreateReminder(ctx context.Context, s Reminders, rr ...*systemType.Reminder) error {
+ return s.CreateReminder(ctx, rr...)
+}
+
+// UpdateReminder updates one or more (existing) Reminders in store
+//
+// This function is auto-generated
+func UpdateReminder(ctx context.Context, s Reminders, rr ...*systemType.Reminder) error {
+ return s.UpdateReminder(ctx, rr...)
+}
+
+// UpsertReminder creates new or updates existing one or more Reminders in store
+//
+// This function is auto-generated
+func UpsertReminder(ctx context.Context, s Reminders, rr ...*systemType.Reminder) error {
+ return s.UpsertReminder(ctx, rr...)
+}
+
+// DeleteReminder deletes one or more Reminders from store
+//
+// This function is auto-generated
+func DeleteReminder(ctx context.Context, s Reminders, rr ...*systemType.Reminder) error {
+ return s.DeleteReminder(ctx, rr...)
+}
+
+// DeleteReminderByID deletes one or more Reminders from store
+//
+// This function is auto-generated
+func DeleteReminderByID(ctx context.Context, s Reminders, id uint64) error {
+ return s.DeleteReminderByID(ctx, id)
+}
+
+// TruncateReminders Deletes all Reminders from store
+//
+// This function is auto-generated
+func TruncateReminders(ctx context.Context, s Reminders) error {
+ return s.TruncateReminders(ctx)
+}
+
+// LookupReminderByID
+//
+// This function is auto-generated
+func LookupReminderByID(ctx context.Context, s Reminders, id uint64) (*systemType.Reminder, error) {
+ return s.LookupReminderByID(ctx, id)
+}
+
+// SearchReports returns all matching Reports from store
+//
+// This function is auto-generated
+func SearchReports(ctx context.Context, s Reports, f systemType.ReportFilter) (systemType.ReportSet, systemType.ReportFilter, error) {
+ return s.SearchReports(ctx, f)
+}
+
+// CreateReport creates one or more Reports in store
+//
+// This function is auto-generated
+func CreateReport(ctx context.Context, s Reports, rr ...*systemType.Report) error {
+ return s.CreateReport(ctx, rr...)
+}
+
+// UpdateReport updates one or more (existing) Reports in store
+//
+// This function is auto-generated
+func UpdateReport(ctx context.Context, s Reports, rr ...*systemType.Report) error {
+ return s.UpdateReport(ctx, rr...)
+}
+
+// UpsertReport creates new or updates existing one or more Reports in store
+//
+// This function is auto-generated
+func UpsertReport(ctx context.Context, s Reports, rr ...*systemType.Report) error {
+ return s.UpsertReport(ctx, rr...)
+}
+
+// DeleteReport deletes one or more Reports from store
+//
+// This function is auto-generated
+func DeleteReport(ctx context.Context, s Reports, rr ...*systemType.Report) error {
+ return s.DeleteReport(ctx, rr...)
+}
+
+// DeleteReportByID deletes one or more Reports from store
+//
+// This function is auto-generated
+func DeleteReportByID(ctx context.Context, s Reports, id uint64) error {
+ return s.DeleteReportByID(ctx, id)
+}
+
+// TruncateReports Deletes all Reports from store
+//
+// This function is auto-generated
+func TruncateReports(ctx context.Context, s Reports) error {
+ return s.TruncateReports(ctx)
+}
+
+// LookupReportByID searches for report by ID
+//
+// It returns report even if deleted
+//
+// This function is auto-generated
+func LookupReportByID(ctx context.Context, s Reports, id uint64) (*systemType.Report, error) {
+ return s.LookupReportByID(ctx, id)
+}
+
+// LookupReportByHandle searches for report by handle
+//
+// It returns report if deleted
+//
+// This function is auto-generated
+func LookupReportByHandle(ctx context.Context, s Reports, handle string) (*systemType.Report, error) {
+ return s.LookupReportByHandle(ctx, handle)
+}
+
+// SearchResourceActivitys returns all matching ResourceActivitys from store
+//
+// This function is auto-generated
+func SearchResourceActivitys(ctx context.Context, s ResourceActivitys, f discoveryType.ResourceActivityFilter) (discoveryType.ResourceActivitySet, discoveryType.ResourceActivityFilter, error) {
+ return s.SearchResourceActivitys(ctx, f)
+}
+
+// CreateResourceActivity creates one or more ResourceActivitys in store
+//
+// This function is auto-generated
+func CreateResourceActivity(ctx context.Context, s ResourceActivitys, rr ...*discoveryType.ResourceActivity) error {
+ return s.CreateResourceActivity(ctx, rr...)
+}
+
+// UpdateResourceActivity updates one or more (existing) ResourceActivitys in store
+//
+// This function is auto-generated
+func UpdateResourceActivity(ctx context.Context, s ResourceActivitys, rr ...*discoveryType.ResourceActivity) error {
+ return s.UpdateResourceActivity(ctx, rr...)
+}
+
+// UpsertResourceActivity creates new or updates existing one or more ResourceActivitys in store
+//
+// This function is auto-generated
+func UpsertResourceActivity(ctx context.Context, s ResourceActivitys, rr ...*discoveryType.ResourceActivity) error {
+ return s.UpsertResourceActivity(ctx, rr...)
+}
+
+// DeleteResourceActivity deletes one or more ResourceActivitys from store
+//
+// This function is auto-generated
+func DeleteResourceActivity(ctx context.Context, s ResourceActivitys, rr ...*discoveryType.ResourceActivity) error {
+ return s.DeleteResourceActivity(ctx, rr...)
+}
+
+// DeleteResourceActivityByID deletes one or more ResourceActivitys from store
+//
+// This function is auto-generated
+func DeleteResourceActivityByID(ctx context.Context, s ResourceActivitys, id uint64) error {
+ return s.DeleteResourceActivityByID(ctx, id)
+}
+
+// TruncateResourceActivitys Deletes all ResourceActivitys from store
+//
+// This function is auto-generated
+func TruncateResourceActivitys(ctx context.Context, s ResourceActivitys) error {
+ return s.TruncateResourceActivitys(ctx)
+}
+
+// SearchResourceTranslations returns all matching ResourceTranslations from store
+//
+// This function is auto-generated
+func SearchResourceTranslations(ctx context.Context, s ResourceTranslations, f systemType.ResourceTranslationFilter) (systemType.ResourceTranslationSet, systemType.ResourceTranslationFilter, error) {
+ return s.SearchResourceTranslations(ctx, f)
+}
+
+// CreateResourceTranslation creates one or more ResourceTranslations in store
+//
+// This function is auto-generated
+func CreateResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*systemType.ResourceTranslation) error {
+ return s.CreateResourceTranslation(ctx, rr...)
+}
+
+// UpdateResourceTranslation updates one or more (existing) ResourceTranslations in store
+//
+// This function is auto-generated
+func UpdateResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*systemType.ResourceTranslation) error {
+ return s.UpdateResourceTranslation(ctx, rr...)
+}
+
+// UpsertResourceTranslation creates new or updates existing one or more ResourceTranslations in store
+//
+// This function is auto-generated
+func UpsertResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*systemType.ResourceTranslation) error {
+ return s.UpsertResourceTranslation(ctx, rr...)
+}
+
+// DeleteResourceTranslation deletes one or more ResourceTranslations from store
+//
+// This function is auto-generated
+func DeleteResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*systemType.ResourceTranslation) error {
+ return s.DeleteResourceTranslation(ctx, rr...)
+}
+
+// DeleteResourceTranslationByID deletes one or more ResourceTranslations from store
+//
+// This function is auto-generated
+func DeleteResourceTranslationByID(ctx context.Context, s ResourceTranslations, id uint64) error {
+ return s.DeleteResourceTranslationByID(ctx, id)
+}
+
+// TruncateResourceTranslations Deletes all ResourceTranslations from store
+//
+// This function is auto-generated
+func TruncateResourceTranslations(ctx context.Context, s ResourceTranslations) error {
+ return s.TruncateResourceTranslations(ctx)
+}
+
+// LookupResourceTranslationByID searches for resource translation by ID
+// It also returns deleted resource translations.
+//
+// This function is auto-generated
+func LookupResourceTranslationByID(ctx context.Context, s ResourceTranslations, id uint64) (*systemType.ResourceTranslation, error) {
+ return s.LookupResourceTranslationByID(ctx, id)
+}
+
+// TransformResource
+//
+// This function is auto-generated
+func TransformResource(ctx context.Context, s ResourceTranslations, lang language.Tag) (map[string]map[string]*locale.ResourceTranslation, error) {
+ return s.TransformResource(ctx, lang)
+}
+
+// SearchRoles returns all matching Roles from store
+//
+// This function is auto-generated
+func SearchRoles(ctx context.Context, s Roles, f systemType.RoleFilter) (systemType.RoleSet, systemType.RoleFilter, error) {
+ return s.SearchRoles(ctx, f)
+}
+
+// CreateRole creates one or more Roles in store
+//
+// This function is auto-generated
+func CreateRole(ctx context.Context, s Roles, rr ...*systemType.Role) error {
+ return s.CreateRole(ctx, rr...)
+}
+
+// UpdateRole updates one or more (existing) Roles in store
+//
+// This function is auto-generated
+func UpdateRole(ctx context.Context, s Roles, rr ...*systemType.Role) error {
+ return s.UpdateRole(ctx, rr...)
+}
+
+// UpsertRole creates new or updates existing one or more Roles in store
+//
+// This function is auto-generated
+func UpsertRole(ctx context.Context, s Roles, rr ...*systemType.Role) error {
+ return s.UpsertRole(ctx, rr...)
+}
+
+// DeleteRole deletes one or more Roles from store
+//
+// This function is auto-generated
+func DeleteRole(ctx context.Context, s Roles, rr ...*systemType.Role) error {
+ return s.DeleteRole(ctx, rr...)
+}
+
+// DeleteRoleByID deletes one or more Roles from store
+//
+// This function is auto-generated
+func DeleteRoleByID(ctx context.Context, s Roles, id uint64) error {
+ return s.DeleteRoleByID(ctx, id)
+}
+
+// TruncateRoles Deletes all Roles from store
+//
+// This function is auto-generated
+func TruncateRoles(ctx context.Context, s Roles) error {
+ return s.TruncateRoles(ctx)
+}
+
+// LookupRoleByID searches for role by ID
+//
+// It returns role even if deleted or suspended
+//
+// This function is auto-generated
+func LookupRoleByID(ctx context.Context, s Roles, id uint64) (*systemType.Role, error) {
+ return s.LookupRoleByID(ctx, id)
+}
+
+// LookupRoleByHandle searches for role by handle
+//
+// It returns only valid role (not deleted, not suspended)
+//
+// This function is auto-generated
+func LookupRoleByHandle(ctx context.Context, s Roles, handle string) (*systemType.Role, error) {
+ return s.LookupRoleByHandle(ctx, handle)
+}
+
+// LookupRoleByName searches for role by name
+//
+// It returns only valid role (not deleted, not suspended)
+//
+// This function is auto-generated
+func LookupRoleByName(ctx context.Context, s Roles, name string) (*systemType.Role, error) {
+ return s.LookupRoleByName(ctx, name)
+}
+
+// RoleMetrics
+//
+// This function is auto-generated
+func RoleMetrics(ctx context.Context, s Roles) (*systemType.RoleMetrics, error) {
+ return s.RoleMetrics(ctx)
+}
+
+// SearchRoleMembers returns all matching RoleMembers from store
+//
+// This function is auto-generated
+func SearchRoleMembers(ctx context.Context, s RoleMembers, f systemType.RoleMemberFilter) (systemType.RoleMemberSet, systemType.RoleMemberFilter, error) {
+ return s.SearchRoleMembers(ctx, f)
+}
+
+// CreateRoleMember creates one or more RoleMembers in store
+//
+// This function is auto-generated
+func CreateRoleMember(ctx context.Context, s RoleMembers, rr ...*systemType.RoleMember) error {
+ return s.CreateRoleMember(ctx, rr...)
+}
+
+// UpdateRoleMember updates one or more (existing) RoleMembers in store
+//
+// This function is auto-generated
+func UpdateRoleMember(ctx context.Context, s RoleMembers, rr ...*systemType.RoleMember) error {
+ return s.UpdateRoleMember(ctx, rr...)
+}
+
+// UpsertRoleMember creates new or updates existing one or more RoleMembers in store
+//
+// This function is auto-generated
+func UpsertRoleMember(ctx context.Context, s RoleMembers, rr ...*systemType.RoleMember) error {
+ return s.UpsertRoleMember(ctx, rr...)
+}
+
+// DeleteRoleMember deletes one or more RoleMembers from store
+//
+// This function is auto-generated
+func DeleteRoleMember(ctx context.Context, s RoleMembers, rr ...*systemType.RoleMember) error {
+ return s.DeleteRoleMember(ctx, rr...)
+}
+
+// DeleteRoleMemberByID deletes one or more RoleMembers from store
+//
+// This function is auto-generated
+func DeleteRoleMemberByUserIDRoleID(ctx context.Context, s RoleMembers, userID uint64, roleID uint64) error {
+ return s.DeleteRoleMemberByUserIDRoleID(ctx, userID, roleID)
+}
+
+// TruncateRoleMembers Deletes all RoleMembers from store
+//
+// This function is auto-generated
+func TruncateRoleMembers(ctx context.Context, s RoleMembers) error {
+ return s.TruncateRoleMembers(ctx)
+}
+
+// TransferRoleMembers
+//
+// This function is auto-generated
+func TransferRoleMembers(ctx context.Context, s RoleMembers, src uint64, dst uint64) error {
+ return s.TransferRoleMembers(ctx, src, dst)
+}
+
+// SearchSettingValues returns all matching SettingValues from store
+//
+// This function is auto-generated
+func SearchSettingValues(ctx context.Context, s SettingValues, f systemType.SettingsFilter) (systemType.SettingValueSet, systemType.SettingsFilter, error) {
+ return s.SearchSettingValues(ctx, f)
+}
+
+// CreateSettingValue creates one or more SettingValues in store
+//
+// This function is auto-generated
+func CreateSettingValue(ctx context.Context, s SettingValues, rr ...*systemType.SettingValue) error {
+ return s.CreateSettingValue(ctx, rr...)
+}
+
+// UpdateSettingValue updates one or more (existing) SettingValues in store
+//
+// This function is auto-generated
+func UpdateSettingValue(ctx context.Context, s SettingValues, rr ...*systemType.SettingValue) error {
+ return s.UpdateSettingValue(ctx, rr...)
+}
+
+// UpsertSettingValue creates new or updates existing one or more SettingValues in store
+//
+// This function is auto-generated
+func UpsertSettingValue(ctx context.Context, s SettingValues, rr ...*systemType.SettingValue) error {
+ return s.UpsertSettingValue(ctx, rr...)
+}
+
+// DeleteSettingValue deletes one or more SettingValues from store
+//
+// This function is auto-generated
+func DeleteSettingValue(ctx context.Context, s SettingValues, rr ...*systemType.SettingValue) error {
+ return s.DeleteSettingValue(ctx, rr...)
+}
+
+// DeleteSettingValueByID deletes one or more SettingValues from store
+//
+// This function is auto-generated
+func DeleteSettingValueByNameOwnedBy(ctx context.Context, s SettingValues, name string, ownedBy uint64) error {
+ return s.DeleteSettingValueByNameOwnedBy(ctx, name, ownedBy)
+}
+
+// TruncateSettingValues Deletes all SettingValues from store
+//
+// This function is auto-generated
+func TruncateSettingValues(ctx context.Context, s SettingValues) error {
+ return s.TruncateSettingValues(ctx)
+}
+
+// LookupSettingValueByNameOwnedBy searches for settings by name and owner
+//
+// This function is auto-generated
+func LookupSettingValueByNameOwnedBy(ctx context.Context, s SettingValues, name string, ownedBy uint64) (*systemType.SettingValue, error) {
+ return s.LookupSettingValueByNameOwnedBy(ctx, name, ownedBy)
+}
+
+// SearchTemplates returns all matching Templates from store
+//
+// This function is auto-generated
+func SearchTemplates(ctx context.Context, s Templates, f systemType.TemplateFilter) (systemType.TemplateSet, systemType.TemplateFilter, error) {
+ return s.SearchTemplates(ctx, f)
+}
+
+// CreateTemplate creates one or more Templates in store
+//
+// This function is auto-generated
+func CreateTemplate(ctx context.Context, s Templates, rr ...*systemType.Template) error {
+ return s.CreateTemplate(ctx, rr...)
+}
+
+// UpdateTemplate updates one or more (existing) Templates in store
+//
+// This function is auto-generated
+func UpdateTemplate(ctx context.Context, s Templates, rr ...*systemType.Template) error {
+ return s.UpdateTemplate(ctx, rr...)
+}
+
+// UpsertTemplate creates new or updates existing one or more Templates in store
+//
+// This function is auto-generated
+func UpsertTemplate(ctx context.Context, s Templates, rr ...*systemType.Template) error {
+ return s.UpsertTemplate(ctx, rr...)
+}
+
+// DeleteTemplate deletes one or more Templates from store
+//
+// This function is auto-generated
+func DeleteTemplate(ctx context.Context, s Templates, rr ...*systemType.Template) error {
+ return s.DeleteTemplate(ctx, rr...)
+}
+
+// DeleteTemplateByID deletes one or more Templates from store
+//
+// This function is auto-generated
+func DeleteTemplateByID(ctx context.Context, s Templates, id uint64) error {
+ return s.DeleteTemplateByID(ctx, id)
+}
+
+// TruncateTemplates Deletes all Templates from store
+//
+// This function is auto-generated
+func TruncateTemplates(ctx context.Context, s Templates) error {
+ return s.TruncateTemplates(ctx)
+}
+
+// LookupTemplateByID searches for template by ID
+//
+// It also returns deleted templates.
+//
+// This function is auto-generated
+func LookupTemplateByID(ctx context.Context, s Templates, id uint64) (*systemType.Template, error) {
+ return s.LookupTemplateByID(ctx, id)
+}
+
+// LookupTemplateByHandle searches for template by handle
+//
+// It returns only valid templates (not deleted)
+//
+// This function is auto-generated
+func LookupTemplateByHandle(ctx context.Context, s Templates, handle string) (*systemType.Template, error) {
+ return s.LookupTemplateByHandle(ctx, handle)
+}
+
+// SearchUsers returns all matching Users from store
+//
+// This function is auto-generated
+func SearchUsers(ctx context.Context, s Users, f systemType.UserFilter) (systemType.UserSet, systemType.UserFilter, error) {
+ return s.SearchUsers(ctx, f)
+}
+
+// CreateUser creates one or more Users in store
+//
+// This function is auto-generated
+func CreateUser(ctx context.Context, s Users, rr ...*systemType.User) error {
+ return s.CreateUser(ctx, rr...)
+}
+
+// UpdateUser updates one or more (existing) Users in store
+//
+// This function is auto-generated
+func UpdateUser(ctx context.Context, s Users, rr ...*systemType.User) error {
+ return s.UpdateUser(ctx, rr...)
+}
+
+// UpsertUser creates new or updates existing one or more Users in store
+//
+// This function is auto-generated
+func UpsertUser(ctx context.Context, s Users, rr ...*systemType.User) error {
+ return s.UpsertUser(ctx, rr...)
+}
+
+// DeleteUser deletes one or more Users from store
+//
+// This function is auto-generated
+func DeleteUser(ctx context.Context, s Users, rr ...*systemType.User) error {
+ return s.DeleteUser(ctx, rr...)
+}
+
+// DeleteUserByID deletes one or more Users from store
+//
+// This function is auto-generated
+func DeleteUserByID(ctx context.Context, s Users, id uint64) error {
+ return s.DeleteUserByID(ctx, id)
+}
+
+// TruncateUsers Deletes all Users from store
+//
+// This function is auto-generated
+func TruncateUsers(ctx context.Context, s Users) error {
+ return s.TruncateUsers(ctx)
+}
+
+// LookupUserByID searches for user by ID
+//
+// It returns user even if deleted or suspended
+//
+// This function is auto-generated
+func LookupUserByID(ctx context.Context, s Users, id uint64) (*systemType.User, error) {
+ return s.LookupUserByID(ctx, id)
+}
+
+// LookupUserByEmail searches for user by email
+//
+// It returns only valid user (not deleted, not suspended)
+//
+// This function is auto-generated
+func LookupUserByEmail(ctx context.Context, s Users, email string) (*systemType.User, error) {
+ return s.LookupUserByEmail(ctx, email)
+}
+
+// LookupUserByHandle searches for user by handle
+//
+// It returns only valid user (not deleted, not suspended)
+//
+// This function is auto-generated
+func LookupUserByHandle(ctx context.Context, s Users, handle string) (*systemType.User, error) {
+ return s.LookupUserByHandle(ctx, handle)
+}
+
+// LookupUserByUsername searches for user by username
+//
+// It returns only valid user (not deleted, not suspended)
+//
+// This function is auto-generated
+func LookupUserByUsername(ctx context.Context, s Users, username string) (*systemType.User, error) {
+ return s.LookupUserByUsername(ctx, username)
+}
+
+// CountUsers
+//
+// This function is auto-generated
+func CountUsers(ctx context.Context, s Users, u systemType.UserFilter) (uint, error) {
+ return s.CountUsers(ctx, u)
+}
+
+// UserMetrics
+//
+// This function is auto-generated
+func UserMetrics(ctx context.Context, s Users) (*systemType.UserMetrics, error) {
+ return s.UserMetrics(ctx)
+}
diff --git a/store/interfaces.go b/store/interfaces.go
deleted file mode 100644
index c2919ab6a..000000000
--- a/store/interfaces.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package store
-
-import (
- "context"
- "go.uber.org/zap"
-)
-
-type (
- // Storer interface combines interfaces of all supported store interfaces
- Storer interface {
- // SetLogger sets new logging facility
- //
- // Store facility should fallback to logger.Default when no logging facility is set
- //
- // Intentionally closely coupled with Zap logger since this is not some public lib
- // and it's highly unlikely we'll support different/multiple logging "backend"
- SetLogger(*zap.Logger)
-
- // Tx is a transaction handler
- Tx(context.Context, func(context.Context, Storer) error) error
-
- // All generated store interfaces
- storerGenerated
- }
-)
diff --git a/store/labels.gen.go b/store/labels.gen.go
deleted file mode 100644
index 863f010fa..000000000
--- a/store/labels.gen.go
+++ /dev/null
@@ -1,84 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/labels.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/pkg/label/types"
-)
-
-type (
- Labels interface {
- SearchLabels(ctx context.Context, f types.LabelFilter) (types.LabelSet, types.LabelFilter, error)
- LookupLabelByKindResourceIDName(ctx context.Context, kind string, resource_id uint64, name string) (*types.Label, error)
-
- CreateLabel(ctx context.Context, rr ...*types.Label) error
-
- UpdateLabel(ctx context.Context, rr ...*types.Label) error
-
- UpsertLabel(ctx context.Context, rr ...*types.Label) error
-
- DeleteLabel(ctx context.Context, rr ...*types.Label) error
- DeleteLabelByKindResourceIDName(ctx context.Context, kind string, resourceID uint64, name string) error
-
- TruncateLabels(ctx context.Context) error
-
- // Additional custom functions
-
- // DeleteExtraLabels (custom function)
- DeleteExtraLabels(ctx context.Context, _kind string, _resourceID uint64, _names ...string) error
- }
-)
-
-var _ *types.Label
-var _ context.Context
-
-// SearchLabels returns all matching Labels from store
-func SearchLabels(ctx context.Context, s Labels, f types.LabelFilter) (types.LabelSet, types.LabelFilter, error) {
- return s.SearchLabels(ctx, f)
-}
-
-// LookupLabelByKindResourceIDName Label lookup by kind, resource, name
-func LookupLabelByKindResourceIDName(ctx context.Context, s Labels, kind string, resource_id uint64, name string) (*types.Label, error) {
- return s.LookupLabelByKindResourceIDName(ctx, kind, resource_id, name)
-}
-
-// CreateLabel creates one or more Labels in store
-func CreateLabel(ctx context.Context, s Labels, rr ...*types.Label) error {
- return s.CreateLabel(ctx, rr...)
-}
-
-// UpdateLabel updates one or more (existing) Labels in store
-func UpdateLabel(ctx context.Context, s Labels, rr ...*types.Label) error {
- return s.UpdateLabel(ctx, rr...)
-}
-
-// UpsertLabel creates new or updates existing one or more Labels in store
-func UpsertLabel(ctx context.Context, s Labels, rr ...*types.Label) error {
- return s.UpsertLabel(ctx, rr...)
-}
-
-// DeleteLabel Deletes one or more Labels from store
-func DeleteLabel(ctx context.Context, s Labels, rr ...*types.Label) error {
- return s.DeleteLabel(ctx, rr...)
-}
-
-// DeleteLabelByKindResourceIDName Deletes Label from store
-func DeleteLabelByKindResourceIDName(ctx context.Context, s Labels, kind string, resourceID uint64, name string) error {
- return s.DeleteLabelByKindResourceIDName(ctx, kind, resourceID, name)
-}
-
-// TruncateLabels Deletes all Labels from store
-func TruncateLabels(ctx context.Context, s Labels) error {
- return s.TruncateLabels(ctx)
-}
-
-func DeleteExtraLabels(ctx context.Context, s Labels, _kind string, _resourceID uint64, _names ...string) error {
- return s.DeleteExtraLabels(ctx, _kind, _resourceID, _names...)
-}
diff --git a/store/labels.yaml b/store/labels.yaml
deleted file mode 100644
index 3bc398ac9..000000000
--- a/store/labels.yaml
+++ /dev/null
@@ -1,39 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/pkg/label/types
-
-types:
- type: types.Label
-
-fields:
- - { field: Kind, isPrimaryKey: true }
- - { field: ResourceID, isPrimaryKey: true }
- - { field: Name, isPrimaryKey: true, lookupFilterPreprocessor: lower }
- - { field: Value }
-
-lookups:
- - fields: [ Kind, ResourceID, Name ]
- uniqueConstraintCheck: true
- description: |-
- Label lookup by kind, resource, name
-
-functions:
- - name: DeleteExtraLabels
- arguments:
- - { name: kind, type: string }
- - { name: resourceID, type: uint64 }
- - { name: names, type: ...string }
- return: [ error ]
-
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
-
-upsert:
- enable: true
-
-rdbms:
- alias: lbl
- table: labels
- customFilterConverter: true
diff --git a/store/mysql/builder.go b/store/mysql/builder.go
deleted file mode 100644
index 6c1943b4d..000000000
--- a/store/mysql/builder.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package mysql
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-// UpsertBuilder combines insert and update builder into upsert (INSERT ... ON CONFLICT UPDATE ...)
-//
-// It accepts name of the table we're inserting to, payload with values that should be inserted and list of
-// columns that represent unique keys
-//
-// This is MySQL eddition that differs a bit from the standard SQL
-// https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
-func UpsertBuilder(cfg *rdbms.Config, table string, payload store.Payload, columns ...string) (squirrel.InsertBuilder, error) {
- var (
- updatePayload = store.Payload{}
-
- // where to cutoff the update query
- updateCutoff = len("UPDATE " + table + " SET ")
- )
-
- for k, v := range payload {
- updatePayload[k] = v
- }
-
- for _, c := range columns {
- if _, has := updatePayload[c]; has {
- delete(updatePayload, c)
- }
- }
-
- sql, args, err := squirrel.
- Update(table).
- PlaceholderFormat(cfg.PlaceholderFormat).
- SetMap(updatePayload).
- ToSql()
-
- if err != nil {
- return squirrel.InsertBuilder{}, err
- }
-
- return squirrel.
- Insert(table).
- PlaceholderFormat(cfg.PlaceholderFormat).
- SetMap(payload).
- Suffix("ON DUPLICATE KEY UPDATE "+sql[updateCutoff:], args...), nil
-}
diff --git a/store/mysql/builder_test.go b/store/mysql/builder_test.go
deleted file mode 100644
index b2afe5247..000000000
--- a/store/mysql/builder_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package mysql
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms"
- "github.com/stretchr/testify/require"
- "testing"
-)
-
-func TestBuilder(t *testing.T) {
- var (
- req = require.New(t)
- cfg = &rdbms.Config{PlaceholderFormat: squirrel.Question}
- )
-
- upsert, err := UpsertBuilder(cfg, "tbl", store.Payload{"c1": "v1", "c2": "v2"}, "c1")
- req.NoError(err)
- sql, args, err := upsert.ToSql()
- req.NoError(err)
- req.Contains(sql, "ON DUPLICATE KEY UPDATE SET")
- req.Contains(sql, "INSERT INTO tbl")
- req.Equal([]interface{}{"v1", "v2", "v2"}, args)
-}
diff --git a/store/mysql/encoder.go b/store/mysql/encoder.go
deleted file mode 100644
index 562ae0c35..000000000
--- a/store/mysql/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package mysql
-
-import "github.com/cortezaproject/corteza-server/pkg/ql"
-
-type (
- // QueryEncoder provides query parts encoding rules for MySQL
- // see ql.QueryEncoder for mor info
- QueryEncoder struct{}
-)
-
-var _ ql.Encoder = &QueryEncoder{}
-
-func (QueryEncoder) CaseInsensitiveLike(neg bool) string {
- if neg {
- return "COLLATE utf8_unicode_ci NOT LIKE"
- } else {
- return "COLLATE utf8_unicode_ci LIKE"
- }
-}
diff --git a/store/mysql/sql_order.go b/store/mysql/sql_order.go
deleted file mode 100644
index eb17b453c..000000000
--- a/store/mysql/sql_order.go
+++ /dev/null
@@ -1,11 +0,0 @@
-package mysql
-
-import "fmt"
-
-func SqlSortHandler(exp string, desc bool) string {
- if desc {
- return fmt.Sprintf("%s DESC", exp)
- } else {
- return fmt.Sprintf("%s ASC", exp)
- }
-}
diff --git a/store/mysql/sql_typecasters.go b/store/mysql/sql_typecasters.go
deleted file mode 100644
index ae8e9566f..000000000
--- a/store/mysql/sql_typecasters.go
+++ /dev/null
@@ -1,49 +0,0 @@
-package mysql
-
-import (
- "fmt"
-
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-// fieldToColumnTypeCaster handles special ComposeModule field query representations
-// @todo Not as elegant as it should be but it'll do the trick until the #2 store iteration
-//
-// Return parameters:
-// * full cast: query column + datatype cast
-// * field cast tpl: fmt template to get query column
-// * type cast tpl: fmt template to cast the compared to value
-func fieldToColumnTypeCaster(field rdbms.ModuleFieldTypeDetector, ident string) (string, string, string, error) {
- fcp := "rv_%s.value"
- fcpRef := "rv_%s.ref"
-
- switch true {
- case field.IsBoolean():
- tcp := "(%s NOT IN ('', '0', 'false', 'f', 'FALSE', 'F', false))"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsNumeric():
- tcp := "CAST(%s AS DOUBLE)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsDateTime():
- tcp := "CAST(%s AS DATETIME)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsDateOnly():
- tcp := "CAST(%s AS DATE)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsTimeOnly():
- tcp := "CAST(%s AS TIME)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsRef():
- tcp := "%s"
- fc := fmt.Sprintf(fcpRef, ident)
- return fmt.Sprintf(tcp, fc), fcpRef, tcp, nil
- }
- tcp := "%s"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
-}
diff --git a/store/payload.go b/store/payload.go
deleted file mode 100644
index 4e78b8e6e..000000000
--- a/store/payload.go
+++ /dev/null
@@ -1,55 +0,0 @@
-package store
-
-import (
- "github.com/cortezaproject/corteza-server/pkg/slice"
-)
-
-type (
- // Payload servers as a generic interface between incoming structs scheduled
- // for update or insertion and the db layer
- Payload map[string]interface{}
-)
-
-// Only returns new payload with subset fields (if empty slice is send, it returns entire payload)
-func (p Payload) Only(ff ...string) Payload {
- if len(ff) == 0 {
- return p
- }
-
- o := Payload{}
- for _, k := range ff {
- if v, has := p[k]; has {
- o[k] = v
- }
- } //
-
- return o
-}
-
-// Skip returns new payload with subset fields (if empty slice is send, it returns entire payload)
-func (p Payload) Skip(ff ...string) Payload {
- if len(ff) == 0 {
- return p
- }
-
- m := slice.ToStringBoolMap(ff)
-
- o := Payload{}
- for k, v := range p {
- if !m[k] {
- o[k] = v
- }
- }
-
- return o
-}
-
-// Alias adds alias (.) to all keys
-func (p Payload) Alias(alias string) Payload {
- o := Payload{}
- for k, v := range p {
- o[alias+"."+k] = v
- }
-
- return o
-}
diff --git a/store/payload_test.go b/store/payload_test.go
deleted file mode 100644
index b4cf70f68..000000000
--- a/store/payload_test.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package store
-
-import (
- "github.com/stretchr/testify/assert"
- "testing"
-)
-
-func TestPayload_Only(t *testing.T) {
- a := assert.New(t)
-
- p := Payload{"foo": 1, "bar": 1}.Only("foo")
- a.Contains(p, "foo")
- a.NotContains(p, "bar")
-}
-
-func TestPayload_Skip(t *testing.T) {
- a := assert.New(t)
-
- p := Payload{"foo": 1, "bar": 1}.Skip("bar")
- a.Contains(p, "foo")
- a.NotContains(p, "bar")
-}
diff --git a/store/postgres/encoder.go b/store/postgres/encoder.go
deleted file mode 100644
index b3d37c346..000000000
--- a/store/postgres/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package postgres
-
-import "github.com/cortezaproject/corteza-server/pkg/ql"
-
-type (
- // QueryEncoder provides query parts encoding rules for Postgres
- // see ql.QueryEncoder for mor info
- QueryEncoder struct{}
-)
-
-var _ ql.Encoder = &QueryEncoder{}
-
-func (QueryEncoder) CaseInsensitiveLike(neg bool) string {
- if neg {
- return "NOT ILIKE"
- } else {
- return "ILIKE"
- }
-}
diff --git a/store/postgres/sql_functions.go b/store/postgres/sql_functions.go
deleted file mode 100644
index 472840f04..000000000
--- a/store/postgres/sql_functions.go
+++ /dev/null
@@ -1,86 +0,0 @@
-package postgres
-
-import (
- "fmt"
- "strings"
-
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "github.com/cortezaproject/corteza-server/pkg/qlng"
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-var (
- sqlExprRegistry = map[string]rdbms.HandlerSig{
- // functions
- // - filtering
- "quarter": makeGenericExtrFncHandler("QUARTER"),
- "year": makeGenericExtrFncHandler("YEAR"),
- "month": makeGenericExtrFncHandler("MONTH"),
- "date": makeGenericExtrFncHandler("DAY"),
- }
-)
-
-func makeGenericExtrFncHandler(extr string) rdbms.HandlerSig {
- return func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("EXTRACT(%s FROM %s)", extr, aa[0].S)
- args = aa[0].Args
- return
- }
-}
-
-func sqlASTFormatter(n *qlng.ASTNode) rdbms.HandlerSig {
- return sqlExprRegistry[n.Ref]
-}
-
-func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) {
- switch strings.ToUpper(f.Name) {
- case "QUARTER", "YEAR":
- return ql.MakeFormattedNode(fmt.Sprintf("EXTRACT(%s FROM %%s::date)", f.Name), f.Arguments...), nil
- case "DATE_FORMAT":
- return ql.MakeReplacedFormattedNode("TO_CHAR(%s::TIMESTAMPTZ, %s::TEXT)", translateDateFormatParams, f.Arguments...), nil
- case "TIMESTAMP":
- return ql.MakeFormattedNode("TIMESTAMPTZ(%s::TIMESTAMPTZ)", f.Arguments...), nil
- case "DATE":
- return ql.MakeFormattedNode("%s::DATE", f.Arguments...), nil
- case "TIME":
- return ql.MakeFormattedNode("DATE_TRUNC('second', %s::TIME)::TIME", f.Arguments...), nil
- case "DATE_ADD", "DATE_SUB", "STD":
- return nil, fmt.Errorf("%q function is currently unsupported in PostgreSQL store backend", f.Name)
- }
-
- return f, nil
-}
-
-func translateDateFormatParams(format string) string {
- return strings.NewReplacer(
- `%a`, `Dy`,
- `%b`, `Mon`,
- `%c`, `FMMM`,
- `%d`, `DD`,
- `%e`, `FMDD`,
- `%f`, `US`,
- `%H`, `HH24`,
- `%h`, `HH12`,
- `%I`, `HH12`,
- `%i`, `MI`,
- `%j`, `DDD`,
- `%k`, `FMHH24`,
- `%l`, `FMHH12`,
- `%M`, `FMMonth`,
- `%m`, `MM`,
- `%p`, `AM`,
- `%r`, `HH12:MI:SS AM`,
- `%S`, `SS`,
- `%s`, `SS`,
- `%T`, `HH24:MI:SS`,
- `%W`, `FMDay`,
- `%Y`, `YYYY`,
- `%y`, `YY`,
- `%%`, `%`,
- ).Replace(format)
-}
diff --git a/store/postgres/sql_typecasters.go b/store/postgres/sql_typecasters.go
deleted file mode 100644
index c8f7a419f..000000000
--- a/store/postgres/sql_typecasters.go
+++ /dev/null
@@ -1,50 +0,0 @@
-package postgres
-
-import (
- "fmt"
-
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-// fieldToColumnTypeCaster handles special ComposeModule field query representations
-// @todo Not as elegant as it should be but it'll do the trick until the #2 store iteration
-//
-// Return parameters:
-// * full cast: query column + datatype cast
-// * field cast tpl: fmt template to get query column
-// * type cast tpl: fmt template to cast the compared to value
-func fieldToColumnTypeCaster(field rdbms.ModuleFieldTypeDetector, ident string) (string, string, string, error) {
- fcp := "rv_%s.value"
- fcpRef := "rv_%s.ref"
-
- switch true {
- case field.IsBoolean():
- tcp := "%s NOT IN ('', '0', 'false', 'f', 'FALSE', 'F')"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsNumeric():
- tcp := "CAST('0' || %s AS NUMERIC)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsDateTime():
- tcp := "to_timestamp(NULLIF(%s, ''),'YYYY-MM-DD\"T\"HH24:MI:SS\"Z\"') "
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsDateOnly():
- tcp := "CAST(NULLIF(%s, '') AS DATE)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsTimeOnly():
- tcp := "CAST(NULLIF(%s, '') AS TIME)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsRef():
- tcp := "%s"
- fc := fmt.Sprintf(fcpRef, ident)
- return fmt.Sprintf(tcp, fc), fcpRef, tcp, nil
- }
-
- tcp := "%s"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
-}
diff --git a/store/preprocessors.go b/store/preprocessors.go
deleted file mode 100644
index bc4eb1bd8..000000000
--- a/store/preprocessors.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package store
-
-import (
- "fmt"
- "strings"
-)
-
-// PreprocessValue value preprocessor logic to modify input value before using it in condition filters and other logic
-//
-// We intentionally panic in case of an error here; misuse can only happen with in case of misconfiguration.
-func PreprocessValue(val interface{}, p string) interface{} {
- switch p {
- case "":
- return val
- case "lower":
- if str, ok := val.(string); ok {
- return strings.ToLower(str)
- }
- panic(fmt.Sprintf("preprocessor %q not compatible with type %T (value: %v)", p, val, val))
-
- default:
- panic(fmt.Sprintf("unknown preprocessor %q used for value %v", p, val))
- }
-}
diff --git a/store/queue.gen.go b/store/queue.gen.go
deleted file mode 100644
index ed6c6f3c1..000000000
--- a/store/queue.gen.go
+++ /dev/null
@@ -1,81 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/queue.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Queues interface {
- SearchQueues(ctx context.Context, f types.QueueFilter) (types.QueueSet, types.QueueFilter, error)
- LookupQueueByID(ctx context.Context, id uint64) (*types.Queue, error)
- LookupQueueByQueue(ctx context.Context, queue string) (*types.Queue, error)
-
- CreateQueue(ctx context.Context, rr ...*types.Queue) error
-
- UpdateQueue(ctx context.Context, rr ...*types.Queue) error
-
- UpsertQueue(ctx context.Context, rr ...*types.Queue) error
-
- DeleteQueue(ctx context.Context, rr ...*types.Queue) error
- DeleteQueueByID(ctx context.Context, ID uint64) error
-
- TruncateQueues(ctx context.Context) error
- }
-)
-
-var _ *types.Queue
-var _ context.Context
-
-// SearchQueues returns all matching Queues from store
-func SearchQueues(ctx context.Context, s Queues, f types.QueueFilter) (types.QueueSet, types.QueueFilter, error) {
- return s.SearchQueues(ctx, f)
-}
-
-// LookupQueueByID searches for queue by ID
-func LookupQueueByID(ctx context.Context, s Queues, id uint64) (*types.Queue, error) {
- return s.LookupQueueByID(ctx, id)
-}
-
-// LookupQueueByQueue searches for queue by queue name
-func LookupQueueByQueue(ctx context.Context, s Queues, queue string) (*types.Queue, error) {
- return s.LookupQueueByQueue(ctx, queue)
-}
-
-// CreateQueue creates one or more Queues in store
-func CreateQueue(ctx context.Context, s Queues, rr ...*types.Queue) error {
- return s.CreateQueue(ctx, rr...)
-}
-
-// UpdateQueue updates one or more (existing) Queues in store
-func UpdateQueue(ctx context.Context, s Queues, rr ...*types.Queue) error {
- return s.UpdateQueue(ctx, rr...)
-}
-
-// UpsertQueue creates new or updates existing one or more Queues in store
-func UpsertQueue(ctx context.Context, s Queues, rr ...*types.Queue) error {
- return s.UpsertQueue(ctx, rr...)
-}
-
-// DeleteQueue Deletes one or more Queues from store
-func DeleteQueue(ctx context.Context, s Queues, rr ...*types.Queue) error {
- return s.DeleteQueue(ctx, rr...)
-}
-
-// DeleteQueueByID Deletes Queue from store
-func DeleteQueueByID(ctx context.Context, s Queues, ID uint64) error {
- return s.DeleteQueueByID(ctx, ID)
-}
-
-// TruncateQueues Deletes all Queues from store
-func TruncateQueues(ctx context.Context, s Queues) error {
- return s.TruncateQueues(ctx)
-}
diff --git a/store/queue.yaml b/store/queue.yaml
deleted file mode 100644
index 20f7a096a..000000000
--- a/store/queue.yaml
+++ /dev/null
@@ -1,32 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Consumer }
- - { field: Queue, sortable: true }
- - { field: Meta, type: "json.Text" }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for queue by ID
- - fields: [ Queue ]
- description: |-
- searches for queue by queue name
-
-rdbms:
- alias: mqs
- table: queue_settings
- customFilterConverter: true
-
-search:
- enablePaging: true
- enableSorting: false
- enableFilterCheckFunction: false
diff --git a/store/queue_message.gen.go b/store/queue_message.gen.go
deleted file mode 100644
index 6a61c4dcc..000000000
--- a/store/queue_message.gen.go
+++ /dev/null
@@ -1,62 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/queue_message.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- QueueMessages interface {
- SearchQueueMessages(ctx context.Context, f types.QueueMessageFilter) (types.QueueMessageSet, types.QueueMessageFilter, error)
-
- CreateQueueMessage(ctx context.Context, rr ...*types.QueueMessage) error
-
- UpdateQueueMessage(ctx context.Context, rr ...*types.QueueMessage) error
-
- DeleteQueueMessage(ctx context.Context, rr ...*types.QueueMessage) error
- DeleteQueueMessageByID(ctx context.Context, ID uint64) error
-
- TruncateQueueMessages(ctx context.Context) error
- }
-)
-
-var _ *types.QueueMessage
-var _ context.Context
-
-// SearchQueueMessages returns all matching QueueMessages from store
-func SearchQueueMessages(ctx context.Context, s QueueMessages, f types.QueueMessageFilter) (types.QueueMessageSet, types.QueueMessageFilter, error) {
- return s.SearchQueueMessages(ctx, f)
-}
-
-// CreateQueueMessage creates one or more QueueMessages in store
-func CreateQueueMessage(ctx context.Context, s QueueMessages, rr ...*types.QueueMessage) error {
- return s.CreateQueueMessage(ctx, rr...)
-}
-
-// UpdateQueueMessage updates one or more (existing) QueueMessages in store
-func UpdateQueueMessage(ctx context.Context, s QueueMessages, rr ...*types.QueueMessage) error {
- return s.UpdateQueueMessage(ctx, rr...)
-}
-
-// DeleteQueueMessage Deletes one or more QueueMessages from store
-func DeleteQueueMessage(ctx context.Context, s QueueMessages, rr ...*types.QueueMessage) error {
- return s.DeleteQueueMessage(ctx, rr...)
-}
-
-// DeleteQueueMessageByID Deletes QueueMessage from store
-func DeleteQueueMessageByID(ctx context.Context, s QueueMessages, ID uint64) error {
- return s.DeleteQueueMessageByID(ctx, ID)
-}
-
-// TruncateQueueMessages Deletes all QueueMessages from store
-func TruncateQueueMessages(ctx context.Context, s QueueMessages) error {
- return s.TruncateQueueMessages(ctx)
-}
diff --git a/store/queue_message.yaml b/store/queue_message.yaml
deleted file mode 100644
index 9be5c89ff..000000000
--- a/store/queue_message.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID, sortable: false }
- - { field: Queue }
- - { field: Payload }
- - { field: Processed, type: "time.Time" }
- - { field: Created, type: "time.Time" }
-
-rdbms:
- alias: mqm
- table: queue_messages
- customFilterConverter: true
-
-search:
- enablePaging: true
- enableFilterCheckFunction: false
-
-upsert:
- enable: false
diff --git a/store/rbac_rules.gen.go b/store/rbac_rules.gen.go
deleted file mode 100644
index 2b8cbb81e..000000000
--- a/store/rbac_rules.gen.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/rbac_rules.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/pkg/rbac"
-)
-
-type (
- RbacRules interface {
- SearchRbacRules(ctx context.Context, f rbac.RuleFilter) (rbac.RuleSet, rbac.RuleFilter, error)
-
- CreateRbacRule(ctx context.Context, rr ...*rbac.Rule) error
-
- UpdateRbacRule(ctx context.Context, rr ...*rbac.Rule) error
-
- UpsertRbacRule(ctx context.Context, rr ...*rbac.Rule) error
-
- DeleteRbacRule(ctx context.Context, rr ...*rbac.Rule) error
- DeleteRbacRuleByRoleIDResourceOperation(ctx context.Context, roleID uint64, resource string, operation string) error
-
- TruncateRbacRules(ctx context.Context) error
-
- // Additional custom functions
-
- // TransferRbacRules (custom function)
- TransferRbacRules(ctx context.Context, _srcRole uint64, _dstRole uint64) error
- }
-)
-
-var _ *rbac.Rule
-var _ context.Context
-
-// SearchRbacRules returns all matching RbacRules from store
-func SearchRbacRules(ctx context.Context, s RbacRules, f rbac.RuleFilter) (rbac.RuleSet, rbac.RuleFilter, error) {
- return s.SearchRbacRules(ctx, f)
-}
-
-// CreateRbacRule creates one or more RbacRules in store
-func CreateRbacRule(ctx context.Context, s RbacRules, rr ...*rbac.Rule) error {
- return s.CreateRbacRule(ctx, rr...)
-}
-
-// UpdateRbacRule updates one or more (existing) RbacRules in store
-func UpdateRbacRule(ctx context.Context, s RbacRules, rr ...*rbac.Rule) error {
- return s.UpdateRbacRule(ctx, rr...)
-}
-
-// UpsertRbacRule creates new or updates existing one or more RbacRules in store
-func UpsertRbacRule(ctx context.Context, s RbacRules, rr ...*rbac.Rule) error {
- return s.UpsertRbacRule(ctx, rr...)
-}
-
-// DeleteRbacRule Deletes one or more RbacRules from store
-func DeleteRbacRule(ctx context.Context, s RbacRules, rr ...*rbac.Rule) error {
- return s.DeleteRbacRule(ctx, rr...)
-}
-
-// DeleteRbacRuleByRoleIDResourceOperation Deletes RbacRule from store
-func DeleteRbacRuleByRoleIDResourceOperation(ctx context.Context, s RbacRules, roleID uint64, resource string, operation string) error {
- return s.DeleteRbacRuleByRoleIDResourceOperation(ctx, roleID, resource, operation)
-}
-
-// TruncateRbacRules Deletes all RbacRules from store
-func TruncateRbacRules(ctx context.Context, s RbacRules) error {
- return s.TruncateRbacRules(ctx)
-}
-
-func TransferRbacRules(ctx context.Context, s RbacRules, _srcRole uint64, _dstRole uint64) error {
- return s.TransferRbacRules(ctx, _srcRole, _dstRole)
-}
diff --git a/store/rbac_rules.yaml b/store/rbac_rules.yaml
deleted file mode 100644
index 41e4f7ca8..000000000
--- a/store/rbac_rules.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/pkg/rbac
-
-types:
- type: rbac.Rule
-
-fields:
- - { field: RoleID, isPrimaryKey: true }
- - { field: Resource, isPrimaryKey: true }
- - { field: Operation, isPrimaryKey: true }
- - { field: Access }
-
-functions:
- - name: TransferRbacRules
- return: [ error ]
- arguments:
- - { name: srcRole, type: uint64 }
- - { name: dstRole, type: uint64 }
-
-rdbms:
- alias: rls
- table: rbac_rules
-
-search:
- enablePaging: false
- enableSorting: false
- enableFilterCheckFunction: false
-
-upsert:
- enable: true
-
diff --git a/store/rdbms/actionlog.gen.go b/store/rdbms/actionlog.gen.go
deleted file mode 100644
index 2a4cb4c01..000000000
--- a/store/rdbms/actionlog.gen.go
+++ /dev/null
@@ -1,240 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/actionlog.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/actionlog"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchActionlogs returns all matching rows
-//
-// This function calls convertActionlogFilter with the given
-// actionlog.Filter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchActionlogs(ctx context.Context, f actionlog.Filter) (actionlog.ActionSet, actionlog.Filter, error) {
- var (
- err error
- set []*actionlog.Action
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertActionlogFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryActionlogs(ctx, q, nil)
- return err
- }()
-}
-
-// QueryActionlogs queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryActionlogs(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*actionlog.Action) (bool, error),
-) ([]*actionlog.Action, error) {
- var (
- tmp = make([]*actionlog.Action, 0, DefaultSliceCapacity)
- set = make([]*actionlog.Action, 0, DefaultSliceCapacity)
- res *actionlog.Action
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalActionlogRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// CreateActionlog creates one or more rows in actionlog table
-func (s Store) CreateActionlog(ctx context.Context, rr ...*actionlog.Action) (err error) {
- for _, res := range rr {
- err = s.checkActionlogConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateActionlogs(ctx, s.internalActionlogEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// TruncateActionlogs Deletes all rows from the actionlog table
-func (s Store) TruncateActionlogs(ctx context.Context) error {
- return s.Truncate(ctx, s.actionlogTable())
-}
-
-// execLookupActionlog prepares Actionlog query and executes it,
-// returning actionlog.Action (or error)
-func (s Store) execLookupActionlog(ctx context.Context, cnd squirrel.Sqlizer) (res *actionlog.Action, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.actionlogsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalActionlogRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateActionlogs updates all matched (by cnd) rows in actionlog with given data
-func (s Store) execCreateActionlogs(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.actionlogTable()).SetMap(payload))
-}
-
-func (s Store) internalActionlogRowScanner(row rowScanner) (res *actionlog.Action, err error) {
- res = &actionlog.Action{}
-
- err = row.Scan(
- &res.ID,
- &res.Timestamp,
- &res.RequestOrigin,
- &res.RequestID,
- &res.ActorIPAddr,
- &res.ActorID,
- &res.Resource,
- &res.Action,
- &res.Error,
- &res.Severity,
- &res.Description,
- &res.Meta,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan actionlog db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryActionlogs returns squirrel.SelectBuilder with set table and all columns
-func (s Store) actionlogsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.actionlogTable("alg"), s.actionlogColumns("alg")...)
-}
-
-// actionlogTable name of the db table
-func (Store) actionlogTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "actionlog" + alias
-}
-
-// ActionlogColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) actionlogColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "ts",
- alias + "request_origin",
- alias + "request_id",
- alias + "actor_ip_addr",
- alias + "actor_id",
- alias + "resource",
- alias + "action",
- alias + "error",
- alias + "severity",
- alias + "description",
- alias + "meta",
- }
-}
-
-// {true true false false false false}
-
-// internalActionlogEncoder encodes fields from actionlog.Action to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeActionlog
-// func when rdbms.customEncoder=true
-func (s Store) internalActionlogEncoder(res *actionlog.Action) store.Payload {
- return s.encodeActionlog(res)
-}
-
-// checkActionlogConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkActionlogConstraints(ctx context.Context, res *actionlog.Action) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/actionlog.go b/store/rdbms/actionlog.go
deleted file mode 100644
index 01caf12a6..000000000
--- a/store/rdbms/actionlog.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package rdbms
-
-import (
- "encoding/json"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/actionlog"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-func (s Store) convertActionlogFilter(f actionlog.Filter) (query squirrel.SelectBuilder, err error) {
- query = s.actionlogsSelectBuilder()
-
- // Always sort by ID descending
- query = query.OrderBy("id DESC")
-
- if f.BeforeActionID > 0 {
- query = query.Where(squirrel.Lt{"id": f.BeforeActionID})
- }
-
- if f.FromTimestamp != nil {
- query = query.Where(squirrel.GtOrEq{"ts": f.FromTimestamp})
- }
-
- if f.ToTimestamp != nil {
- query = query.Where(squirrel.LtOrEq{"ts": f.ToTimestamp})
- }
-
- if len(f.ActorID) > 0 {
- query = query.Where(squirrel.Eq{"actor_id": f.ActorID})
- }
-
- if f.Origin != "" {
- query = query.Where(squirrel.Eq{"origin": f.Origin})
- }
-
- if f.Resource != "" {
- query = query.Where(squirrel.Eq{"resource": f.Resource})
- }
-
- if f.Action != "" {
- query = query.Where(squirrel.Eq{"action": f.Action})
- }
-
- if f.Limit == 0 || f.Limit > MaxLimit {
- f.Limit = MaxLimit
- }
-
- query = query.Limit(uint64(f.Limit))
-
- return
-}
-
-func (s Store) scanActionlogRow(row rowScanner, res *actionlog.Action) (err error) {
- var metaBuf json.RawMessage
-
- err = row.Scan(
- &res.ID,
- &res.Timestamp,
- &res.RequestOrigin,
- &res.RequestID,
- &res.ActorIPAddr,
- &res.ActorID,
- &res.Resource,
- &res.Action,
- &res.Error,
- &res.Severity,
- &res.Description,
- &metaBuf,
- )
-
- if err != nil {
- return err
- }
-
- // Ignoring unmarshal errors
- _ = json.Unmarshal(metaBuf, &res.Meta)
-
- return nil
-}
-
-func (s Store) encodeActionlog(res *actionlog.Action) store.Payload {
- // ActionlogEnc encodes fields from actionlog.Action to store.Payload (map)
- out := store.Payload{
- "id": res.ID,
- "ts": res.Timestamp,
- "request_origin": res.RequestOrigin,
- "request_id": res.RequestID,
- "actor_ip_addr": res.ActorIPAddr,
- "actor_id": res.ActorID,
- "resource": res.Resource,
- "action": res.Action,
- "error": res.Error,
- "severity": res.Severity,
- "description": res.Description,
- "meta": []byte("{}"),
- }
-
- if res.Meta != nil {
- out["meta"], _ = json.Marshal(res.Meta)
- }
-
- return out
-}
diff --git a/store/rdbms/apigw_filter.gen.go b/store/rdbms/apigw_filter.gen.go
deleted file mode 100644
index 972cc0774..000000000
--- a/store/rdbms/apigw_filter.gen.go
+++ /dev/null
@@ -1,574 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/apigw_filter.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchApigwFilters returns all matching rows
-//
-// This function calls convertApigwFilterFilter with the given
-// types.ApigwFilterFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchApigwFilters(ctx context.Context, f types.ApigwFilterFilter) (types.ApigwFilterSet, types.ApigwFilterFilter, error) {
- var (
- err error
- set []*types.ApigwFilter
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertApigwFilterFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableApigwFilterColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfApigwFilters(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfApigwFilters collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfApigwFilters(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.ApigwFilter) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.ApigwFilter, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.ApigwFilter
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.ApigwFilter, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryApigwFilters(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectApigwFilterCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectApigwFilterCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectApigwFilterCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryApigwFilters queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryApigwFilters(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ApigwFilter) (bool, error),
-) ([]*types.ApigwFilter, error) {
- var (
- tmp = make([]*types.ApigwFilter, 0, DefaultSliceCapacity)
- set = make([]*types.ApigwFilter, 0, DefaultSliceCapacity)
- res *types.ApigwFilter
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalApigwFilterRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupApigwFilterByID searches for filter by ID
-func (s Store) LookupApigwFilterByID(ctx context.Context, id uint64) (*types.ApigwFilter, error) {
- return s.execLookupApigwFilter(ctx, squirrel.Eq{
- s.preprocessColumn("af.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupApigwFilterByRoute searches for filter by route
-func (s Store) LookupApigwFilterByRoute(ctx context.Context, route string) (*types.ApigwFilter, error) {
- return s.execLookupApigwFilter(ctx, squirrel.Eq{
- s.preprocessColumn("af.rel_route", ""): store.PreprocessValue(route, ""),
- })
-}
-
-// CreateApigwFilter creates one or more rows in apigw_filters table
-func (s Store) CreateApigwFilter(ctx context.Context, rr ...*types.ApigwFilter) (err error) {
- for _, res := range rr {
- err = s.checkApigwFilterConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateApigwFilters(ctx, s.internalApigwFilterEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateApigwFilter updates one or more existing rows in apigw_filters
-func (s Store) UpdateApigwFilter(ctx context.Context, rr ...*types.ApigwFilter) error {
- return s.partialApigwFilterUpdate(ctx, nil, rr...)
-}
-
-// partialApigwFilterUpdate updates one or more existing rows in apigw_filters
-func (s Store) partialApigwFilterUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ApigwFilter) (err error) {
- for _, res := range rr {
- err = s.checkApigwFilterConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateApigwFilters(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("af.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalApigwFilterEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// DeleteApigwFilter Deletes one or more rows from apigw_filters table
-func (s Store) DeleteApigwFilter(ctx context.Context, rr ...*types.ApigwFilter) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteApigwFilters(ctx, squirrel.Eq{
- s.preprocessColumn("af.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteApigwFilterByID Deletes row from the apigw_filters table
-func (s Store) DeleteApigwFilterByID(ctx context.Context, ID uint64) error {
- return s.execDeleteApigwFilters(ctx, squirrel.Eq{
- s.preprocessColumn("af.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateApigwFilters Deletes all rows from the apigw_filters table
-func (s Store) TruncateApigwFilters(ctx context.Context) error {
- return s.Truncate(ctx, s.apigwFilterTable())
-}
-
-// execLookupApigwFilter prepares ApigwFilter query and executes it,
-// returning types.ApigwFilter (or error)
-func (s Store) execLookupApigwFilter(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ApigwFilter, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.apigwFiltersSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalApigwFilterRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateApigwFilters updates all matched (by cnd) rows in apigw_filters with given data
-func (s Store) execCreateApigwFilters(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.apigwFilterTable()).SetMap(payload))
-}
-
-// execUpdateApigwFilters updates all matched (by cnd) rows in apigw_filters with given data
-func (s Store) execUpdateApigwFilters(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.apigwFilterTable("af")).Where(cnd).SetMap(set))
-}
-
-// execDeleteApigwFilters Deletes all matched (by cnd) rows in apigw_filters with given data
-func (s Store) execDeleteApigwFilters(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.apigwFilterTable("af")).Where(cnd))
-}
-
-func (s Store) internalApigwFilterRowScanner(row rowScanner) (res *types.ApigwFilter, err error) {
- res = &types.ApigwFilter{}
-
- err = row.Scan(
- &res.ID,
- &res.Route,
- &res.Weight,
- &res.Kind,
- &res.Ref,
- &res.Enabled,
- &res.Params,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan apigwFilter db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryApigwFilters returns squirrel.SelectBuilder with set table and all columns
-func (s Store) apigwFiltersSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.apigwFilterTable("af"), s.apigwFilterColumns("af")...)
-}
-
-// apigwFilterTable name of the db table
-func (Store) apigwFilterTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "apigw_filters" + alias
-}
-
-// ApigwFilterColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) apigwFilterColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_route",
- alias + "weight",
- alias + "kind",
- alias + "ref",
- alias + "enabled",
- alias + "params",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableApigwFilterColumns returns all ApigwFilter columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableApigwFilterColumns() map[string]string {
- return map[string]string{
- "id": "id",
- }
-}
-
-// internalApigwFilterEncoder encodes fields from types.ApigwFilter to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeApigwFilter
-// func when rdbms.customEncoder=true
-func (s Store) internalApigwFilterEncoder(res *types.ApigwFilter) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_route": res.Route,
- "weight": res.Weight,
- "kind": res.Kind,
- "ref": res.Ref,
- "enabled": res.Enabled,
- "params": res.Params,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectApigwFilterCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectApigwFilterCursorValues(res *types.ApigwFilter, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkApigwFilterConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkApigwFilterConstraints(ctx context.Context, res *types.ApigwFilter) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/apigw_filter.go b/store/rdbms/apigw_filter.go
deleted file mode 100644
index ae6da5b6f..000000000
--- a/store/rdbms/apigw_filter.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertApigwFilterFilter(f types.ApigwFilterFilter) (query squirrel.SelectBuilder, err error) {
- query = s.apigwFiltersSelectBuilder()
-
- query = filter.StateCondition(query, "af.deleted_at", f.Deleted)
- query = filter.StateConditionNegBool(query, "af.enabled", f.Disabled)
-
- if f.RouteID > 0 {
- query = query.Where(squirrel.Eq{"af.rel_route": f.RouteID})
- }
-
- return
-}
diff --git a/store/rdbms/apigw_route.gen.go b/store/rdbms/apigw_route.gen.go
deleted file mode 100644
index a9287f25c..000000000
--- a/store/rdbms/apigw_route.gen.go
+++ /dev/null
@@ -1,590 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/apigw_route.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchApigwRoutes returns all matching rows
-//
-// This function calls convertApigwRouteFilter with the given
-// types.ApigwRouteFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchApigwRoutes(ctx context.Context, f types.ApigwRouteFilter) (types.ApigwRouteSet, types.ApigwRouteFilter, error) {
- var (
- err error
- set []*types.ApigwRoute
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertApigwRouteFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableApigwRouteColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfApigwRoutes(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfApigwRoutes collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfApigwRoutes(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.ApigwRoute) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.ApigwRoute, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.ApigwRoute
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.ApigwRoute, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryApigwRoutes(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectApigwRouteCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectApigwRouteCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectApigwRouteCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryApigwRoutes queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryApigwRoutes(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ApigwRoute) (bool, error),
-) ([]*types.ApigwRoute, error) {
- var (
- tmp = make([]*types.ApigwRoute, 0, DefaultSliceCapacity)
- set = make([]*types.ApigwRoute, 0, DefaultSliceCapacity)
- res *types.ApigwRoute
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalApigwRouteRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupApigwRouteByID searches for route by ID
-func (s Store) LookupApigwRouteByID(ctx context.Context, id uint64) (*types.ApigwRoute, error) {
- return s.execLookupApigwRoute(ctx, squirrel.Eq{
- s.preprocessColumn("ar.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupApigwRouteByEndpoint searches for route by endpoint
-func (s Store) LookupApigwRouteByEndpoint(ctx context.Context, endpoint string) (*types.ApigwRoute, error) {
- return s.execLookupApigwRoute(ctx, squirrel.Eq{
- s.preprocessColumn("ar.endpoint", ""): store.PreprocessValue(endpoint, ""),
- })
-}
-
-// CreateApigwRoute creates one or more rows in apigw_routes table
-func (s Store) CreateApigwRoute(ctx context.Context, rr ...*types.ApigwRoute) (err error) {
- for _, res := range rr {
- err = s.checkApigwRouteConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateApigwRoutes(ctx, s.internalApigwRouteEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateApigwRoute updates one or more existing rows in apigw_routes
-func (s Store) UpdateApigwRoute(ctx context.Context, rr ...*types.ApigwRoute) error {
- return s.partialApigwRouteUpdate(ctx, nil, rr...)
-}
-
-// partialApigwRouteUpdate updates one or more existing rows in apigw_routes
-func (s Store) partialApigwRouteUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ApigwRoute) (err error) {
- for _, res := range rr {
- err = s.checkApigwRouteConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateApigwRoutes(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("ar.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalApigwRouteEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// DeleteApigwRoute Deletes one or more rows from apigw_routes table
-func (s Store) DeleteApigwRoute(ctx context.Context, rr ...*types.ApigwRoute) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteApigwRoutes(ctx, squirrel.Eq{
- s.preprocessColumn("ar.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteApigwRouteByID Deletes row from the apigw_routes table
-func (s Store) DeleteApigwRouteByID(ctx context.Context, ID uint64) error {
- return s.execDeleteApigwRoutes(ctx, squirrel.Eq{
- s.preprocessColumn("ar.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateApigwRoutes Deletes all rows from the apigw_routes table
-func (s Store) TruncateApigwRoutes(ctx context.Context) error {
- return s.Truncate(ctx, s.apigwRouteTable())
-}
-
-// execLookupApigwRoute prepares ApigwRoute query and executes it,
-// returning types.ApigwRoute (or error)
-func (s Store) execLookupApigwRoute(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ApigwRoute, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.apigwRoutesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalApigwRouteRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateApigwRoutes updates all matched (by cnd) rows in apigw_routes with given data
-func (s Store) execCreateApigwRoutes(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.apigwRouteTable()).SetMap(payload))
-}
-
-// execUpdateApigwRoutes updates all matched (by cnd) rows in apigw_routes with given data
-func (s Store) execUpdateApigwRoutes(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.apigwRouteTable("ar")).Where(cnd).SetMap(set))
-}
-
-// execDeleteApigwRoutes Deletes all matched (by cnd) rows in apigw_routes with given data
-func (s Store) execDeleteApigwRoutes(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.apigwRouteTable("ar")).Where(cnd))
-}
-
-func (s Store) internalApigwRouteRowScanner(row rowScanner) (res *types.ApigwRoute, err error) {
- res = &types.ApigwRoute{}
-
- err = row.Scan(
- &res.ID,
- &res.Endpoint,
- &res.Method,
- &res.Enabled,
- &res.Group,
- &res.Meta,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan apigwRoute db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryApigwRoutes returns squirrel.SelectBuilder with set table and all columns
-func (s Store) apigwRoutesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.apigwRouteTable("ar"), s.apigwRouteColumns("ar")...)
-}
-
-// apigwRouteTable name of the db table
-func (Store) apigwRouteTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "apigw_routes" + alias
-}
-
-// ApigwRouteColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) apigwRouteColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "endpoint",
- alias + "method",
- alias + "enabled",
- alias + "rel_group",
- alias + "meta",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableApigwRouteColumns returns all ApigwRoute columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableApigwRouteColumns() map[string]string {
- return map[string]string{
- "id": "id", "endpoint": "endpoint", "method": "method", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalApigwRouteEncoder encodes fields from types.ApigwRoute to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeApigwRoute
-// func when rdbms.customEncoder=true
-func (s Store) internalApigwRouteEncoder(res *types.ApigwRoute) store.Payload {
- return store.Payload{
- "id": res.ID,
- "endpoint": res.Endpoint,
- "method": res.Method,
- "enabled": res.Enabled,
- "rel_group": res.Group,
- "meta": res.Meta,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectApigwRouteCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectApigwRouteCursorValues(res *types.ApigwRoute, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "endpoint":
- cursor.Set(c.Column, res.Endpoint, c.Descending)
-
- case "method":
- cursor.Set(c.Column, res.Method, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkApigwRouteConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkApigwRouteConstraints(ctx context.Context, res *types.ApigwRoute) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/apigw_route.go b/store/rdbms/apigw_route.go
deleted file mode 100644
index 3a860a4a4..000000000
--- a/store/rdbms/apigw_route.go
+++ /dev/null
@@ -1,15 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertApigwRouteFilter(f types.ApigwRouteFilter) (query squirrel.SelectBuilder, err error) {
- query = s.apigwRoutesSelectBuilder()
- query = filter.StateCondition(query, "ar.deleted_at", f.Deleted)
- query = filter.StateConditionNegBool(query, "ar.enabled", f.Disabled)
-
- return
-}
diff --git a/store/rdbms/applications.gen.go b/store/rdbms/applications.gen.go
deleted file mode 100644
index 8132b440a..000000000
--- a/store/rdbms/applications.gen.go
+++ /dev/null
@@ -1,609 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/applications.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchApplications returns all matching rows
-//
-// This function calls convertApplicationFilter with the given
-// types.ApplicationFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchApplications(ctx context.Context, f types.ApplicationFilter) (types.ApplicationSet, types.ApplicationFilter, error) {
- var (
- err error
- set []*types.Application
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertApplicationFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableApplicationColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfApplications(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfApplications collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfApplications(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Application) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Application, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Application
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Application, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryApplications(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectApplicationCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectApplicationCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectApplicationCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryApplications queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryApplications(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Application) (bool, error),
-) ([]*types.Application, error) {
- var (
- tmp = make([]*types.Application, 0, DefaultSliceCapacity)
- set = make([]*types.Application, 0, DefaultSliceCapacity)
- res *types.Application
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalApplicationRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupApplicationByID searches for application by ID
-//
-// It returns application even if deleted
-func (s Store) LookupApplicationByID(ctx context.Context, id uint64) (*types.Application, error) {
- return s.execLookupApplication(ctx, squirrel.Eq{
- s.preprocessColumn("app.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateApplication creates one or more rows in applications table
-func (s Store) CreateApplication(ctx context.Context, rr ...*types.Application) (err error) {
- for _, res := range rr {
- err = s.checkApplicationConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateApplications(ctx, s.internalApplicationEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateApplication updates one or more existing rows in applications
-func (s Store) UpdateApplication(ctx context.Context, rr ...*types.Application) error {
- return s.partialApplicationUpdate(ctx, nil, rr...)
-}
-
-// partialApplicationUpdate updates one or more existing rows in applications
-func (s Store) partialApplicationUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Application) (err error) {
- for _, res := range rr {
- err = s.checkApplicationConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateApplications(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("app.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalApplicationEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertApplication updates one or more existing rows in applications
-func (s Store) UpsertApplication(ctx context.Context, rr ...*types.Application) (err error) {
- for _, res := range rr {
- err = s.checkApplicationConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertApplications(ctx, s.internalApplicationEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteApplication Deletes one or more rows from applications table
-func (s Store) DeleteApplication(ctx context.Context, rr ...*types.Application) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteApplications(ctx, squirrel.Eq{
- s.preprocessColumn("app.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteApplicationByID Deletes row from the applications table
-func (s Store) DeleteApplicationByID(ctx context.Context, ID uint64) error {
- return s.execDeleteApplications(ctx, squirrel.Eq{
- s.preprocessColumn("app.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateApplications Deletes all rows from the applications table
-func (s Store) TruncateApplications(ctx context.Context) error {
- return s.Truncate(ctx, s.applicationTable())
-}
-
-// execLookupApplication prepares Application query and executes it,
-// returning types.Application (or error)
-func (s Store) execLookupApplication(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Application, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.applicationsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalApplicationRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateApplications updates all matched (by cnd) rows in applications with given data
-func (s Store) execCreateApplications(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.applicationTable()).SetMap(payload))
-}
-
-// execUpdateApplications updates all matched (by cnd) rows in applications with given data
-func (s Store) execUpdateApplications(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.applicationTable("app")).Where(cnd).SetMap(set))
-}
-
-// execUpsertApplications inserts new or updates matching (by-primary-key) rows in applications with given data
-func (s Store) execUpsertApplications(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.applicationTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteApplications Deletes all matched (by cnd) rows in applications with given data
-func (s Store) execDeleteApplications(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.applicationTable("app")).Where(cnd))
-}
-
-func (s Store) internalApplicationRowScanner(row rowScanner) (res *types.Application, err error) {
- res = &types.Application{}
-
- err = row.Scan(
- &res.ID,
- &res.Name,
- &res.OwnerID,
- &res.Enabled,
- &res.Weight,
- &res.Unify,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan application db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryApplications returns squirrel.SelectBuilder with set table and all columns
-func (s Store) applicationsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.applicationTable("app"), s.applicationColumns("app")...)
-}
-
-// applicationTable name of the db table
-func (Store) applicationTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "applications" + alias
-}
-
-// ApplicationColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) applicationColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "name",
- alias + "rel_owner",
- alias + "enabled",
- alias + "weight",
- alias + "unify",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableApplicationColumns returns all Application columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableApplicationColumns() map[string]string {
- return map[string]string{
- "id": "id", "name": "name", "weight": "weight", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalApplicationEncoder encodes fields from types.Application to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeApplication
-// func when rdbms.customEncoder=true
-func (s Store) internalApplicationEncoder(res *types.Application) store.Payload {
- return store.Payload{
- "id": res.ID,
- "name": res.Name,
- "rel_owner": res.OwnerID,
- "enabled": res.Enabled,
- "weight": res.Weight,
- "unify": res.Unify,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectApplicationCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectApplicationCursorValues(res *types.Application, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "name":
- cursor.Set(c.Column, res.Name, c.Descending)
-
- case "weight":
- cursor.Set(c.Column, res.Weight, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkApplicationConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkApplicationConstraints(ctx context.Context, res *types.Application) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/applications.go b/store/rdbms/applications.go
deleted file mode 100644
index a575e01a1..000000000
--- a/store/rdbms/applications.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package rdbms
-
-import (
- "context"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertApplicationFilter(f types.ApplicationFilter) (query squirrel.SelectBuilder, err error) {
- query = s.applicationsSelectBuilder()
-
- query = filter.StateCondition(query, "app.deleted_at", f.Deleted)
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"app.id": f.LabeledIDs})
- }
-
- if len(f.FlaggedIDs) > 0 {
- query = query.Where(squirrel.Eq{"app.id": f.FlaggedIDs})
- }
-
- if f.Query != "" {
- qs := "%" + f.Query + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"app.name": qs},
- })
- }
-
- if f.Name != "" {
- query = query.Where(squirrel.Eq{"app.name": f.Name})
- }
-
- return
-}
-
-func (s Store) ApplicationMetrics(ctx context.Context) (*types.ApplicationMetrics, error) {
- var (
- counters = squirrel.
- Select(
- "COUNT(*) as total",
- "SUM(CASE WHEN deleted_at IS NULL THEN 0 ELSE 1 END) as deleted",
- "SUM(CASE WHEN deleted_at IS NULL THEN 1 ELSE 0 END) as valid",
- ).
- PlaceholderFormat(s.config.PlaceholderFormat).
- From(s.applicationTable("u"))
-
- rval = &types.ApplicationMetrics{}
- row, err = s.QueryRow(ctx, counters)
- )
-
- if err != nil {
- return nil, err
- }
-
- err = row.Scan(&rval.Total, &rval.Deleted, &rval.Valid)
- if err != nil {
- return nil, err
- }
-
- return rval, nil
-}
-
-func (s Store) ReorderApplications(ctx context.Context, order []uint64) (err error) {
- var (
- apps types.ApplicationSet
- appMap = map[uint64]bool{}
- weight = 1
-
- f = types.ApplicationFilter{}
- )
-
- if apps, _, err = s.SearchApplications(ctx, f); err != nil {
- return
- }
-
- for _, app := range apps {
- appMap[app.ID] = true
- }
-
- // honor parameter first
- for _, pageID := range order {
- if appMap[pageID] {
- appMap[pageID] = false
- err = s.execUpdateApplications(ctx,
- squirrel.Eq{"app.id": pageID},
- store.Payload{"weight": weight})
-
- if err != nil {
- return
- }
-
- weight++
- }
- }
-
- for pageID, update := range appMap {
- if !update {
- continue
- }
-
- err = s.execUpdateApplications(ctx,
- squirrel.Eq{"app.id": pageID},
- store.Payload{"weight": weight})
-
- if err != nil {
- return
- }
-
- weight++
-
- }
-
- return
-}
diff --git a/store/rdbms/ast_transformer.go b/store/rdbms/ast_transformer.go
deleted file mode 100644
index 8f40a235f..000000000
--- a/store/rdbms/ast_transformer.go
+++ /dev/null
@@ -1,468 +0,0 @@
-package rdbms
-
-import (
- "fmt"
-
- "github.com/cortezaproject/corteza-server/pkg/qlng"
-)
-
-type (
- astTransformer struct {
- placeholders bool
- root *qlng.ASTNode
- custom []ASTFormatterFn
- onSymbol func(s string) string
- }
-
- // FormattedASTArgs is a temporary storage for already handled nested arguments
- FormattedASTArgs struct {
- S string
- Args []interface{}
-
- ResultType string
- }
- ASTFormatterFn func(n *qlng.ASTNode) HandlerSig
- HandlerSig func(aa ...FormattedASTArgs) (string, []interface{}, bool, error)
-
- exprHandler struct {
- Args argSet
- RArgs bool
- Result *arg
-
- Handler HandlerSig
- }
- argSet []*arg
- arg struct {
- Required bool
- Type string
- }
-)
-
-var (
- bracketHandler = makeGenericBracketHandler("(", ")")
-
- // @todo IS and IS NOT; should this be calculated with eq operators?
- sqlExprRegistry = map[string]exprHandler{
- // operators
- "not": {
- Args: collectParams(true, "Boolean"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericModifierHandler("NOT"),
- },
-
- // - bool
- "and": {
- Args: collectParams(true, "Boolean"),
- RArgs: true,
- Result: wrapRes("Boolean"),
- Handler: makeGenericBoolHandler("AND"),
- },
- "or": {
- Args: collectParams(true, "Boolean"),
- RArgs: true,
- Result: wrapRes("Boolean"),
- Handler: makeGenericBoolHandler("OR"),
- },
- "xor": {
- Args: collectParams(true, "Boolean"),
- RArgs: true,
- Result: wrapRes("Boolean"),
- Handler: makeGenericBoolHandler("XOR"),
- },
-
- // - comp.
- "eq": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("="),
- },
- "ne": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("!="),
- },
- "lt": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("<"),
- },
- "le": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("<="),
- },
- "gt": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler(">"),
- },
- "ge": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler(">="),
- },
-
- // - math
- "add": {
- Args: collectParams(true, "Number", "Number"),
- RArgs: true,
- Result: wrapRes("Number"),
- Handler: makeGenericCompHandler("+"),
- },
- "sub": {
- Args: collectParams(true, "Number", "Number"),
- RArgs: true,
- Result: wrapRes("Number"),
- Handler: makeGenericCompHandler("-"),
- },
- "mult": {
- Args: collectParams(true, "Number", "Number"),
- RArgs: true,
- Result: wrapRes("Number"),
- Handler: makeGenericCompHandler("*"),
- },
- "div": {
- Args: collectParams(true, "Number", "Number"),
- RArgs: true,
- Result: wrapRes("Number"),
- Handler: makeGenericCompHandler("/"),
- },
-
- // - strings
- "concat": {
- Args: collectParams(true, "String"),
- RArgs: true,
- Result: wrapRes("String"),
- Handler: makeGenericFncHandler("CONCAT"),
- },
-
- // @todo better negation?
- "like": {
- Args: collectParams(true, "String", "String"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("LIKE"),
- },
- "nlike": {
- Args: collectParams(true, "String", "String"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("NOT LIKE"),
- },
-
- "is": {
- Args: collectParams(true, "Any", "Any"),
- Result: wrapRes("Boolean"),
- Handler: makeGenericCompHandler("IS"),
- },
-
- // functions
- // - aggregation
- "count": {
- Args: collectParams(false, "Any"),
- Result: wrapRes("Number"),
- Handler: makeGenericAggFncHandler("COUNT"),
- },
- "sum": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("Number"),
- Handler: makeGenericAggFncHandler("SUM"),
- },
- "max": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("Number"),
- Handler: makeGenericAggFncHandler("MAX"),
- },
- "min": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("Number"),
- Handler: makeGenericAggFncHandler("MIN"),
- },
- "avg": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("Number"),
- Handler: makeGenericAggFncHandler("AVG"),
- },
-
- // - filtering
- "now": {
- Result: wrapRes("DateTime"),
- Handler: makeGenericFilterFncHandler("NOW"),
- },
- "quarter": {
- Args: collectParams(true, "DateTime"),
- Result: wrapRes("Number"),
- Handler: makeGenericFilterFncHandler("QUARTER"),
- },
- "year": {
- Args: collectParams(true, "DateTime"),
- Result: wrapRes("Number"),
- Handler: makeGenericFilterFncHandler("YEAR"),
- },
- "month": {
- Args: collectParams(true, "DateTime"),
- Result: wrapRes("Number"),
- Handler: makeGenericFilterFncHandler("MONTH"),
- },
- "date": {
- Args: collectParams(true, "DateTime"),
- Result: wrapRes("Number"),
- Handler: makeGenericFilterFncHandler("DAY"),
- },
-
- // generic stuff
- "null": {
- Result: wrapRes("Null"),
- Handler: func(aa ...FormattedASTArgs) (string, []interface{}, bool, error) {
- return "NULL", nil, true, nil
- },
- },
- "nnull": {
- Result: wrapRes("Null"),
- Handler: func(aa ...FormattedASTArgs) (string, []interface{}, bool, error) {
- return "NOT NULL", nil, true, nil
- },
- },
-
- "exists": {
- Args: collectParams(false, "Any"),
- Result: wrapRes("Boolean"),
- Handler: func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("(%s IS NOT NULL)", aa[0].S)
- selfEnclosed = true
-
- return
- },
- },
-
- // - typecast
- "float": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("Float"),
- Handler: makeGenericTypecastHandler("DECIMAL"),
- },
- "int": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("Float"),
- Handler: makeGenericTypecastHandler("SIGNED"),
- },
- // @todo some better way of casting to string?
- // MySQL does not support casting to longtext so I decided on doing this for now
- "string": {
- Args: collectParams(true, "Any"),
- Result: wrapRes("String"),
- Handler: makeGenericTypecastHandler("CHAR(8192)"),
- },
- }
-)
-
-func newASTFormatter(n *qlng.ASTNode, custom ...ASTFormatterFn) *astTransformer {
- return &astTransformer{
- placeholders: true,
- root: n,
- custom: custom,
- }
-}
-
-func (t *astTransformer) SetPlaceholder(use bool) {
- t.placeholders = use
-}
-
-// ToSql conforms the struct to squirrel allowing trivial RDBMS use
-func (t *astTransformer) ToSql() (string, []interface{}, error) {
- return t.toSql(t.root, true)
-}
-
-func (t *astTransformer) toSql(n *qlng.ASTNode, isRoot bool) (string, []interface{}, error) {
- // Leaf edge-cases
- switch {
- case n.Symbol != "":
- return t.handleSymbol(n)
- case n.Value != nil:
- return t.handleValue(n)
- }
-
- // Process arguments for the op.
- args := make([]FormattedASTArgs, len(n.Args))
- for i, a := range n.Args {
- s, pp, err := t.toSql(a, false)
- if err != nil {
- return "", nil, err
- }
-
- args[i] = FormattedASTArgs{
- S: s,
- Args: pp,
- }
- }
-
- // Custom handlers take precedence
- for _, c := range t.custom {
- if c == nil {
- continue
- }
-
- if h := c(n); h != nil {
- s, args, encl, err := h(args...)
- if !isRoot && !encl && len(args) > 1 {
- s = "(" + s + ")"
- }
- return s, args, err
- }
- }
-
- if n.Ref == "group" {
- s, args, _, err := bracketHandler(args...)
- return s, args, err
- }
-
- // Default handlers
- if e, ok := sqlExprRegistry[n.Ref]; !ok {
- return "", nil, fmt.Errorf("unknown expression: handler not defined: %s", n.Ref)
- } else {
- s, _args, encl, err := e.Handler(args...)
- if !isRoot && !encl && len(args) > 1 {
- s = "(" + s + ")"
- }
- return s, _args, err
- }
-}
-
-func wrapIntfs(vv ...interface{}) []interface{} {
- return vv
-}
-
-func mergeIntfs(aa ...[]interface{}) (out []interface{}) {
- out = make([]interface{}, 0, 10)
- for _, a := range aa {
- out = append(out, a...)
- }
-
- return out
-}
-
-// Analyze analyzes the AST and returns the resulting type and any errors
-func (t *astTransformer) Analyze(symbolIndex map[string]string) (string, error) {
- return t.analyze(t.root, symbolIndex)
-}
-
-func (t *astTransformer) analyze(n *qlng.ASTNode, symbolIndex map[string]string) (string, error) {
- // Leaf edge-cases
- // - symbol
- if n.Symbol != "" {
- sy, ok := symbolIndex[n.Symbol]
- if !ok {
- return "", fmt.Errorf("unknown symbol %s", n.Symbol)
- }
- return sy, nil
- }
- // - plain value
- if n.Value != nil {
- return n.Value.V.Type(), nil
- }
-
- // expr. validity
- args := make([]FormattedASTArgs, len(n.Args))
- for i, a := range n.Args {
- t, err := t.analyze(a, symbolIndex)
- if err != nil {
- return "", err
- }
-
- args[i] = FormattedASTArgs{
- ResultType: t,
- }
- }
-
- // groups proxy the type from their inner ops
- if n.Ref == "group" {
- if len(args) != 1 {
- return "", fmt.Errorf("a group must have a single root operation")
- }
- return args[0].ResultType, nil
- }
-
- // custom handlers should have no affect on the input/output of the handler
- e, ok := sqlExprRegistry[n.Ref]
- if !ok {
- return "", fmt.Errorf("unknown expression: handler not defined: %s", n.Ref)
- }
-
- // - check arg count
- pc, opc := countParams(e)
- if !e.RArgs {
- if len(args) < pc-opc || len(args) > pc {
- if opc > 0 {
- return "", fmt.Errorf("%s: expecting %d + %d arguments, got %d", n.Ref, pc-opc, opc, len(args))
- }
- return "", fmt.Errorf("%s: expecting %d arguments, got %d", n.Ref, pc, len(args))
- }
- } else {
- if len(args)%pc != 0 {
- return "", fmt.Errorf("%s: expecting multiple of %d arguments, got %d", n.Ref, len(e.Args), len(args))
- }
- }
-
- // - check arg types
- for i, p := range args {
- a := e.Args[i%len(e.Args)].Type
- b := p.ResultType
-
- if a == "Any" {
- continue
- }
-
- // Number allows all numeric types
- if a == "Number" && isNumber(b) {
- continue
- }
-
- if a == b {
- continue
- }
-
- return "", fmt.Errorf("argument type missmatch: expecting %s, got %s for argument %d", a, b, i)
- }
-
- return e.Result.Type, nil
-}
-
-// // // // // // // // // // // // // // // // // // // // // // // // //
-
-func isNumber(t string) bool {
- return t == "Number" || t == "Integer" || t == "UnsignedInteger" || t == "Float"
-}
-
-func countParams(e exprHandler) (all int, opt int) {
- all = len(e.Args)
-
- for _, p := range e.Args {
- if !p.Required {
- opt++
- }
- }
-
- return
-}
-
-func collectParams(req bool, ss ...string) argSet {
- pp := make(argSet, len(ss))
- for i, t := range ss {
- pp[i] = wrapParam(req, t)
- }
- return pp
-}
-
-func wrapParam(req bool, t string) *arg {
- return &arg{
- Required: req,
- Type: t,
- }
-}
-
-func wrapRes(t string) *arg {
- return wrapParam(false, t)
-}
diff --git a/store/rdbms/ast_transformer_handlers.go b/store/rdbms/ast_transformer_handlers.go
deleted file mode 100644
index fec26f012..000000000
--- a/store/rdbms/ast_transformer_handlers.go
+++ /dev/null
@@ -1,186 +0,0 @@
-package rdbms
-
-import (
- "fmt"
- "strings"
- "time"
-
- "github.com/cortezaproject/corteza-server/pkg/qlng"
-)
-
-func (t *astTransformer) handleSymbol(n *qlng.ASTNode) (string, []interface{}, error) {
- s := n.Symbol
- if t.onSymbol != nil {
- s = t.onSymbol(s)
- }
- return s, nil, nil
-}
-
-func (t *astTransformer) handleValue(n *qlng.ASTNode) (string, []interface{}, error) {
- if t.placeholders {
- return "?", wrapIntfs(n.Value.V.Get()), nil
- }
-
- vl := n.Value.V.Get()
-
- // such type casting is ok here, as the typedvalue should already be this
- switch n.Value.V.Type() {
- case "Boolean":
- if vl.(bool) {
- return "TRUE", nil, nil
- }
- return "FALSE", nil, nil
-
- case "Integer":
- return fmt.Sprintf("%d", vl.(int64)), nil, nil
-
- case "UnsignedInteger":
- return fmt.Sprintf("%d", vl.(uint64)), nil, nil
-
- case "Float":
- return fmt.Sprintf("%f", vl.(float64)), nil, nil
-
- case "String":
- return fmt.Sprintf("'%s'", vl.(string)), nil, nil
-
- case "DateTime":
- dt := vl.(*time.Time)
- return fmt.Sprintf("'%s'", dt.Format(time.RFC3339)), nil, nil
- }
-
- return "", nil, fmt.Errorf("unsupported value type: %s", n.Value.V.Type())
-}
-
-func makeGenericBoolHandler(op string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) < 1 {
- err = fmt.Errorf("expecting 1 or more arguments, got %d", len(aa))
- return
- }
-
- outPts := make([]string, len(aa))
- args = make([]interface{}, 0, 10)
- for i, a := range aa {
- outPts[i] = a.S
- args = append(args, a.Args...)
- }
-
- out = strings.Join(outPts, " "+op+" ")
- return
- }
-}
-
-func makeGenericBracketHandler(bb ...string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 argument, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("%s%s%s", bb[0], aa[0].S, bb[1])
- args = aa[0].Args
- return
- }
-}
-
-func makeGenericCompHandler(comp string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) != 2 {
- err = fmt.Errorf("expecting 2 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("%s %s %s", aa[0].S, comp, aa[1].S)
- args = mergeIntfs(aa[0].Args, aa[1].Args)
- return
- }
-}
-
-func makeGenericModifierHandler(mdf string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("%s %s", mdf, aa[0].S)
- args = aa[0].Args
- return
- }
-}
-
-func makeGenericAggFncHandler(fnc string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if fnc == "COUNT" && len(aa) == 0 {
- out = "COUNT(*)"
- return
- }
-
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 argument, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("%s(%s)", fnc, aa[0].S)
- args = aa[0].Args
- return
- }
-}
-
-func makeGenericFncHandler(fnc string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- params := make([]string, len(aa))
- for i, a := range aa {
- params[i] = a.S
- args = append(args, a.Args...)
- }
-
- out = fmt.Sprintf("%s(%s)", fnc, strings.Join(params, ", "))
- return
- }
-}
-
-func makeGenericTypecastHandler(t string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 argument, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("CAST(%s AS %s)", aa[0].S, t)
- args = aa[0].Args
- return
- }
-}
-
-func makeGenericFilterFncHandler(fnc string) HandlerSig {
- return func(aa ...FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) == 0 {
- return fmt.Sprintf("%s()", fnc), nil, selfEnclosed, nil
- }
-
- args = make([]interface{}, 0, len(aa))
- auxArgs := make([]string, len(aa))
- for i, a := range aa {
- auxArgs[i] = a.S
- args = append(args, a.Args...)
- }
-
- out = fmt.Sprintf("%s(%s)", fnc, strings.Join(auxArgs, ", "))
- return
- }
-}
diff --git a/store/rdbms/attachments.gen.go b/store/rdbms/attachments.gen.go
deleted file mode 100644
index c6be21a36..000000000
--- a/store/rdbms/attachments.gen.go
+++ /dev/null
@@ -1,358 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/attachments.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchAttachments returns all matching rows
-//
-// This function calls convertAttachmentFilter with the given
-// types.AttachmentFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAttachments(ctx context.Context, f types.AttachmentFilter) (types.AttachmentSet, types.AttachmentFilter, error) {
- var (
- err error
- set []*types.Attachment
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAttachmentFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryAttachments(ctx, q, f.Check)
- return err
- }()
-}
-
-// QueryAttachments queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAttachments(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Attachment) (bool, error),
-) ([]*types.Attachment, error) {
- var (
- tmp = make([]*types.Attachment, 0, DefaultSliceCapacity)
- set = make([]*types.Attachment, 0, DefaultSliceCapacity)
- res *types.Attachment
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAttachmentRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAttachmentByID searches for attachment by its ID
-//
-// It returns attachment even if deleted
-func (s Store) LookupAttachmentByID(ctx context.Context, id uint64) (*types.Attachment, error) {
- return s.execLookupAttachment(ctx, squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateAttachment creates one or more rows in attachments table
-func (s Store) CreateAttachment(ctx context.Context, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
- err = s.checkAttachmentConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAttachments(ctx, s.internalAttachmentEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAttachment updates one or more existing rows in attachments
-func (s Store) UpdateAttachment(ctx context.Context, rr ...*types.Attachment) error {
- return s.partialAttachmentUpdate(ctx, nil, rr...)
-}
-
-// partialAttachmentUpdate updates one or more existing rows in attachments
-func (s Store) partialAttachmentUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
- err = s.checkAttachmentConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAttachments(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalAttachmentEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAttachment updates one or more existing rows in attachments
-func (s Store) UpsertAttachment(ctx context.Context, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
- err = s.checkAttachmentConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAttachments(ctx, s.internalAttachmentEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAttachment Deletes one or more rows from attachments table
-func (s Store) DeleteAttachment(ctx context.Context, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAttachments(ctx, squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAttachmentByID Deletes row from the attachments table
-func (s Store) DeleteAttachmentByID(ctx context.Context, ID uint64) error {
- return s.execDeleteAttachments(ctx, squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAttachments Deletes all rows from the attachments table
-func (s Store) TruncateAttachments(ctx context.Context) error {
- return s.Truncate(ctx, s.attachmentTable())
-}
-
-// execLookupAttachment prepares Attachment query and executes it,
-// returning types.Attachment (or error)
-func (s Store) execLookupAttachment(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Attachment, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.attachmentsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAttachmentRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAttachments updates all matched (by cnd) rows in attachments with given data
-func (s Store) execCreateAttachments(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.attachmentTable()).SetMap(payload))
-}
-
-// execUpdateAttachments updates all matched (by cnd) rows in attachments with given data
-func (s Store) execUpdateAttachments(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.attachmentTable("att")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAttachments inserts new or updates matching (by-primary-key) rows in attachments with given data
-func (s Store) execUpsertAttachments(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.attachmentTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAttachments Deletes all matched (by cnd) rows in attachments with given data
-func (s Store) execDeleteAttachments(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.attachmentTable("att")).Where(cnd))
-}
-
-func (s Store) internalAttachmentRowScanner(row rowScanner) (res *types.Attachment, err error) {
- res = &types.Attachment{}
-
- err = row.Scan(
- &res.ID,
- &res.OwnerID,
- &res.Kind,
- &res.Url,
- &res.PreviewUrl,
- &res.Name,
- &res.Meta,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan attachment db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAttachments returns squirrel.SelectBuilder with set table and all columns
-func (s Store) attachmentsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.attachmentTable("att"), s.attachmentColumns("att")...)
-}
-
-// attachmentTable name of the db table
-func (Store) attachmentTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "attachments" + alias
-}
-
-// AttachmentColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) attachmentColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_owner",
- alias + "kind",
- alias + "url",
- alias + "preview_url",
- alias + "name",
- alias + "meta",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false false false true}
-
-// internalAttachmentEncoder encodes fields from types.Attachment to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAttachment
-// func when rdbms.customEncoder=true
-func (s Store) internalAttachmentEncoder(res *types.Attachment) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_owner": res.OwnerID,
- "kind": res.Kind,
- "url": res.Url,
- "preview_url": res.PreviewUrl,
- "name": res.Name,
- "meta": res.Meta,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkAttachmentConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAttachmentConstraints(ctx context.Context, res *types.Attachment) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/attachments.go b/store/rdbms/attachments.go
deleted file mode 100644
index 0c639be0c..000000000
--- a/store/rdbms/attachments.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertAttachmentFilter(f types.AttachmentFilter) (query squirrel.SelectBuilder, err error) {
- query = s.attachmentsSelectBuilder()
-
- if f.Kind != "" {
- query = query.Where(squirrel.Eq{"att.kind": f.Kind})
- }
-
- return
-}
diff --git a/store/rdbms/auth_clients.gen.go b/store/rdbms/auth_clients.gen.go
deleted file mode 100644
index ac02a4408..000000000
--- a/store/rdbms/auth_clients.gen.go
+++ /dev/null
@@ -1,665 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/auth_clients.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchAuthClients returns all matching rows
-//
-// This function calls convertAuthClientFilter with the given
-// types.AuthClientFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAuthClients(ctx context.Context, f types.AuthClientFilter) (types.AuthClientSet, types.AuthClientFilter, error) {
- var (
- err error
- set []*types.AuthClient
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAuthClientFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableAuthClientColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAuthClients(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfAuthClients collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfAuthClients(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.AuthClient) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.AuthClient, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.AuthClient
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.AuthClient, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryAuthClients(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectAuthClientCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectAuthClientCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectAuthClientCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryAuthClients queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAuthClients(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.AuthClient) (bool, error),
-) ([]*types.AuthClient, error) {
- var (
- tmp = make([]*types.AuthClient, 0, DefaultSliceCapacity)
- set = make([]*types.AuthClient, 0, DefaultSliceCapacity)
- res *types.AuthClient
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAuthClientRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAuthClientByID searches for auth client by ID
-//
-// It returns auth client even if deleted
-func (s Store) LookupAuthClientByID(ctx context.Context, id uint64) (*types.AuthClient, error) {
- return s.execLookupAuthClient(ctx, squirrel.Eq{
- s.preprocessColumn("ac.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupAuthClientByHandle searches for auth client by ID
-//
-// It returns auth client even if deleted
-func (s Store) LookupAuthClientByHandle(ctx context.Context, handle string) (*types.AuthClient, error) {
- return s.execLookupAuthClient(ctx, squirrel.Eq{
- s.preprocessColumn("ac.handle", ""): store.PreprocessValue(handle, ""),
-
- "ac.deleted_at": nil,
- })
-}
-
-// CreateAuthClient creates one or more rows in auth_clients table
-func (s Store) CreateAuthClient(ctx context.Context, rr ...*types.AuthClient) (err error) {
- for _, res := range rr {
- err = s.checkAuthClientConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAuthClients(ctx, s.internalAuthClientEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAuthClient updates one or more existing rows in auth_clients
-func (s Store) UpdateAuthClient(ctx context.Context, rr ...*types.AuthClient) error {
- return s.partialAuthClientUpdate(ctx, nil, rr...)
-}
-
-// partialAuthClientUpdate updates one or more existing rows in auth_clients
-func (s Store) partialAuthClientUpdate(ctx context.Context, onlyColumns []string, rr ...*types.AuthClient) (err error) {
- for _, res := range rr {
- err = s.checkAuthClientConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAuthClients(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("ac.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalAuthClientEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAuthClient updates one or more existing rows in auth_clients
-func (s Store) UpsertAuthClient(ctx context.Context, rr ...*types.AuthClient) (err error) {
- for _, res := range rr {
- err = s.checkAuthClientConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAuthClients(ctx, s.internalAuthClientEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthClient Deletes one or more rows from auth_clients table
-func (s Store) DeleteAuthClient(ctx context.Context, rr ...*types.AuthClient) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAuthClients(ctx, squirrel.Eq{
- s.preprocessColumn("ac.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthClientByID Deletes row from the auth_clients table
-func (s Store) DeleteAuthClientByID(ctx context.Context, ID uint64) error {
- return s.execDeleteAuthClients(ctx, squirrel.Eq{
- s.preprocessColumn("ac.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAuthClients Deletes all rows from the auth_clients table
-func (s Store) TruncateAuthClients(ctx context.Context) error {
- return s.Truncate(ctx, s.authClientTable())
-}
-
-// execLookupAuthClient prepares AuthClient query and executes it,
-// returning types.AuthClient (or error)
-func (s Store) execLookupAuthClient(ctx context.Context, cnd squirrel.Sqlizer) (res *types.AuthClient, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.authClientsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAuthClientRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAuthClients updates all matched (by cnd) rows in auth_clients with given data
-func (s Store) execCreateAuthClients(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.authClientTable()).SetMap(payload))
-}
-
-// execUpdateAuthClients updates all matched (by cnd) rows in auth_clients with given data
-func (s Store) execUpdateAuthClients(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.authClientTable("ac")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAuthClients inserts new or updates matching (by-primary-key) rows in auth_clients with given data
-func (s Store) execUpsertAuthClients(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.authClientTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAuthClients Deletes all matched (by cnd) rows in auth_clients with given data
-func (s Store) execDeleteAuthClients(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.authClientTable("ac")).Where(cnd))
-}
-
-func (s Store) internalAuthClientRowScanner(row rowScanner) (res *types.AuthClient, err error) {
- res = &types.AuthClient{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Meta,
- &res.Secret,
- &res.Scope,
- &res.ValidGrant,
- &res.RedirectURI,
- &res.Trusted,
- &res.Enabled,
- &res.ValidFrom,
- &res.ExpiresAt,
- &res.Security,
- &res.OwnedBy,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan authClient db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAuthClients returns squirrel.SelectBuilder with set table and all columns
-func (s Store) authClientsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.authClientTable("ac"), s.authClientColumns("ac")...)
-}
-
-// authClientTable name of the db table
-func (Store) authClientTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "auth_clients" + alias
-}
-
-// AuthClientColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) authClientColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "meta",
- alias + "secret",
- alias + "scope",
- alias + "valid_grant",
- alias + "redirect_uri",
- alias + "trusted",
- alias + "enabled",
- alias + "valid_from",
- alias + "expires_at",
- alias + "security",
- alias + "owned_by",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableAuthClientColumns returns all AuthClient columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableAuthClientColumns() map[string]string {
- return map[string]string{
- "id": "id", "handle": "handle", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalAuthClientEncoder encodes fields from types.AuthClient to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAuthClient
-// func when rdbms.customEncoder=true
-func (s Store) internalAuthClientEncoder(res *types.AuthClient) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "meta": res.Meta,
- "secret": res.Secret,
- "scope": res.Scope,
- "valid_grant": res.ValidGrant,
- "redirect_uri": res.RedirectURI,
- "trusted": res.Trusted,
- "enabled": res.Enabled,
- "valid_from": res.ValidFrom,
- "expires_at": res.ExpiresAt,
- "security": res.Security,
- "owned_by": res.OwnedBy,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectAuthClientCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectAuthClientCursorValues(res *types.AuthClient, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkAuthClientConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAuthClientConstraints(ctx context.Context, res *types.AuthClient) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Handle) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Handle if AuthClient does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupAuthClientByHandle(ctx, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/auth_clients.go b/store/rdbms/auth_clients.go
deleted file mode 100644
index 636de911b..000000000
--- a/store/rdbms/auth_clients.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertAuthClientFilter(f types.AuthClientFilter) (query squirrel.SelectBuilder, err error) {
- query = s.authClientsSelectBuilder()
-
- query = filter.StateCondition(query, "ac.deleted_at", f.Deleted)
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"ac.id": f.LabeledIDs})
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"ac.handle": f.Handle})
- }
-
- return
-}
diff --git a/store/rdbms/auth_confirmed_clients.gen.go b/store/rdbms/auth_confirmed_clients.gen.go
deleted file mode 100644
index 0f6ec2391..000000000
--- a/store/rdbms/auth_confirmed_clients.gen.go
+++ /dev/null
@@ -1,345 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/auth_confirmed_clients.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchAuthConfirmedClients returns all matching rows
-//
-// This function calls convertAuthConfirmedClientFilter with the given
-// types.AuthConfirmedClientFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAuthConfirmedClients(ctx context.Context, f types.AuthConfirmedClientFilter) (types.AuthConfirmedClientSet, types.AuthConfirmedClientFilter, error) {
- var (
- err error
- set []*types.AuthConfirmedClient
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAuthConfirmedClientFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryAuthConfirmedClients(ctx, q, nil)
- return err
- }()
-}
-
-// QueryAuthConfirmedClients queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAuthConfirmedClients(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.AuthConfirmedClient) (bool, error),
-) ([]*types.AuthConfirmedClient, error) {
- var (
- tmp = make([]*types.AuthConfirmedClient, 0, DefaultSliceCapacity)
- set = make([]*types.AuthConfirmedClient, 0, DefaultSliceCapacity)
- res *types.AuthConfirmedClient
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAuthConfirmedClientRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAuthConfirmedClientByUserIDClientID
-func (s Store) LookupAuthConfirmedClientByUserIDClientID(ctx context.Context, user_id uint64, client_id uint64) (*types.AuthConfirmedClient, error) {
- return s.execLookupAuthConfirmedClient(ctx, squirrel.Eq{
- s.preprocessColumn("acc.rel_user", ""): store.PreprocessValue(user_id, ""),
- s.preprocessColumn("acc.rel_client", ""): store.PreprocessValue(client_id, ""),
- })
-}
-
-// CreateAuthConfirmedClient creates one or more rows in auth_confirmed_clients table
-func (s Store) CreateAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) (err error) {
- for _, res := range rr {
- err = s.checkAuthConfirmedClientConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAuthConfirmedClients(ctx, s.internalAuthConfirmedClientEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAuthConfirmedClient updates one or more existing rows in auth_confirmed_clients
-func (s Store) UpdateAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) error {
- return s.partialAuthConfirmedClientUpdate(ctx, nil, rr...)
-}
-
-// partialAuthConfirmedClientUpdate updates one or more existing rows in auth_confirmed_clients
-func (s Store) partialAuthConfirmedClientUpdate(ctx context.Context, onlyColumns []string, rr ...*types.AuthConfirmedClient) (err error) {
- for _, res := range rr {
- err = s.checkAuthConfirmedClientConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAuthConfirmedClients(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("acc.rel_user", ""): store.PreprocessValue(res.UserID, ""), s.preprocessColumn("acc.rel_client", ""): store.PreprocessValue(res.ClientID, ""),
- },
- s.internalAuthConfirmedClientEncoder(res).Skip("rel_user", "rel_client").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAuthConfirmedClient updates one or more existing rows in auth_confirmed_clients
-func (s Store) UpsertAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) (err error) {
- for _, res := range rr {
- err = s.checkAuthConfirmedClientConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAuthConfirmedClients(ctx, s.internalAuthConfirmedClientEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthConfirmedClient Deletes one or more rows from auth_confirmed_clients table
-func (s Store) DeleteAuthConfirmedClient(ctx context.Context, rr ...*types.AuthConfirmedClient) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAuthConfirmedClients(ctx, squirrel.Eq{
- s.preprocessColumn("acc.rel_user", ""): store.PreprocessValue(res.UserID, ""), s.preprocessColumn("acc.rel_client", ""): store.PreprocessValue(res.ClientID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthConfirmedClientByUserIDClientID Deletes row from the auth_confirmed_clients table
-func (s Store) DeleteAuthConfirmedClientByUserIDClientID(ctx context.Context, userID uint64, clientID uint64) error {
- return s.execDeleteAuthConfirmedClients(ctx, squirrel.Eq{
- s.preprocessColumn("acc.rel_user", ""): store.PreprocessValue(userID, ""),
- s.preprocessColumn("acc.rel_client", ""): store.PreprocessValue(clientID, ""),
- })
-}
-
-// TruncateAuthConfirmedClients Deletes all rows from the auth_confirmed_clients table
-func (s Store) TruncateAuthConfirmedClients(ctx context.Context) error {
- return s.Truncate(ctx, s.authConfirmedClientTable())
-}
-
-// execLookupAuthConfirmedClient prepares AuthConfirmedClient query and executes it,
-// returning types.AuthConfirmedClient (or error)
-func (s Store) execLookupAuthConfirmedClient(ctx context.Context, cnd squirrel.Sqlizer) (res *types.AuthConfirmedClient, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.authConfirmedClientsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAuthConfirmedClientRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAuthConfirmedClients updates all matched (by cnd) rows in auth_confirmed_clients with given data
-func (s Store) execCreateAuthConfirmedClients(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.authConfirmedClientTable()).SetMap(payload))
-}
-
-// execUpdateAuthConfirmedClients updates all matched (by cnd) rows in auth_confirmed_clients with given data
-func (s Store) execUpdateAuthConfirmedClients(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.authConfirmedClientTable("acc")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAuthConfirmedClients inserts new or updates matching (by-primary-key) rows in auth_confirmed_clients with given data
-func (s Store) execUpsertAuthConfirmedClients(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.authConfirmedClientTable(),
- set,
- s.preprocessColumn("rel_user", ""),
- s.preprocessColumn("rel_client", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAuthConfirmedClients Deletes all matched (by cnd) rows in auth_confirmed_clients with given data
-func (s Store) execDeleteAuthConfirmedClients(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.authConfirmedClientTable("acc")).Where(cnd))
-}
-
-func (s Store) internalAuthConfirmedClientRowScanner(row rowScanner) (res *types.AuthConfirmedClient, err error) {
- res = &types.AuthConfirmedClient{}
-
- err = row.Scan(
- &res.UserID,
- &res.ClientID,
- &res.ConfirmedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan authConfirmedClient db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAuthConfirmedClients returns squirrel.SelectBuilder with set table and all columns
-func (s Store) authConfirmedClientsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.authConfirmedClientTable("acc"), s.authConfirmedClientColumns("acc")...)
-}
-
-// authConfirmedClientTable name of the db table
-func (Store) authConfirmedClientTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "auth_confirmed_clients" + alias
-}
-
-// AuthConfirmedClientColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) authConfirmedClientColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "rel_user",
- alias + "rel_client",
- alias + "confirmed_at",
- }
-}
-
-// {true true false false false false}
-
-// internalAuthConfirmedClientEncoder encodes fields from types.AuthConfirmedClient to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAuthConfirmedClient
-// func when rdbms.customEncoder=true
-func (s Store) internalAuthConfirmedClientEncoder(res *types.AuthConfirmedClient) store.Payload {
- return store.Payload{
- "rel_user": res.UserID,
- "rel_client": res.ClientID,
- "confirmed_at": res.ConfirmedAt,
- }
-}
-
-// checkAuthConfirmedClientConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAuthConfirmedClientConstraints(ctx context.Context, res *types.AuthConfirmedClient) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && res.UserID > 0
-
- valid = valid && res.ClientID > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by UserIDClientID if AuthConfirmedClient does not match filters
-
- ex, err := s.LookupAuthConfirmedClientByUserIDClientID(ctx, res.UserID, res.ClientID)
- if err == nil && ex != nil && ex.UserID != res.UserID && ex.ClientID != res.ClientID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/auth_confirmed_clients.go b/store/rdbms/auth_confirmed_clients.go
deleted file mode 100644
index e6ee89ac6..000000000
--- a/store/rdbms/auth_confirmed_clients.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertAuthConfirmedClientFilter(f types.AuthConfirmedClientFilter) (query squirrel.SelectBuilder, err error) {
- query = s.authConfirmedClientsSelectBuilder()
- query = query.Where(squirrel.Eq{"acc.rel_user": f.UserID})
- return
-}
diff --git a/store/rdbms/auth_oa2tokens.gen.go b/store/rdbms/auth_oa2tokens.gen.go
deleted file mode 100644
index a9c3f5a57..000000000
--- a/store/rdbms/auth_oa2tokens.gen.go
+++ /dev/null
@@ -1,350 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/auth_oa2tokens.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchAuthOa2tokens returns all matching rows
-//
-// This function calls convertAuthOa2tokenFilter with the given
-// types.AuthOa2tokenFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAuthOa2tokens(ctx context.Context, f types.AuthOa2tokenFilter) (types.AuthOa2tokenSet, types.AuthOa2tokenFilter, error) {
- var (
- err error
- set []*types.AuthOa2token
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAuthOa2tokenFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryAuthOa2tokens(ctx, q, nil)
- return err
- }()
-}
-
-// QueryAuthOa2tokens queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAuthOa2tokens(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.AuthOa2token) (bool, error),
-) ([]*types.AuthOa2token, error) {
- var (
- tmp = make([]*types.AuthOa2token, 0, DefaultSliceCapacity)
- set = make([]*types.AuthOa2token, 0, DefaultSliceCapacity)
- res *types.AuthOa2token
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAuthOa2tokenRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAuthOa2tokenByID
-func (s Store) LookupAuthOa2tokenByID(ctx context.Context, id uint64) (*types.AuthOa2token, error) {
- return s.execLookupAuthOa2token(ctx, squirrel.Eq{
- s.preprocessColumn("tkn.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupAuthOa2tokenByCode
-func (s Store) LookupAuthOa2tokenByCode(ctx context.Context, code string) (*types.AuthOa2token, error) {
- return s.execLookupAuthOa2token(ctx, squirrel.Eq{
- s.preprocessColumn("tkn.code", ""): store.PreprocessValue(code, ""),
- })
-}
-
-// LookupAuthOa2tokenByAccess
-func (s Store) LookupAuthOa2tokenByAccess(ctx context.Context, access string) (*types.AuthOa2token, error) {
- return s.execLookupAuthOa2token(ctx, squirrel.Eq{
- s.preprocessColumn("tkn.access", ""): store.PreprocessValue(access, ""),
- })
-}
-
-// LookupAuthOa2tokenByRefresh
-func (s Store) LookupAuthOa2tokenByRefresh(ctx context.Context, refresh string) (*types.AuthOa2token, error) {
- return s.execLookupAuthOa2token(ctx, squirrel.Eq{
- s.preprocessColumn("tkn.refresh", ""): store.PreprocessValue(refresh, ""),
- })
-}
-
-// CreateAuthOa2token creates one or more rows in auth_oa2tokens table
-func (s Store) CreateAuthOa2token(ctx context.Context, rr ...*types.AuthOa2token) (err error) {
- for _, res := range rr {
- err = s.checkAuthOa2tokenConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAuthOa2tokens(ctx, s.internalAuthOa2tokenEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// DeleteAuthOa2token Deletes one or more rows from auth_oa2tokens table
-func (s Store) DeleteAuthOa2token(ctx context.Context, rr ...*types.AuthOa2token) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAuthOa2tokens(ctx, squirrel.Eq{
- s.preprocessColumn("tkn.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthOa2tokenByID Deletes row from the auth_oa2tokens table
-func (s Store) DeleteAuthOa2tokenByID(ctx context.Context, ID uint64) error {
- return s.execDeleteAuthOa2tokens(ctx, squirrel.Eq{
- s.preprocessColumn("tkn.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAuthOa2tokens Deletes all rows from the auth_oa2tokens table
-func (s Store) TruncateAuthOa2tokens(ctx context.Context) error {
- return s.Truncate(ctx, s.authOa2tokenTable())
-}
-
-// execLookupAuthOa2token prepares AuthOa2token query and executes it,
-// returning types.AuthOa2token (or error)
-func (s Store) execLookupAuthOa2token(ctx context.Context, cnd squirrel.Sqlizer) (res *types.AuthOa2token, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.authOa2tokensSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAuthOa2tokenRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAuthOa2tokens updates all matched (by cnd) rows in auth_oa2tokens with given data
-func (s Store) execCreateAuthOa2tokens(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.authOa2tokenTable()).SetMap(payload))
-}
-
-// execDeleteAuthOa2tokens Deletes all matched (by cnd) rows in auth_oa2tokens with given data
-func (s Store) execDeleteAuthOa2tokens(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.authOa2tokenTable("tkn")).Where(cnd))
-}
-
-func (s Store) internalAuthOa2tokenRowScanner(row rowScanner) (res *types.AuthOa2token, err error) {
- res = &types.AuthOa2token{}
-
- err = row.Scan(
- &res.ID,
- &res.Code,
- &res.Access,
- &res.Refresh,
- &res.ExpiresAt,
- &res.CreatedAt,
- &res.Data,
- &res.ClientID,
- &res.UserID,
- &res.RemoteAddr,
- &res.UserAgent,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan authOa2token db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAuthOa2tokens returns squirrel.SelectBuilder with set table and all columns
-func (s Store) authOa2tokensSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.authOa2tokenTable("tkn"), s.authOa2tokenColumns("tkn")...)
-}
-
-// authOa2tokenTable name of the db table
-func (Store) authOa2tokenTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "auth_oa2tokens" + alias
-}
-
-// AuthOa2tokenColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) authOa2tokenColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "code",
- alias + "access",
- alias + "refresh",
- alias + "expires_at",
- alias + "created_at",
- alias + "data",
- alias + "rel_client",
- alias + "rel_user",
- alias + "remote_addr",
- alias + "user_agent",
- }
-}
-
-// {true true false false false false}
-
-// internalAuthOa2tokenEncoder encodes fields from types.AuthOa2token to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAuthOa2token
-// func when rdbms.customEncoder=true
-func (s Store) internalAuthOa2tokenEncoder(res *types.AuthOa2token) store.Payload {
- return store.Payload{
- "id": res.ID,
- "code": res.Code,
- "access": res.Access,
- "refresh": res.Refresh,
- "expires_at": res.ExpiresAt,
- "created_at": res.CreatedAt,
- "data": res.Data,
- "rel_client": res.ClientID,
- "rel_user": res.UserID,
- "remote_addr": res.RemoteAddr,
- "user_agent": res.UserAgent,
- }
-}
-
-// checkAuthOa2tokenConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAuthOa2tokenConstraints(ctx context.Context, res *types.AuthOa2token) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Code) > 0
-
- valid = valid && len(res.Access) > 0
-
- valid = valid && len(res.Refresh) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Code if AuthOa2token does not match filters
-
- ex, err := s.LookupAuthOa2tokenByCode(ctx, res.Code)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by Access if AuthOa2token does not match filters
-
- ex, err := s.LookupAuthOa2tokenByAccess(ctx, res.Access)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by Refresh if AuthOa2token does not match filters
-
- ex, err := s.LookupAuthOa2tokenByRefresh(ctx, res.Refresh)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/auth_oa2tokens.go b/store/rdbms/auth_oa2tokens.go
deleted file mode 100644
index 00957c4d5..000000000
--- a/store/rdbms/auth_oa2tokens.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package rdbms
-
-import (
- "context"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/system/types"
- "time"
-)
-
-func (s Store) convertAuthOa2tokenFilter(f types.AuthOa2tokenFilter) (query squirrel.SelectBuilder, err error) {
- query = s.authOa2tokensSelectBuilder()
-
- if f.UserID > 0 {
- query = query.Where(squirrel.Eq{"tkn.rel_user": f.UserID})
- }
-
- return
-}
-
-func (s Store) DeleteExpiredAuthOA2Tokens(ctx context.Context) error {
- return s.execDeleteAuthOa2tokens(ctx, squirrel.Lt{"tkn.expires_at": time.Now()})
-}
-
-func (s Store) DeleteAuthOA2TokenByCode(ctx context.Context, code string) error {
- return s.execDeleteAuthOa2tokens(ctx, squirrel.Eq{"tkn.code": code})
-}
-
-func (s Store) DeleteAuthOA2TokenByAccess(ctx context.Context, access string) error {
- return s.execDeleteAuthOa2tokens(ctx, squirrel.Eq{"tkn.access": access})
-}
-
-func (s Store) DeleteAuthOA2TokenByRefresh(ctx context.Context, refresh string) error {
- return s.execDeleteAuthOa2tokens(ctx, squirrel.Eq{"tkn.refresh": refresh})
-}
-
-func (s Store) DeleteAuthOA2TokenByUserID(ctx context.Context, userID uint64) error {
- return s.execDeleteAuthOa2tokens(ctx, squirrel.Eq{"tkn.rel_user": userID})
-}
diff --git a/store/rdbms/auth_sessions.gen.go b/store/rdbms/auth_sessions.gen.go
deleted file mode 100644
index c13b1ffce..000000000
--- a/store/rdbms/auth_sessions.gen.go
+++ /dev/null
@@ -1,352 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/auth_sessions.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchAuthSessions returns all matching rows
-//
-// This function calls convertAuthSessionFilter with the given
-// types.AuthSessionFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAuthSessions(ctx context.Context, f types.AuthSessionFilter) (types.AuthSessionSet, types.AuthSessionFilter, error) {
- var (
- err error
- set []*types.AuthSession
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAuthSessionFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryAuthSessions(ctx, q, nil)
- return err
- }()
-}
-
-// QueryAuthSessions queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAuthSessions(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.AuthSession) (bool, error),
-) ([]*types.AuthSession, error) {
- var (
- tmp = make([]*types.AuthSession, 0, DefaultSliceCapacity)
- set = make([]*types.AuthSession, 0, DefaultSliceCapacity)
- res *types.AuthSession
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAuthSessionRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAuthSessionByID
-func (s Store) LookupAuthSessionByID(ctx context.Context, id string) (*types.AuthSession, error) {
- return s.execLookupAuthSession(ctx, squirrel.Eq{
- s.preprocessColumn("ses.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateAuthSession creates one or more rows in auth_sessions table
-func (s Store) CreateAuthSession(ctx context.Context, rr ...*types.AuthSession) (err error) {
- for _, res := range rr {
- err = s.checkAuthSessionConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAuthSessions(ctx, s.internalAuthSessionEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAuthSession updates one or more existing rows in auth_sessions
-func (s Store) UpdateAuthSession(ctx context.Context, rr ...*types.AuthSession) error {
- return s.partialAuthSessionUpdate(ctx, nil, rr...)
-}
-
-// partialAuthSessionUpdate updates one or more existing rows in auth_sessions
-func (s Store) partialAuthSessionUpdate(ctx context.Context, onlyColumns []string, rr ...*types.AuthSession) (err error) {
- for _, res := range rr {
- err = s.checkAuthSessionConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAuthSessions(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("ses.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalAuthSessionEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAuthSession updates one or more existing rows in auth_sessions
-func (s Store) UpsertAuthSession(ctx context.Context, rr ...*types.AuthSession) (err error) {
- for _, res := range rr {
- err = s.checkAuthSessionConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAuthSessions(ctx, s.internalAuthSessionEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthSession Deletes one or more rows from auth_sessions table
-func (s Store) DeleteAuthSession(ctx context.Context, rr ...*types.AuthSession) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAuthSessions(ctx, squirrel.Eq{
- s.preprocessColumn("ses.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAuthSessionByID Deletes row from the auth_sessions table
-func (s Store) DeleteAuthSessionByID(ctx context.Context, ID string) error {
- return s.execDeleteAuthSessions(ctx, squirrel.Eq{
- s.preprocessColumn("ses.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAuthSessions Deletes all rows from the auth_sessions table
-func (s Store) TruncateAuthSessions(ctx context.Context) error {
- return s.Truncate(ctx, s.authSessionTable())
-}
-
-// execLookupAuthSession prepares AuthSession query and executes it,
-// returning types.AuthSession (or error)
-func (s Store) execLookupAuthSession(ctx context.Context, cnd squirrel.Sqlizer) (res *types.AuthSession, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.authSessionsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAuthSessionRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAuthSessions updates all matched (by cnd) rows in auth_sessions with given data
-func (s Store) execCreateAuthSessions(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.authSessionTable()).SetMap(payload))
-}
-
-// execUpdateAuthSessions updates all matched (by cnd) rows in auth_sessions with given data
-func (s Store) execUpdateAuthSessions(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.authSessionTable("ses")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAuthSessions inserts new or updates matching (by-primary-key) rows in auth_sessions with given data
-func (s Store) execUpsertAuthSessions(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.authSessionTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAuthSessions Deletes all matched (by cnd) rows in auth_sessions with given data
-func (s Store) execDeleteAuthSessions(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.authSessionTable("ses")).Where(cnd))
-}
-
-func (s Store) internalAuthSessionRowScanner(row rowScanner) (res *types.AuthSession, err error) {
- res = &types.AuthSession{}
-
- err = row.Scan(
- &res.ID,
- &res.Data,
- &res.UserID,
- &res.RemoteAddr,
- &res.UserAgent,
- &res.CreatedAt,
- &res.ExpiresAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan authSession db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAuthSessions returns squirrel.SelectBuilder with set table and all columns
-func (s Store) authSessionsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.authSessionTable("ses"), s.authSessionColumns("ses")...)
-}
-
-// authSessionTable name of the db table
-func (Store) authSessionTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "auth_sessions" + alias
-}
-
-// AuthSessionColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) authSessionColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "data",
- alias + "rel_user",
- alias + "remote_addr",
- alias + "user_agent",
- alias + "created_at",
- alias + "expires_at",
- }
-}
-
-// {true true false false false false}
-
-// internalAuthSessionEncoder encodes fields from types.AuthSession to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAuthSession
-// func when rdbms.customEncoder=true
-func (s Store) internalAuthSessionEncoder(res *types.AuthSession) store.Payload {
- return store.Payload{
- "id": res.ID,
- "data": res.Data,
- "rel_user": res.UserID,
- "remote_addr": res.RemoteAddr,
- "user_agent": res.UserAgent,
- "created_at": res.CreatedAt,
- "expires_at": res.ExpiresAt,
- }
-}
-
-// checkAuthSessionConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAuthSessionConstraints(ctx context.Context, res *types.AuthSession) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.ID) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by ID if AuthSession does not match filters
-
- ex, err := s.LookupAuthSessionByID(ctx, res.ID)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/auth_sessions.go b/store/rdbms/auth_sessions.go
deleted file mode 100644
index d242cc835..000000000
--- a/store/rdbms/auth_sessions.go
+++ /dev/null
@@ -1,25 +0,0 @@
-package rdbms
-
-import (
- "context"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/system/types"
- "time"
-)
-
-func (s Store) convertAuthSessionFilter(f types.AuthSessionFilter) (query squirrel.SelectBuilder, err error) {
- query = s.authSessionsSelectBuilder()
-
- if f.UserID > 0 {
- query = query.Where(squirrel.Eq{"ses.rel_user": f.UserID})
- }
-
- return
-}
-func (s Store) DeleteAuthSessionsByUserID(ctx context.Context, userID uint64) error {
- return s.execDeleteAuthSessions(ctx, squirrel.Eq{"ses.rel_user": userID})
-}
-
-func (s Store) DeleteExpiredAuthSessions(ctx context.Context) error {
- return s.execDeleteAuthSessions(ctx, squirrel.Lt{"ses.expires_at": time.Now()})
-}
diff --git a/store/rdbms/automation_sessions.gen.go b/store/rdbms/automation_sessions.gen.go
deleted file mode 100644
index 12c69540b..000000000
--- a/store/rdbms/automation_sessions.gen.go
+++ /dev/null
@@ -1,631 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/automation_sessions.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/automation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchAutomationSessions returns all matching rows
-//
-// This function calls convertAutomationSessionFilter with the given
-// types.SessionFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAutomationSessions(ctx context.Context, f types.SessionFilter) (types.SessionSet, types.SessionFilter, error) {
- var (
- err error
- set []*types.Session
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAutomationSessionFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableAutomationSessionColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAutomationSessions(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfAutomationSessions collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfAutomationSessions(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Session) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Session, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Session
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Session, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryAutomationSessions(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectAutomationSessionCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectAutomationSessionCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectAutomationSessionCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryAutomationSessions queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAutomationSessions(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Session) (bool, error),
-) ([]*types.Session, error) {
- var (
- tmp = make([]*types.Session, 0, DefaultSliceCapacity)
- set = make([]*types.Session, 0, DefaultSliceCapacity)
- res *types.Session
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAutomationSessionRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAutomationSessionByID searches for session by ID
-//
-// It returns session even if deleted
-func (s Store) LookupAutomationSessionByID(ctx context.Context, id uint64) (*types.Session, error) {
- return s.execLookupAutomationSession(ctx, squirrel.Eq{
- s.preprocessColumn("atms.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateAutomationSession creates one or more rows in automation_sessions table
-func (s Store) CreateAutomationSession(ctx context.Context, rr ...*types.Session) (err error) {
- for _, res := range rr {
- err = s.checkAutomationSessionConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAutomationSessions(ctx, s.internalAutomationSessionEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAutomationSession updates one or more existing rows in automation_sessions
-func (s Store) UpdateAutomationSession(ctx context.Context, rr ...*types.Session) error {
- return s.partialAutomationSessionUpdate(ctx, nil, rr...)
-}
-
-// partialAutomationSessionUpdate updates one or more existing rows in automation_sessions
-func (s Store) partialAutomationSessionUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Session) (err error) {
- for _, res := range rr {
- err = s.checkAutomationSessionConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAutomationSessions(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("atms.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalAutomationSessionEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAutomationSession updates one or more existing rows in automation_sessions
-func (s Store) UpsertAutomationSession(ctx context.Context, rr ...*types.Session) (err error) {
- for _, res := range rr {
- err = s.checkAutomationSessionConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAutomationSessions(ctx, s.internalAutomationSessionEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAutomationSession Deletes one or more rows from automation_sessions table
-func (s Store) DeleteAutomationSession(ctx context.Context, rr ...*types.Session) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAutomationSessions(ctx, squirrel.Eq{
- s.preprocessColumn("atms.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAutomationSessionByID Deletes row from the automation_sessions table
-func (s Store) DeleteAutomationSessionByID(ctx context.Context, ID uint64) error {
- return s.execDeleteAutomationSessions(ctx, squirrel.Eq{
- s.preprocessColumn("atms.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAutomationSessions Deletes all rows from the automation_sessions table
-func (s Store) TruncateAutomationSessions(ctx context.Context) error {
- return s.Truncate(ctx, s.automationSessionTable())
-}
-
-// execLookupAutomationSession prepares AutomationSession query and executes it,
-// returning types.Session (or error)
-func (s Store) execLookupAutomationSession(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Session, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.automationSessionsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAutomationSessionRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAutomationSessions updates all matched (by cnd) rows in automation_sessions with given data
-func (s Store) execCreateAutomationSessions(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.automationSessionTable()).SetMap(payload))
-}
-
-// execUpdateAutomationSessions updates all matched (by cnd) rows in automation_sessions with given data
-func (s Store) execUpdateAutomationSessions(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.automationSessionTable("atms")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAutomationSessions inserts new or updates matching (by-primary-key) rows in automation_sessions with given data
-func (s Store) execUpsertAutomationSessions(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.automationSessionTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAutomationSessions Deletes all matched (by cnd) rows in automation_sessions with given data
-func (s Store) execDeleteAutomationSessions(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.automationSessionTable("atms")).Where(cnd))
-}
-
-func (s Store) internalAutomationSessionRowScanner(row rowScanner) (res *types.Session, err error) {
- res = &types.Session{}
-
- err = row.Scan(
- &res.ID,
- &res.WorkflowID,
- &res.EventType,
- &res.ResourceType,
- &res.Status,
- &res.Input,
- &res.Output,
- &res.Stacktrace,
- &res.CreatedBy,
- &res.CreatedAt,
- &res.PurgeAt,
- &res.CompletedAt,
- &res.SuspendedAt,
- &res.Error,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan automationSession db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAutomationSessions returns squirrel.SelectBuilder with set table and all columns
-func (s Store) automationSessionsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.automationSessionTable("atms"), s.automationSessionColumns("atms")...)
-}
-
-// automationSessionTable name of the db table
-func (Store) automationSessionTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "automation_sessions" + alias
-}
-
-// AutomationSessionColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) automationSessionColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_workflow",
- alias + "event_type",
- alias + "resource_type",
- alias + "status",
- alias + "input",
- alias + "output",
- alias + "stacktrace",
- alias + "created_by",
- alias + "created_at",
- alias + "purge_at",
- alias + "completed_at",
- alias + "suspended_at",
- alias + "error",
- }
-}
-
-// {true true false true true true}
-
-// sortableAutomationSessionColumns returns all AutomationSession columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableAutomationSessionColumns() map[string]string {
- return map[string]string{
- "id": "id", "event_type": "event_type",
- "eventtype": "event_type",
- "resource_type": "resource_type",
- "resourcetype": "resource_type",
- "status": "status", "created_at": "created_at",
- "createdat": "created_at",
- "completed_at": "completed_at",
- "completedat": "completed_at",
- "suspended_at": "suspended_at",
- "suspendedat": "suspended_at",
- }
-}
-
-// internalAutomationSessionEncoder encodes fields from types.Session to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAutomationSession
-// func when rdbms.customEncoder=true
-func (s Store) internalAutomationSessionEncoder(res *types.Session) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_workflow": res.WorkflowID,
- "event_type": res.EventType,
- "resource_type": res.ResourceType,
- "status": res.Status,
- "input": res.Input,
- "output": res.Output,
- "stacktrace": res.Stacktrace,
- "created_by": res.CreatedBy,
- "created_at": res.CreatedAt,
- "purge_at": res.PurgeAt,
- "completed_at": res.CompletedAt,
- "suspended_at": res.SuspendedAt,
- "error": res.Error,
- }
-}
-
-// collectAutomationSessionCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectAutomationSessionCursorValues(res *types.Session, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "event_type":
- cursor.Set(c.Column, res.EventType, c.Descending)
-
- case "resource_type":
- cursor.Set(c.Column, res.ResourceType, c.Descending)
-
- case "status":
- cursor.Set(c.Column, res.Status, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "completed_at":
- cursor.Set(c.Column, res.CompletedAt, c.Descending)
-
- case "suspended_at":
- cursor.Set(c.Column, res.SuspendedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkAutomationSessionConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAutomationSessionConstraints(ctx context.Context, res *types.Session) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/automation_sessions.go b/store/rdbms/automation_sessions.go
deleted file mode 100644
index d8ab5ac8a..000000000
--- a/store/rdbms/automation_sessions.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/automation/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertAutomationSessionFilter(f types.SessionFilter) (query squirrel.SelectBuilder, err error) {
- query = s.automationSessionsSelectBuilder()
-
- query = filter.StateCondition(query, "atms.completed_at", f.Completed)
-
- if len(f.SessionID) > 0 {
- query = query.Where(squirrel.Eq{"atms.id": f.SessionID})
- }
-
- if len(f.CreatedBy) > 0 {
- query = query.Where(squirrel.Eq{"atms.created_by": f.CreatedBy})
- }
-
- if len(f.Status) > 0 {
- query = query.Where(squirrel.Eq{"atms.status": f.Status})
- }
-
- if len(f.WorkflowID) > 0 {
- query = query.Where(squirrel.Eq{"atms.rel_workflow": f.WorkflowID})
- }
-
- if len(f.EventType) > 0 {
- query = query.Where(squirrel.Eq{"atms.event_type": f.EventType})
- }
-
- if len(f.ResourceType) > 0 {
- query = query.Where(squirrel.Eq{"atms.resource_type": f.ResourceType})
- }
-
- return
-}
diff --git a/store/rdbms/automation_triggers.gen.go b/store/rdbms/automation_triggers.gen.go
deleted file mode 100644
index c8d5f0c32..000000000
--- a/store/rdbms/automation_triggers.gen.go
+++ /dev/null
@@ -1,611 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/automation_triggers.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/automation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchAutomationTriggers returns all matching rows
-//
-// This function calls convertAutomationTriggerFilter with the given
-// types.TriggerFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAutomationTriggers(ctx context.Context, f types.TriggerFilter) (types.TriggerSet, types.TriggerFilter, error) {
- var (
- err error
- set []*types.Trigger
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAutomationTriggerFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableAutomationTriggerColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAutomationTriggers(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfAutomationTriggers collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfAutomationTriggers(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Trigger) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Trigger, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Trigger
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Trigger, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryAutomationTriggers(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectAutomationTriggerCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectAutomationTriggerCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectAutomationTriggerCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryAutomationTriggers queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAutomationTriggers(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Trigger) (bool, error),
-) ([]*types.Trigger, error) {
- var (
- tmp = make([]*types.Trigger, 0, DefaultSliceCapacity)
- set = make([]*types.Trigger, 0, DefaultSliceCapacity)
- res *types.Trigger
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAutomationTriggerRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAutomationTriggerByID searches for trigger by ID
-//
-// It returns trigger even if deleted
-func (s Store) LookupAutomationTriggerByID(ctx context.Context, id uint64) (*types.Trigger, error) {
- return s.execLookupAutomationTrigger(ctx, squirrel.Eq{
- s.preprocessColumn("atmt.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateAutomationTrigger creates one or more rows in automation_triggers table
-func (s Store) CreateAutomationTrigger(ctx context.Context, rr ...*types.Trigger) (err error) {
- for _, res := range rr {
- err = s.checkAutomationTriggerConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAutomationTriggers(ctx, s.internalAutomationTriggerEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAutomationTrigger updates one or more existing rows in automation_triggers
-func (s Store) UpdateAutomationTrigger(ctx context.Context, rr ...*types.Trigger) error {
- return s.partialAutomationTriggerUpdate(ctx, nil, rr...)
-}
-
-// partialAutomationTriggerUpdate updates one or more existing rows in automation_triggers
-func (s Store) partialAutomationTriggerUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Trigger) (err error) {
- for _, res := range rr {
- err = s.checkAutomationTriggerConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAutomationTriggers(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("atmt.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalAutomationTriggerEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAutomationTrigger updates one or more existing rows in automation_triggers
-func (s Store) UpsertAutomationTrigger(ctx context.Context, rr ...*types.Trigger) (err error) {
- for _, res := range rr {
- err = s.checkAutomationTriggerConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAutomationTriggers(ctx, s.internalAutomationTriggerEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAutomationTrigger Deletes one or more rows from automation_triggers table
-func (s Store) DeleteAutomationTrigger(ctx context.Context, rr ...*types.Trigger) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAutomationTriggers(ctx, squirrel.Eq{
- s.preprocessColumn("atmt.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAutomationTriggerByID Deletes row from the automation_triggers table
-func (s Store) DeleteAutomationTriggerByID(ctx context.Context, ID uint64) error {
- return s.execDeleteAutomationTriggers(ctx, squirrel.Eq{
- s.preprocessColumn("atmt.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAutomationTriggers Deletes all rows from the automation_triggers table
-func (s Store) TruncateAutomationTriggers(ctx context.Context) error {
- return s.Truncate(ctx, s.automationTriggerTable())
-}
-
-// execLookupAutomationTrigger prepares AutomationTrigger query and executes it,
-// returning types.Trigger (or error)
-func (s Store) execLookupAutomationTrigger(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Trigger, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.automationTriggersSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAutomationTriggerRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAutomationTriggers updates all matched (by cnd) rows in automation_triggers with given data
-func (s Store) execCreateAutomationTriggers(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.automationTriggerTable()).SetMap(payload))
-}
-
-// execUpdateAutomationTriggers updates all matched (by cnd) rows in automation_triggers with given data
-func (s Store) execUpdateAutomationTriggers(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.automationTriggerTable("atmt")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAutomationTriggers inserts new or updates matching (by-primary-key) rows in automation_triggers with given data
-func (s Store) execUpsertAutomationTriggers(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.automationTriggerTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAutomationTriggers Deletes all matched (by cnd) rows in automation_triggers with given data
-func (s Store) execDeleteAutomationTriggers(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.automationTriggerTable("atmt")).Where(cnd))
-}
-
-func (s Store) internalAutomationTriggerRowScanner(row rowScanner) (res *types.Trigger, err error) {
- res = &types.Trigger{}
-
- err = row.Scan(
- &res.ID,
- &res.WorkflowID,
- &res.StepID,
- &res.Enabled,
- &res.ResourceType,
- &res.EventType,
- &res.Meta,
- &res.Constraints,
- &res.Input,
- &res.OwnedBy,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan automationTrigger db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAutomationTriggers returns squirrel.SelectBuilder with set table and all columns
-func (s Store) automationTriggersSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.automationTriggerTable("atmt"), s.automationTriggerColumns("atmt")...)
-}
-
-// automationTriggerTable name of the db table
-func (Store) automationTriggerTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "automation_triggers" + alias
-}
-
-// AutomationTriggerColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) automationTriggerColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_workflow",
- alias + "rel_step",
- alias + "enabled",
- alias + "resource_type",
- alias + "event_type",
- alias + "meta",
- alias + "constraints",
- alias + "input",
- alias + "owned_by",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableAutomationTriggerColumns returns all AutomationTrigger columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableAutomationTriggerColumns() map[string]string {
- return map[string]string{
- "id": "id",
- }
-}
-
-// internalAutomationTriggerEncoder encodes fields from types.Trigger to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAutomationTrigger
-// func when rdbms.customEncoder=true
-func (s Store) internalAutomationTriggerEncoder(res *types.Trigger) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_workflow": res.WorkflowID,
- "rel_step": res.StepID,
- "enabled": res.Enabled,
- "resource_type": res.ResourceType,
- "event_type": res.EventType,
- "meta": res.Meta,
- "constraints": res.Constraints,
- "input": res.Input,
- "owned_by": res.OwnedBy,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectAutomationTriggerCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectAutomationTriggerCursorValues(res *types.Trigger, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkAutomationTriggerConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAutomationTriggerConstraints(ctx context.Context, res *types.Trigger) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/automation_triggers.go b/store/rdbms/automation_triggers.go
deleted file mode 100644
index 46f717d40..000000000
--- a/store/rdbms/automation_triggers.go
+++ /dev/null
@@ -1,36 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/automation/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertAutomationTriggerFilter(f types.TriggerFilter) (query squirrel.SelectBuilder, err error) {
- query = s.automationTriggersSelectBuilder()
-
- query = filter.StateCondition(query, "atmt.deleted_at", f.Deleted)
- query = filter.StateConditionNegBool(query, "atmt.enabled", f.Disabled)
-
- if len(f.TriggerID) > 0 {
- query = query.Where(squirrel.Eq{"atmt.id": f.TriggerID})
- }
-
- if len(f.WorkflowID) > 0 {
- query = query.Where(squirrel.Eq{"atmt.rel_workflow": f.WorkflowID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"atmt.id": f.LabeledIDs})
- }
-
- if len(f.EventType) > 0 {
- query = query.Where(squirrel.Eq{"atmt.event_type": f.EventType})
- }
-
- if len(f.ResourceType) > 0 {
- query = query.Where(squirrel.Eq{"atmt.resource_type": f.ResourceType})
- }
-
- return
-}
diff --git a/store/rdbms/automation_workflows.gen.go b/store/rdbms/automation_workflows.gen.go
deleted file mode 100644
index d8d600bf0..000000000
--- a/store/rdbms/automation_workflows.gen.go
+++ /dev/null
@@ -1,666 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/automation_workflows.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/automation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchAutomationWorkflows returns all matching rows
-//
-// This function calls convertAutomationWorkflowFilter with the given
-// types.WorkflowFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchAutomationWorkflows(ctx context.Context, f types.WorkflowFilter) (types.WorkflowSet, types.WorkflowFilter, error) {
- var (
- err error
- set []*types.Workflow
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertAutomationWorkflowFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableAutomationWorkflowColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfAutomationWorkflows(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfAutomationWorkflows collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfAutomationWorkflows(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Workflow) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Workflow, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Workflow
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Workflow, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryAutomationWorkflows(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectAutomationWorkflowCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectAutomationWorkflowCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectAutomationWorkflowCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryAutomationWorkflows queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryAutomationWorkflows(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Workflow) (bool, error),
-) ([]*types.Workflow, error) {
- var (
- tmp = make([]*types.Workflow, 0, DefaultSliceCapacity)
- set = make([]*types.Workflow, 0, DefaultSliceCapacity)
- res *types.Workflow
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalAutomationWorkflowRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupAutomationWorkflowByID searches for workflow by ID
-//
-// It returns workflow even if deleted
-func (s Store) LookupAutomationWorkflowByID(ctx context.Context, id uint64) (*types.Workflow, error) {
- return s.execLookupAutomationWorkflow(ctx, squirrel.Eq{
- s.preprocessColumn("atmwf.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupAutomationWorkflowByHandle searches for workflow by their handle
-//
-// It returns only valid workflows
-func (s Store) LookupAutomationWorkflowByHandle(ctx context.Context, handle string) (*types.Workflow, error) {
- return s.execLookupAutomationWorkflow(ctx, squirrel.Eq{
- s.preprocessColumn("atmwf.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "atmwf.deleted_at": nil,
- })
-}
-
-// CreateAutomationWorkflow creates one or more rows in automation_workflows table
-func (s Store) CreateAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) (err error) {
- for _, res := range rr {
- err = s.checkAutomationWorkflowConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateAutomationWorkflows(ctx, s.internalAutomationWorkflowEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateAutomationWorkflow updates one or more existing rows in automation_workflows
-func (s Store) UpdateAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) error {
- return s.partialAutomationWorkflowUpdate(ctx, nil, rr...)
-}
-
-// partialAutomationWorkflowUpdate updates one or more existing rows in automation_workflows
-func (s Store) partialAutomationWorkflowUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Workflow) (err error) {
- for _, res := range rr {
- err = s.checkAutomationWorkflowConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateAutomationWorkflows(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("atmwf.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalAutomationWorkflowEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertAutomationWorkflow updates one or more existing rows in automation_workflows
-func (s Store) UpsertAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) (err error) {
- for _, res := range rr {
- err = s.checkAutomationWorkflowConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertAutomationWorkflows(ctx, s.internalAutomationWorkflowEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAutomationWorkflow Deletes one or more rows from automation_workflows table
-func (s Store) DeleteAutomationWorkflow(ctx context.Context, rr ...*types.Workflow) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteAutomationWorkflows(ctx, squirrel.Eq{
- s.preprocessColumn("atmwf.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteAutomationWorkflowByID Deletes row from the automation_workflows table
-func (s Store) DeleteAutomationWorkflowByID(ctx context.Context, ID uint64) error {
- return s.execDeleteAutomationWorkflows(ctx, squirrel.Eq{
- s.preprocessColumn("atmwf.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateAutomationWorkflows Deletes all rows from the automation_workflows table
-func (s Store) TruncateAutomationWorkflows(ctx context.Context) error {
- return s.Truncate(ctx, s.automationWorkflowTable())
-}
-
-// execLookupAutomationWorkflow prepares AutomationWorkflow query and executes it,
-// returning types.Workflow (or error)
-func (s Store) execLookupAutomationWorkflow(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Workflow, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.automationWorkflowsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalAutomationWorkflowRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateAutomationWorkflows updates all matched (by cnd) rows in automation_workflows with given data
-func (s Store) execCreateAutomationWorkflows(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.automationWorkflowTable()).SetMap(payload))
-}
-
-// execUpdateAutomationWorkflows updates all matched (by cnd) rows in automation_workflows with given data
-func (s Store) execUpdateAutomationWorkflows(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.automationWorkflowTable("atmwf")).Where(cnd).SetMap(set))
-}
-
-// execUpsertAutomationWorkflows inserts new or updates matching (by-primary-key) rows in automation_workflows with given data
-func (s Store) execUpsertAutomationWorkflows(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.automationWorkflowTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteAutomationWorkflows Deletes all matched (by cnd) rows in automation_workflows with given data
-func (s Store) execDeleteAutomationWorkflows(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.automationWorkflowTable("atmwf")).Where(cnd))
-}
-
-func (s Store) internalAutomationWorkflowRowScanner(row rowScanner) (res *types.Workflow, err error) {
- res = &types.Workflow{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Meta,
- &res.Enabled,
- &res.Trace,
- &res.KeepSessions,
- &res.Scope,
- &res.Steps,
- &res.Paths,
- &res.Issues,
- &res.RunAs,
- &res.OwnedBy,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan automationWorkflow db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryAutomationWorkflows returns squirrel.SelectBuilder with set table and all columns
-func (s Store) automationWorkflowsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.automationWorkflowTable("atmwf"), s.automationWorkflowColumns("atmwf")...)
-}
-
-// automationWorkflowTable name of the db table
-func (Store) automationWorkflowTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "automation_workflows" + alias
-}
-
-// AutomationWorkflowColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) automationWorkflowColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "meta",
- alias + "enabled",
- alias + "trace",
- alias + "keep_sessions",
- alias + "scope",
- alias + "steps",
- alias + "paths",
- alias + "issues",
- alias + "run_as",
- alias + "owned_by",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableAutomationWorkflowColumns returns all AutomationWorkflow columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableAutomationWorkflowColumns() map[string]string {
- return map[string]string{
- "id": "id", "handle": "handle", "enabled": "enabled", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalAutomationWorkflowEncoder encodes fields from types.Workflow to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeAutomationWorkflow
-// func when rdbms.customEncoder=true
-func (s Store) internalAutomationWorkflowEncoder(res *types.Workflow) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "meta": res.Meta,
- "enabled": res.Enabled,
- "trace": res.Trace,
- "keep_sessions": res.KeepSessions,
- "scope": res.Scope,
- "steps": res.Steps,
- "paths": res.Paths,
- "issues": res.Issues,
- "run_as": res.RunAs,
- "owned_by": res.OwnedBy,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectAutomationWorkflowCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectAutomationWorkflowCursorValues(res *types.Workflow, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
- hasUnique = true
-
- case "enabled":
- cursor.Set(c.Column, res.Enabled, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkAutomationWorkflowConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkAutomationWorkflowConstraints(ctx context.Context, res *types.Workflow) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Handle) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Handle if AutomationWorkflow does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupAutomationWorkflowByHandle(ctx, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/automation_workflows.go b/store/rdbms/automation_workflows.go
deleted file mode 100644
index 2b73eb5c1..000000000
--- a/store/rdbms/automation_workflows.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/automation/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertAutomationWorkflowFilter(f types.WorkflowFilter) (query squirrel.SelectBuilder, err error) {
- query = s.automationWorkflowsSelectBuilder()
-
- query = filter.StateCondition(query, "atmwf.deleted_at", f.Deleted)
- query = filter.StateConditionNegBool(query, "atmwf.enabled", f.Disabled)
-
- if len(f.WorkflowID) > 0 {
- query = query.Where(squirrel.Eq{"atmwf.id": f.WorkflowID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"atmwf.id": f.LabeledIDs})
- }
-
- if f.Query != "" {
- qs := "%" + f.Query + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"atmwf.handle": qs},
- })
- }
-
- return
-}
diff --git a/store/rdbms/builder.go b/store/rdbms/builder.go
deleted file mode 100644
index 492a9b456..000000000
--- a/store/rdbms/builder.go
+++ /dev/null
@@ -1,54 +0,0 @@
-package rdbms
-
-import (
- "fmt"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
- "strings"
-)
-
-// UpsertBuilder combines insert and update builder into upsert (INSERT ... ON CONFLICT UPDATE ...)
-//
-// It accepts name of the table we're inserting to, payload with values that should be inserted and list of
-// columns that represent unique keys
-//
-// https://www.postgresql.org/docs/12/sql-insert.html
-// https://sqlite.org/lang_UPSERT.html
-func UpsertBuilder(cfg *Config, table string, payload store.Payload, columns ...string) (squirrel.InsertBuilder, error) {
- var (
- updateCond = squirrel.Eq{}
- updatePayload = store.Payload{}
-
- // where to cutoff the update query
- updateCutoff = len("UPDATE " + table + " ")
- )
-
- for k, v := range payload {
- updatePayload[k] = v
- }
-
- for _, c := range columns {
- if _, has := updatePayload[c]; has {
- delete(updatePayload, c)
- updateCond[c] = payload[c]
- }
- }
-
- sql, args, err := squirrel.
- Update(table).
- SetMap(updatePayload).
- //Where(updateCond).
- ToSql()
-
- if err != nil {
- return squirrel.InsertBuilder{}, err
- }
-
- suffix := fmt.Sprintf("ON CONFLICT (%s) DO UPDATE %s", strings.Join(columns, ","), sql[updateCutoff:])
-
- return squirrel.
- Insert(table).
- PlaceholderFormat(cfg.PlaceholderFormat).
- SetMap(payload).
- Suffix(suffix, args...), nil
-}
diff --git a/store/rdbms/builder_test.go b/store/rdbms/builder_test.go
deleted file mode 100644
index b3ba1320f..000000000
--- a/store/rdbms/builder_test.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/stretchr/testify/require"
- "testing"
-)
-
-func TestBuilder(t *testing.T) {
- var (
- req = require.New(t)
- cfg = &Config{PlaceholderFormat: squirrel.Question}
- )
-
- upsert, err := UpsertBuilder(cfg, "tbl", store.Payload{"c1": "v1", "c2": "v2"}, "c1")
- req.NoError(err)
- sql, args, err := upsert.ToSql()
- req.NoError(err)
- req.Contains(sql, "ON CONFLICT (c1) DO UPDATE SET")
- req.Contains(sql, "INSERT INTO tbl")
- req.Equal([]interface{}{"v1", "v2", "v2"}, args)
-
-}
diff --git a/store/rdbms/builders/README.adoc b/store/rdbms/builders/README.adoc
deleted file mode 100644
index 483c7cf02..000000000
--- a/store/rdbms/builders/README.adoc
+++ /dev/null
@@ -1,3 +0,0 @@
-= SQL builders
-
-Plan: generalize and move all query builders here.
diff --git a/store/rdbms/compose_attachments.gen.go b/store/rdbms/compose_attachments.gen.go
deleted file mode 100644
index 5e8f6a8e7..000000000
--- a/store/rdbms/compose_attachments.gen.go
+++ /dev/null
@@ -1,361 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_attachments.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchComposeAttachments returns all matching rows
-//
-// This function calls convertComposeAttachmentFilter with the given
-// types.AttachmentFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchComposeAttachments(ctx context.Context, f types.AttachmentFilter) (types.AttachmentSet, types.AttachmentFilter, error) {
- var (
- err error
- set []*types.Attachment
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposeAttachmentFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryComposeAttachments(ctx, q, f.Check)
- return err
- }()
-}
-
-// QueryComposeAttachments queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeAttachments(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Attachment) (bool, error),
-) ([]*types.Attachment, error) {
- var (
- tmp = make([]*types.Attachment, 0, DefaultSliceCapacity)
- set = make([]*types.Attachment, 0, DefaultSliceCapacity)
- res *types.Attachment
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeAttachmentRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupComposeAttachmentByID searches for attachment by its ID
-//
-// It returns attachment even if deleted
-func (s Store) LookupComposeAttachmentByID(ctx context.Context, id uint64) (*types.Attachment, error) {
- return s.execLookupComposeAttachment(ctx, squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateComposeAttachment creates one or more rows in compose_attachment table
-func (s Store) CreateComposeAttachment(ctx context.Context, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
- err = s.checkComposeAttachmentConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeAttachments(ctx, s.internalComposeAttachmentEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateComposeAttachment updates one or more existing rows in compose_attachment
-func (s Store) UpdateComposeAttachment(ctx context.Context, rr ...*types.Attachment) error {
- return s.partialComposeAttachmentUpdate(ctx, nil, rr...)
-}
-
-// partialComposeAttachmentUpdate updates one or more existing rows in compose_attachment
-func (s Store) partialComposeAttachmentUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
- err = s.checkComposeAttachmentConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeAttachments(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposeAttachmentEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertComposeAttachment updates one or more existing rows in compose_attachment
-func (s Store) UpsertComposeAttachment(ctx context.Context, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
- err = s.checkComposeAttachmentConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeAttachments(ctx, s.internalComposeAttachmentEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeAttachment Deletes one or more rows from compose_attachment table
-func (s Store) DeleteComposeAttachment(ctx context.Context, rr ...*types.Attachment) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeAttachments(ctx, squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeAttachmentByID Deletes row from the compose_attachment table
-func (s Store) DeleteComposeAttachmentByID(ctx context.Context, ID uint64) error {
- return s.execDeleteComposeAttachments(ctx, squirrel.Eq{
- s.preprocessColumn("att.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateComposeAttachments Deletes all rows from the compose_attachment table
-func (s Store) TruncateComposeAttachments(ctx context.Context) error {
- return s.Truncate(ctx, s.composeAttachmentTable())
-}
-
-// execLookupComposeAttachment prepares ComposeAttachment query and executes it,
-// returning types.Attachment (or error)
-func (s Store) execLookupComposeAttachment(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Attachment, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeAttachmentsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeAttachmentRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposeAttachments updates all matched (by cnd) rows in compose_attachment with given data
-func (s Store) execCreateComposeAttachments(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeAttachmentTable()).SetMap(payload))
-}
-
-// execUpdateComposeAttachments updates all matched (by cnd) rows in compose_attachment with given data
-func (s Store) execUpdateComposeAttachments(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeAttachmentTable("att")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeAttachments inserts new or updates matching (by-primary-key) rows in compose_attachment with given data
-func (s Store) execUpsertComposeAttachments(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeAttachmentTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeAttachments Deletes all matched (by cnd) rows in compose_attachment with given data
-func (s Store) execDeleteComposeAttachments(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeAttachmentTable("att")).Where(cnd))
-}
-
-func (s Store) internalComposeAttachmentRowScanner(row rowScanner) (res *types.Attachment, err error) {
- res = &types.Attachment{}
-
- err = row.Scan(
- &res.ID,
- &res.NamespaceID,
- &res.Kind,
- &res.Url,
- &res.PreviewUrl,
- &res.Name,
- &res.Meta,
- &res.OwnerID,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeAttachment db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeAttachments returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeAttachmentsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeAttachmentTable("att"), s.composeAttachmentColumns("att")...)
-}
-
-// composeAttachmentTable name of the db table
-func (Store) composeAttachmentTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_attachment" + alias
-}
-
-// ComposeAttachmentColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeAttachmentColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_namespace",
- alias + "kind",
- alias + "url",
- alias + "preview_url",
- alias + "name",
- alias + "meta",
- alias + "rel_owner",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false false false true}
-
-// internalComposeAttachmentEncoder encodes fields from types.Attachment to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeAttachment
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeAttachmentEncoder(res *types.Attachment) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_namespace": res.NamespaceID,
- "kind": res.Kind,
- "url": res.Url,
- "preview_url": res.PreviewUrl,
- "name": res.Name,
- "meta": res.Meta,
- "rel_owner": res.OwnerID,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkComposeAttachmentConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeAttachmentConstraints(ctx context.Context, res *types.Attachment) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_attachments.go b/store/rdbms/compose_attachments.go
deleted file mode 100644
index 1bff81aac..000000000
--- a/store/rdbms/compose_attachments.go
+++ /dev/null
@@ -1,57 +0,0 @@
-package rdbms
-
-import (
- "fmt"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
-)
-
-func (s Store) convertComposeAttachmentFilter(f types.AttachmentFilter) (query squirrel.SelectBuilder, err error) {
- query = s.attachmentsSelectBuilder()
-
- if f.Kind != "" {
- query = query.Where(squirrel.Eq{"att.kind": f.Kind})
- }
-
- if f.NamespaceID > 0 {
- query = query.Where("a.rel_namespace = ?", f.NamespaceID)
- }
-
- switch f.Kind {
- case types.PageAttachment:
- // @todo implement filtering by page
- if f.PageID > 0 {
- err = fmt.Errorf("filtering by pageID not implemented")
- return
- }
-
- case types.RecordAttachment:
- query = query.
- Join("compose_record_value AS v ON (v.ref = a.id)")
-
- if f.ModuleID > 0 {
- query = query.
- Join("compose_record AS r ON (r.id = v.record_id)").
- Where(squirrel.Eq{"r.module_id": f.ModuleID})
- }
-
- if f.RecordID > 0 {
- query = query.Where(squirrel.Eq{"v.record_id": f.RecordID})
- }
-
- if f.FieldName != "" {
- query = query.Where(squirrel.Eq{"v.name": f.FieldName})
- }
-
- default:
- err = fmt.Errorf("unsupported kind value")
- return
- }
-
- if f.Filter != "" {
- err = fmt.Errorf("filtering by filter not implemented")
- return
- }
-
- return
-}
diff --git a/store/rdbms/compose_charts.gen.go b/store/rdbms/compose_charts.gen.go
deleted file mode 100644
index 450696c21..000000000
--- a/store/rdbms/compose_charts.gen.go
+++ /dev/null
@@ -1,617 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_charts.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchComposeCharts returns all matching rows
-//
-// This function calls convertComposeChartFilter with the given
-// types.ChartFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchComposeCharts(ctx context.Context, f types.ChartFilter) (types.ChartSet, types.ChartFilter, error) {
- var (
- err error
- set []*types.Chart
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposeChartFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableComposeChartColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeCharts(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfComposeCharts collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfComposeCharts(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Chart) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Chart, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Chart
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Chart, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryComposeCharts(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectComposeChartCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectComposeChartCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectComposeChartCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryComposeCharts queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeCharts(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Chart) (bool, error),
-) ([]*types.Chart, error) {
- var (
- tmp = make([]*types.Chart, 0, DefaultSliceCapacity)
- set = make([]*types.Chart, 0, DefaultSliceCapacity)
- res *types.Chart
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeChartRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupComposeChartByID searches for compose chart by ID
-//
-// It returns compose chart even if deleted
-func (s Store) LookupComposeChartByID(ctx context.Context, id uint64) (*types.Chart, error) {
- return s.execLookupComposeChart(ctx, squirrel.Eq{
- s.preprocessColumn("cch.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupComposeChartByNamespaceIDHandle searches for compose chart by handle (case-insensitive)
-func (s Store) LookupComposeChartByNamespaceIDHandle(ctx context.Context, namespace_id uint64, handle string) (*types.Chart, error) {
- return s.execLookupComposeChart(ctx, squirrel.Eq{
- s.preprocessColumn("cch.rel_namespace", ""): store.PreprocessValue(namespace_id, ""),
- s.preprocessColumn("cch.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "cch.deleted_at": nil,
- })
-}
-
-// CreateComposeChart creates one or more rows in compose_chart table
-func (s Store) CreateComposeChart(ctx context.Context, rr ...*types.Chart) (err error) {
- for _, res := range rr {
- err = s.checkComposeChartConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeCharts(ctx, s.internalComposeChartEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateComposeChart updates one or more existing rows in compose_chart
-func (s Store) UpdateComposeChart(ctx context.Context, rr ...*types.Chart) error {
- return s.partialComposeChartUpdate(ctx, nil, rr...)
-}
-
-// partialComposeChartUpdate updates one or more existing rows in compose_chart
-func (s Store) partialComposeChartUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Chart) (err error) {
- for _, res := range rr {
- err = s.checkComposeChartConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeCharts(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cch.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposeChartEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertComposeChart updates one or more existing rows in compose_chart
-func (s Store) UpsertComposeChart(ctx context.Context, rr ...*types.Chart) (err error) {
- for _, res := range rr {
- err = s.checkComposeChartConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeCharts(ctx, s.internalComposeChartEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeChart Deletes one or more rows from compose_chart table
-func (s Store) DeleteComposeChart(ctx context.Context, rr ...*types.Chart) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeCharts(ctx, squirrel.Eq{
- s.preprocessColumn("cch.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeChartByID Deletes row from the compose_chart table
-func (s Store) DeleteComposeChartByID(ctx context.Context, ID uint64) error {
- return s.execDeleteComposeCharts(ctx, squirrel.Eq{
- s.preprocessColumn("cch.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateComposeCharts Deletes all rows from the compose_chart table
-func (s Store) TruncateComposeCharts(ctx context.Context) error {
- return s.Truncate(ctx, s.composeChartTable())
-}
-
-// execLookupComposeChart prepares ComposeChart query and executes it,
-// returning types.Chart (or error)
-func (s Store) execLookupComposeChart(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Chart, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeChartsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeChartRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposeCharts updates all matched (by cnd) rows in compose_chart with given data
-func (s Store) execCreateComposeCharts(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeChartTable()).SetMap(payload))
-}
-
-// execUpdateComposeCharts updates all matched (by cnd) rows in compose_chart with given data
-func (s Store) execUpdateComposeCharts(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeChartTable("cch")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeCharts inserts new or updates matching (by-primary-key) rows in compose_chart with given data
-func (s Store) execUpsertComposeCharts(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeChartTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeCharts Deletes all matched (by cnd) rows in compose_chart with given data
-func (s Store) execDeleteComposeCharts(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeChartTable("cch")).Where(cnd))
-}
-
-func (s Store) internalComposeChartRowScanner(row rowScanner) (res *types.Chart, err error) {
- res = &types.Chart{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Name,
- &res.Config,
- &res.NamespaceID,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeChart db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeCharts returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeChartsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeChartTable("cch"), s.composeChartColumns("cch")...)
-}
-
-// composeChartTable name of the db table
-func (Store) composeChartTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_chart" + alias
-}
-
-// ComposeChartColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeChartColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "name",
- alias + "config",
- alias + "rel_namespace",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableComposeChartColumns returns all ComposeChart columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableComposeChartColumns() map[string]string {
- return map[string]string{
- "id": "id", "handle": "handle", "name": "name", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalComposeChartEncoder encodes fields from types.Chart to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeChart
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeChartEncoder(res *types.Chart) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "name": res.Name,
- "config": res.Config,
- "rel_namespace": res.NamespaceID,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectComposeChartCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectComposeChartCursorValues(res *types.Chart, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
- hasUnique = true
-
- case "name":
- cursor.Set(c.Column, res.Name, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkComposeChartConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeChartConstraints(ctx context.Context, res *types.Chart) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_charts.go b/store/rdbms/compose_charts.go
deleted file mode 100644
index 673ba3f0a..000000000
--- a/store/rdbms/compose_charts.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package rdbms
-
-import (
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertComposeChartFilter(f types.ChartFilter) (query squirrel.SelectBuilder, err error) {
- query = s.composeChartsSelectBuilder()
-
- query = filter.StateCondition(query, "cch.deleted_at", f.Deleted)
-
- if len(f.ChartID) > 0 {
- query = query.Where(squirrel.Eq{"cch.id": f.ChartID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"cch.id": f.LabeledIDs})
- }
-
- if f.NamespaceID > 0 {
- query = query.Where("cch.rel_namespace = ?", f.NamespaceID)
- }
-
- if f.Query != "" {
- q := "%" + strings.ToLower(f.Query) + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"LOWER(cch.handle)": q},
- squirrel.Like{"LOWER(cch.name)": q},
- })
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"LOWER(cch.handle)": strings.ToLower(f.Handle)})
- }
-
- if f.Name != "" {
- query = query.Where(squirrel.Eq{"LOWER(cch.name)": strings.ToLower(f.Name)})
- }
-
- return
-}
diff --git a/store/rdbms/compose_module_fields.gen.go b/store/rdbms/compose_module_fields.gen.go
deleted file mode 100644
index 58c787d80..000000000
--- a/store/rdbms/compose_module_fields.gen.go
+++ /dev/null
@@ -1,387 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_module_fields.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchComposeModuleFields returns all matching rows
-//
-// This function calls convertComposeModuleFieldFilter with the given
-// types.ModuleFieldFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchComposeModuleFields(ctx context.Context, f types.ModuleFieldFilter) (types.ModuleFieldSet, types.ModuleFieldFilter, error) {
- var (
- err error
- set []*types.ModuleField
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposeModuleFieldFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryComposeModuleFields(ctx, q, nil)
- return err
- }()
-}
-
-// QueryComposeModuleFields queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeModuleFields(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ModuleField) (bool, error),
-) ([]*types.ModuleField, error) {
- var (
- tmp = make([]*types.ModuleField, 0, DefaultSliceCapacity)
- set = make([]*types.ModuleField, 0, DefaultSliceCapacity)
- res *types.ModuleField
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeModuleFieldRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupComposeModuleFieldByModuleIDName searches for compose module field by name (case-insensitive)
-func (s Store) LookupComposeModuleFieldByModuleIDName(ctx context.Context, module_id uint64, name string) (*types.ModuleField, error) {
- return s.execLookupComposeModuleField(ctx, squirrel.Eq{
- s.preprocessColumn("cmf.rel_module", ""): store.PreprocessValue(module_id, ""),
- s.preprocessColumn("cmf.name", "lower"): store.PreprocessValue(name, "lower"),
-
- "cmf.deleted_at": nil,
- })
-}
-
-// CreateComposeModuleField creates one or more rows in compose_module_field table
-func (s Store) CreateComposeModuleField(ctx context.Context, rr ...*types.ModuleField) (err error) {
- for _, res := range rr {
- err = s.checkComposeModuleFieldConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeModuleFields(ctx, s.internalComposeModuleFieldEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateComposeModuleField updates one or more existing rows in compose_module_field
-func (s Store) UpdateComposeModuleField(ctx context.Context, rr ...*types.ModuleField) error {
- return s.partialComposeModuleFieldUpdate(ctx, nil, rr...)
-}
-
-// partialComposeModuleFieldUpdate updates one or more existing rows in compose_module_field
-func (s Store) partialComposeModuleFieldUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ModuleField) (err error) {
- for _, res := range rr {
- err = s.checkComposeModuleFieldConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeModuleFields(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cmf.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposeModuleFieldEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertComposeModuleField updates one or more existing rows in compose_module_field
-func (s Store) UpsertComposeModuleField(ctx context.Context, rr ...*types.ModuleField) (err error) {
- for _, res := range rr {
- err = s.checkComposeModuleFieldConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeModuleFields(ctx, s.internalComposeModuleFieldEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeModuleField Deletes one or more rows from compose_module_field table
-func (s Store) DeleteComposeModuleField(ctx context.Context, rr ...*types.ModuleField) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeModuleFields(ctx, squirrel.Eq{
- s.preprocessColumn("cmf.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeModuleFieldByID Deletes row from the compose_module_field table
-func (s Store) DeleteComposeModuleFieldByID(ctx context.Context, ID uint64) error {
- return s.execDeleteComposeModuleFields(ctx, squirrel.Eq{
- s.preprocessColumn("cmf.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateComposeModuleFields Deletes all rows from the compose_module_field table
-func (s Store) TruncateComposeModuleFields(ctx context.Context) error {
- return s.Truncate(ctx, s.composeModuleFieldTable())
-}
-
-// execLookupComposeModuleField prepares ComposeModuleField query and executes it,
-// returning types.ModuleField (or error)
-func (s Store) execLookupComposeModuleField(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ModuleField, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeModuleFieldsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeModuleFieldRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposeModuleFields updates all matched (by cnd) rows in compose_module_field with given data
-func (s Store) execCreateComposeModuleFields(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeModuleFieldTable()).SetMap(payload))
-}
-
-// execUpdateComposeModuleFields updates all matched (by cnd) rows in compose_module_field with given data
-func (s Store) execUpdateComposeModuleFields(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeModuleFieldTable("cmf")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeModuleFields inserts new or updates matching (by-primary-key) rows in compose_module_field with given data
-func (s Store) execUpsertComposeModuleFields(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeModuleFieldTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeModuleFields Deletes all matched (by cnd) rows in compose_module_field with given data
-func (s Store) execDeleteComposeModuleFields(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeModuleFieldTable("cmf")).Where(cnd))
-}
-
-func (s Store) internalComposeModuleFieldRowScanner(row rowScanner) (res *types.ModuleField, err error) {
- res = &types.ModuleField{}
-
- err = row.Scan(
- &res.ID,
- &res.Name,
- &res.ModuleID,
- &res.Place,
- &res.Kind,
- &res.Label,
- &res.Options,
- &res.Private,
- &res.Required,
- &res.Visible,
- &res.Multi,
- &res.DefaultValue,
- &res.Expressions,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeModuleField db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeModuleFields returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeModuleFieldsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeModuleFieldTable("cmf"), s.composeModuleFieldColumns("cmf")...)
-}
-
-// composeModuleFieldTable name of the db table
-func (Store) composeModuleFieldTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_module_field" + alias
-}
-
-// ComposeModuleFieldColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeModuleFieldColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "name",
- alias + "rel_module",
- alias + "place",
- alias + "kind",
- alias + "label",
- alias + "options",
- alias + "is_private",
- alias + "is_required",
- alias + "is_visible",
- alias + "is_multi",
- alias + "default_value",
- alias + "expressions",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false false false false}
-
-// internalComposeModuleFieldEncoder encodes fields from types.ModuleField to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeModuleField
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeModuleFieldEncoder(res *types.ModuleField) store.Payload {
- return store.Payload{
- "id": res.ID,
- "name": res.Name,
- "rel_module": res.ModuleID,
- "place": res.Place,
- "kind": res.Kind,
- "label": res.Label,
- "options": res.Options,
- "is_private": res.Private,
- "is_required": res.Required,
- "is_visible": res.Visible,
- "is_multi": res.Multi,
- "default_value": res.DefaultValue,
- "expressions": res.Expressions,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkComposeModuleFieldConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeModuleFieldConstraints(ctx context.Context, res *types.ModuleField) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && res.ModuleID > 0
-
- valid = valid && len(res.Name) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by ModuleIDName if ComposeModuleField does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupComposeModuleFieldByModuleIDName(ctx, res.ModuleID, res.Name)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_modules.gen.go b/store/rdbms/compose_modules.gen.go
deleted file mode 100644
index 0809208c9..000000000
--- a/store/rdbms/compose_modules.gen.go
+++ /dev/null
@@ -1,647 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_modules.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchComposeModules returns all matching rows
-//
-// This function calls convertComposeModuleFilter with the given
-// types.ModuleFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchComposeModules(ctx context.Context, f types.ModuleFilter) (types.ModuleSet, types.ModuleFilter, error) {
- var (
- err error
- set []*types.Module
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposeModuleFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableComposeModuleColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeModules(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfComposeModules collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfComposeModules(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Module) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Module, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Module
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Module, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryComposeModules(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectComposeModuleCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectComposeModuleCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectComposeModuleCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryComposeModules queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeModules(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Module) (bool, error),
-) ([]*types.Module, error) {
- var (
- tmp = make([]*types.Module, 0, DefaultSliceCapacity)
- set = make([]*types.Module, 0, DefaultSliceCapacity)
- res *types.Module
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeModuleRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupComposeModuleByNamespaceIDHandle searches for compose module by handle (case-insensitive)
-func (s Store) LookupComposeModuleByNamespaceIDHandle(ctx context.Context, namespace_id uint64, handle string) (*types.Module, error) {
- return s.execLookupComposeModule(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.rel_namespace", ""): store.PreprocessValue(namespace_id, ""),
- s.preprocessColumn("cmd.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "cmd.deleted_at": nil,
- })
-}
-
-// LookupComposeModuleByNamespaceIDName searches for compose module by name (case-insensitive)
-func (s Store) LookupComposeModuleByNamespaceIDName(ctx context.Context, namespace_id uint64, name string) (*types.Module, error) {
- return s.execLookupComposeModule(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.rel_namespace", ""): store.PreprocessValue(namespace_id, ""),
- s.preprocessColumn("cmd.name", "lower"): store.PreprocessValue(name, "lower"),
-
- "cmd.deleted_at": nil,
- })
-}
-
-// LookupComposeModuleByID searches for compose module by ID
-//
-// It returns compose module even if deleted
-func (s Store) LookupComposeModuleByID(ctx context.Context, id uint64) (*types.Module, error) {
- return s.execLookupComposeModule(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateComposeModule creates one or more rows in compose_module table
-func (s Store) CreateComposeModule(ctx context.Context, rr ...*types.Module) (err error) {
- for _, res := range rr {
- err = s.checkComposeModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeModules(ctx, s.internalComposeModuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateComposeModule updates one or more existing rows in compose_module
-func (s Store) UpdateComposeModule(ctx context.Context, rr ...*types.Module) error {
- return s.partialComposeModuleUpdate(ctx, nil, rr...)
-}
-
-// partialComposeModuleUpdate updates one or more existing rows in compose_module
-func (s Store) partialComposeModuleUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Module) (err error) {
- for _, res := range rr {
- err = s.checkComposeModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeModules(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposeModuleEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertComposeModule updates one or more existing rows in compose_module
-func (s Store) UpsertComposeModule(ctx context.Context, rr ...*types.Module) (err error) {
- for _, res := range rr {
- err = s.checkComposeModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeModules(ctx, s.internalComposeModuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeModule Deletes one or more rows from compose_module table
-func (s Store) DeleteComposeModule(ctx context.Context, rr ...*types.Module) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeModules(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeModuleByID Deletes row from the compose_module table
-func (s Store) DeleteComposeModuleByID(ctx context.Context, ID uint64) error {
- return s.execDeleteComposeModules(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateComposeModules Deletes all rows from the compose_module table
-func (s Store) TruncateComposeModules(ctx context.Context) error {
- return s.Truncate(ctx, s.composeModuleTable())
-}
-
-// execLookupComposeModule prepares ComposeModule query and executes it,
-// returning types.Module (or error)
-func (s Store) execLookupComposeModule(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Module, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeModulesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeModuleRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposeModules updates all matched (by cnd) rows in compose_module with given data
-func (s Store) execCreateComposeModules(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeModuleTable()).SetMap(payload))
-}
-
-// execUpdateComposeModules updates all matched (by cnd) rows in compose_module with given data
-func (s Store) execUpdateComposeModules(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeModuleTable("cmd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeModules inserts new or updates matching (by-primary-key) rows in compose_module with given data
-func (s Store) execUpsertComposeModules(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeModuleTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeModules Deletes all matched (by cnd) rows in compose_module with given data
-func (s Store) execDeleteComposeModules(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeModuleTable("cmd")).Where(cnd))
-}
-
-func (s Store) internalComposeModuleRowScanner(row rowScanner) (res *types.Module, err error) {
- res = &types.Module{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Name,
- &res.Meta,
- &res.NamespaceID,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeModule db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeModules returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeModulesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeModuleTable("cmd"), s.composeModuleColumns("cmd")...)
-}
-
-// composeModuleTable name of the db table
-func (Store) composeModuleTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_module" + alias
-}
-
-// ComposeModuleColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeModuleColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "name",
- alias + "meta",
- alias + "rel_namespace",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableComposeModuleColumns returns all ComposeModule columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableComposeModuleColumns() map[string]string {
- return map[string]string{
- "id": "id", "handle": "handle", "name": "name", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalComposeModuleEncoder encodes fields from types.Module to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeModule
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeModuleEncoder(res *types.Module) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "name": res.Name,
- "meta": res.Meta,
- "rel_namespace": res.NamespaceID,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectComposeModuleCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectComposeModuleCursorValues(res *types.Module, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
- hasUnique = true
-
- case "name":
- cursor.Set(c.Column, res.Name, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkComposeModuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeModuleConstraints(ctx context.Context, res *types.Module) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && res.NamespaceID > 0
-
- valid = valid && len(res.Handle) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by NamespaceIDHandle if ComposeModule does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupComposeModuleByNamespaceIDHandle(ctx, res.NamespaceID, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_modules.go b/store/rdbms/compose_modules.go
deleted file mode 100644
index 20e6e9eaa..000000000
--- a/store/rdbms/compose_modules.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "strings"
-)
-
-func (s Store) convertComposeModuleFilter(f types.ModuleFilter) (query squirrel.SelectBuilder, err error) {
- query = s.composeModulesSelectBuilder()
-
- query = filter.StateCondition(query, "cmd.deleted_at", f.Deleted)
-
- if len(f.ModuleID) > 0 {
- query = query.Where(squirrel.Eq{"cmd.id": f.ModuleID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"cmd.id": f.LabeledIDs})
- }
-
- if f.NamespaceID > 0 {
- query = query.Where("cmd.rel_namespace = ?", f.NamespaceID)
- }
-
- if f.Query != "" {
- q := "%" + strings.ToLower(f.Query) + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"LOWER(cmd.name)": q},
- squirrel.Like{"LOWER(cmd.handle)": q},
- })
- }
-
- if f.Name != "" {
- query = query.Where(squirrel.Eq{"LOWER(cmd.name)": strings.ToLower(f.Name)})
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"LOWER(cmd.handle)": strings.ToLower(f.Handle)})
- }
-
- return
-}
diff --git a/store/rdbms/compose_modules_fields.go b/store/rdbms/compose_modules_fields.go
deleted file mode 100644
index fbdfa6161..000000000
--- a/store/rdbms/compose_modules_fields.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package rdbms
-
-import (
- "fmt"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertComposeModuleFieldFilter(f types.ModuleFieldFilter) (query squirrel.SelectBuilder, err error) {
- query = s.composeModuleFieldsSelectBuilder()
-
- if len(f.ModuleID) == 0 {
- err = fmt.Errorf("cannot search for module fields without module IDs")
- return
- }
-
- query = filter.StateCondition(query, "cmf.deleted_at", f.Deleted)
- query = query.Where(squirrel.Eq{"cmf.rel_module": f.ModuleID})
-
- return
-}
diff --git a/store/rdbms/compose_namespaces.gen.go b/store/rdbms/compose_namespaces.gen.go
deleted file mode 100644
index 0d7ce79b5..000000000
--- a/store/rdbms/compose_namespaces.gen.go
+++ /dev/null
@@ -1,634 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_namespaces.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchComposeNamespaces returns all matching rows
-//
-// This function calls convertComposeNamespaceFilter with the given
-// types.NamespaceFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchComposeNamespaces(ctx context.Context, f types.NamespaceFilter) (types.NamespaceSet, types.NamespaceFilter, error) {
- var (
- err error
- set []*types.Namespace
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposeNamespaceFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableComposeNamespaceColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeNamespaces(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfComposeNamespaces collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfComposeNamespaces(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Namespace) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Namespace, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Namespace
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Namespace, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryComposeNamespaces(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectComposeNamespaceCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectComposeNamespaceCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectComposeNamespaceCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryComposeNamespaces queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeNamespaces(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Namespace) (bool, error),
-) ([]*types.Namespace, error) {
- var (
- tmp = make([]*types.Namespace, 0, DefaultSliceCapacity)
- set = make([]*types.Namespace, 0, DefaultSliceCapacity)
- res *types.Namespace
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeNamespaceRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupComposeNamespaceBySlug searches for namespace by slug (case-insensitive)
-func (s Store) LookupComposeNamespaceBySlug(ctx context.Context, slug string) (*types.Namespace, error) {
- return s.execLookupComposeNamespace(ctx, squirrel.Eq{
- s.preprocessColumn("cns.slug", "lower"): store.PreprocessValue(slug, "lower"),
-
- "cns.deleted_at": nil,
- })
-}
-
-// LookupComposeNamespaceByID searches for compose namespace by ID
-//
-// It returns compose namespace even if deleted
-func (s Store) LookupComposeNamespaceByID(ctx context.Context, id uint64) (*types.Namespace, error) {
- return s.execLookupComposeNamespace(ctx, squirrel.Eq{
- s.preprocessColumn("cns.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateComposeNamespace creates one or more rows in compose_namespace table
-func (s Store) CreateComposeNamespace(ctx context.Context, rr ...*types.Namespace) (err error) {
- for _, res := range rr {
- err = s.checkComposeNamespaceConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeNamespaces(ctx, s.internalComposeNamespaceEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateComposeNamespace updates one or more existing rows in compose_namespace
-func (s Store) UpdateComposeNamespace(ctx context.Context, rr ...*types.Namespace) error {
- return s.partialComposeNamespaceUpdate(ctx, nil, rr...)
-}
-
-// partialComposeNamespaceUpdate updates one or more existing rows in compose_namespace
-func (s Store) partialComposeNamespaceUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Namespace) (err error) {
- for _, res := range rr {
- err = s.checkComposeNamespaceConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeNamespaces(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cns.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposeNamespaceEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertComposeNamespace updates one or more existing rows in compose_namespace
-func (s Store) UpsertComposeNamespace(ctx context.Context, rr ...*types.Namespace) (err error) {
- for _, res := range rr {
- err = s.checkComposeNamespaceConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeNamespaces(ctx, s.internalComposeNamespaceEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeNamespace Deletes one or more rows from compose_namespace table
-func (s Store) DeleteComposeNamespace(ctx context.Context, rr ...*types.Namespace) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeNamespaces(ctx, squirrel.Eq{
- s.preprocessColumn("cns.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposeNamespaceByID Deletes row from the compose_namespace table
-func (s Store) DeleteComposeNamespaceByID(ctx context.Context, ID uint64) error {
- return s.execDeleteComposeNamespaces(ctx, squirrel.Eq{
- s.preprocessColumn("cns.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateComposeNamespaces Deletes all rows from the compose_namespace table
-func (s Store) TruncateComposeNamespaces(ctx context.Context) error {
- return s.Truncate(ctx, s.composeNamespaceTable())
-}
-
-// execLookupComposeNamespace prepares ComposeNamespace query and executes it,
-// returning types.Namespace (or error)
-func (s Store) execLookupComposeNamespace(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Namespace, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeNamespacesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeNamespaceRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposeNamespaces updates all matched (by cnd) rows in compose_namespace with given data
-func (s Store) execCreateComposeNamespaces(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeNamespaceTable()).SetMap(payload))
-}
-
-// execUpdateComposeNamespaces updates all matched (by cnd) rows in compose_namespace with given data
-func (s Store) execUpdateComposeNamespaces(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeNamespaceTable("cns")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeNamespaces inserts new or updates matching (by-primary-key) rows in compose_namespace with given data
-func (s Store) execUpsertComposeNamespaces(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeNamespaceTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeNamespaces Deletes all matched (by cnd) rows in compose_namespace with given data
-func (s Store) execDeleteComposeNamespaces(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeNamespaceTable("cns")).Where(cnd))
-}
-
-func (s Store) internalComposeNamespaceRowScanner(row rowScanner) (res *types.Namespace, err error) {
- res = &types.Namespace{}
-
- err = row.Scan(
- &res.ID,
- &res.Name,
- &res.Slug,
- &res.Enabled,
- &res.Meta,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeNamespace db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeNamespaces returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeNamespacesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeNamespaceTable("cns"), s.composeNamespaceColumns("cns")...)
-}
-
-// composeNamespaceTable name of the db table
-func (Store) composeNamespaceTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_namespace" + alias
-}
-
-// ComposeNamespaceColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeNamespaceColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "name",
- alias + "slug",
- alias + "enabled",
- alias + "meta",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableComposeNamespaceColumns returns all ComposeNamespace columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableComposeNamespaceColumns() map[string]string {
- return map[string]string{
- "id": "id", "name": "name", "slug": "slug", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalComposeNamespaceEncoder encodes fields from types.Namespace to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeNamespace
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeNamespaceEncoder(res *types.Namespace) store.Payload {
- return store.Payload{
- "id": res.ID,
- "name": res.Name,
- "slug": res.Slug,
- "enabled": res.Enabled,
- "meta": res.Meta,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectComposeNamespaceCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectComposeNamespaceCursorValues(res *types.Namespace, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "name":
- cursor.Set(c.Column, res.Name, c.Descending)
-
- case "slug":
- cursor.Set(c.Column, res.Slug, c.Descending)
- hasUnique = true
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkComposeNamespaceConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeNamespaceConstraints(ctx context.Context, res *types.Namespace) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Slug) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Slug if ComposeNamespace does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupComposeNamespaceBySlug(ctx, res.Slug)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_namespaces.go b/store/rdbms/compose_namespaces.go
deleted file mode 100644
index 32a932f89..000000000
--- a/store/rdbms/compose_namespaces.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package rdbms
-
-import (
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertComposeNamespaceFilter(f types.NamespaceFilter) (query squirrel.SelectBuilder, err error) {
- query = s.composeNamespacesSelectBuilder()
-
- query = filter.StateCondition(query, "cns.deleted_at", f.Deleted)
-
- if len(f.NamespaceID) > 0 {
- query = query.Where(squirrel.Eq{"cns.id": f.NamespaceID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"cns.id": f.LabeledIDs})
- }
-
- if f.Query != "" {
- q := "%" + strings.ToLower(f.Query) + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"LOWER(cns.name)": q},
- squirrel.Like{"LOWER(cns.slug)": q},
- })
- }
-
- if f.Name != "" {
- query = query.Where(squirrel.Eq{"LOWER(cns.name)": strings.ToLower(f.Name)})
- }
-
- if f.Slug != "" {
- query = query.Where(squirrel.Eq{"LOWER(cns.slug)": strings.ToLower(f.Slug)})
- }
-
- return
-}
diff --git a/store/rdbms/compose_pages.gen.go b/store/rdbms/compose_pages.gen.go
deleted file mode 100644
index f5bba651d..000000000
--- a/store/rdbms/compose_pages.gen.go
+++ /dev/null
@@ -1,641 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_pages.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchComposePages returns all matching rows
-//
-// This function calls convertComposePageFilter with the given
-// types.PageFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchComposePages(ctx context.Context, f types.PageFilter) (types.PageSet, types.PageFilter, error) {
- var (
- err error
- set []*types.Page
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposePageFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableComposePageColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposePages(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfComposePages collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfComposePages(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Page) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Page, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Page
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Page, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryComposePages(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectComposePageCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectComposePageCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectComposePageCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryComposePages queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposePages(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Page) (bool, error),
-) ([]*types.Page, error) {
- var (
- tmp = make([]*types.Page, 0, DefaultSliceCapacity)
- set = make([]*types.Page, 0, DefaultSliceCapacity)
- res *types.Page
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposePageRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupComposePageByNamespaceIDHandle searches for page by handle (case-insensitive)
-func (s Store) LookupComposePageByNamespaceIDHandle(ctx context.Context, namespace_id uint64, handle string) (*types.Page, error) {
- return s.execLookupComposePage(ctx, squirrel.Eq{
- s.preprocessColumn("cpg.rel_namespace", ""): store.PreprocessValue(namespace_id, ""),
- s.preprocessColumn("cpg.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "cpg.deleted_at": nil,
- })
-}
-
-// LookupComposePageByNamespaceIDModuleID searches for page by moduleID
-func (s Store) LookupComposePageByNamespaceIDModuleID(ctx context.Context, namespace_id uint64, module_id uint64) (*types.Page, error) {
- return s.execLookupComposePage(ctx, squirrel.Eq{
- s.preprocessColumn("cpg.rel_namespace", ""): store.PreprocessValue(namespace_id, ""),
- s.preprocessColumn("cpg.rel_module", ""): store.PreprocessValue(module_id, ""),
-
- "cpg.deleted_at": nil,
- })
-}
-
-// LookupComposePageByID searches for compose page by ID
-//
-// It returns compose page even if deleted
-func (s Store) LookupComposePageByID(ctx context.Context, id uint64) (*types.Page, error) {
- return s.execLookupComposePage(ctx, squirrel.Eq{
- s.preprocessColumn("cpg.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateComposePage creates one or more rows in compose_page table
-func (s Store) CreateComposePage(ctx context.Context, rr ...*types.Page) (err error) {
- for _, res := range rr {
- err = s.checkComposePageConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposePages(ctx, s.internalComposePageEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateComposePage updates one or more existing rows in compose_page
-func (s Store) UpdateComposePage(ctx context.Context, rr ...*types.Page) error {
- return s.partialComposePageUpdate(ctx, nil, rr...)
-}
-
-// partialComposePageUpdate updates one or more existing rows in compose_page
-func (s Store) partialComposePageUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Page) (err error) {
- for _, res := range rr {
- err = s.checkComposePageConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposePages(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cpg.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposePageEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertComposePage updates one or more existing rows in compose_page
-func (s Store) UpsertComposePage(ctx context.Context, rr ...*types.Page) (err error) {
- for _, res := range rr {
- err = s.checkComposePageConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposePages(ctx, s.internalComposePageEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposePage Deletes one or more rows from compose_page table
-func (s Store) DeleteComposePage(ctx context.Context, rr ...*types.Page) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposePages(ctx, squirrel.Eq{
- s.preprocessColumn("cpg.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteComposePageByID Deletes row from the compose_page table
-func (s Store) DeleteComposePageByID(ctx context.Context, ID uint64) error {
- return s.execDeleteComposePages(ctx, squirrel.Eq{
- s.preprocessColumn("cpg.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateComposePages Deletes all rows from the compose_page table
-func (s Store) TruncateComposePages(ctx context.Context) error {
- return s.Truncate(ctx, s.composePageTable())
-}
-
-// execLookupComposePage prepares ComposePage query and executes it,
-// returning types.Page (or error)
-func (s Store) execLookupComposePage(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Page, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composePagesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposePageRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposePages updates all matched (by cnd) rows in compose_page with given data
-func (s Store) execCreateComposePages(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composePageTable()).SetMap(payload))
-}
-
-// execUpdateComposePages updates all matched (by cnd) rows in compose_page with given data
-func (s Store) execUpdateComposePages(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composePageTable("cpg")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposePages inserts new or updates matching (by-primary-key) rows in compose_page with given data
-func (s Store) execUpsertComposePages(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composePageTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposePages Deletes all matched (by cnd) rows in compose_page with given data
-func (s Store) execDeleteComposePages(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composePageTable("cpg")).Where(cnd))
-}
-
-func (s Store) internalComposePageRowScanner(row rowScanner) (res *types.Page, err error) {
- res = &types.Page{}
-
- err = row.Scan(
- &res.ID,
- &res.SelfID,
- &res.NamespaceID,
- &res.ModuleID,
- &res.Handle,
- &res.Title,
- &res.Description,
- &res.Config,
- &res.Blocks,
- &res.Visible,
- &res.Weight,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composePage db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposePages returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composePagesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composePageTable("cpg"), s.composePageColumns("cpg")...)
-}
-
-// composePageTable name of the db table
-func (Store) composePageTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_page" + alias
-}
-
-// ComposePageColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composePageColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "self_id",
- alias + "rel_namespace",
- alias + "rel_module",
- alias + "handle",
- alias + "title",
- alias + "description",
- alias + "config",
- alias + "blocks",
- alias + "visible",
- alias + "weight",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableComposePageColumns returns all ComposePage columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableComposePageColumns() map[string]string {
- return map[string]string{
- "id": "id", "weight": "weight", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalComposePageEncoder encodes fields from types.Page to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposePage
-// func when rdbms.customEncoder=true
-func (s Store) internalComposePageEncoder(res *types.Page) store.Payload {
- return store.Payload{
- "id": res.ID,
- "self_id": res.SelfID,
- "rel_namespace": res.NamespaceID,
- "rel_module": res.ModuleID,
- "handle": res.Handle,
- "title": res.Title,
- "description": res.Description,
- "config": res.Config,
- "blocks": res.Blocks,
- "visible": res.Visible,
- "weight": res.Weight,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectComposePageCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectComposePageCursorValues(res *types.Page, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "weight":
- cursor.Set(c.Column, res.Weight, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkComposePageConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposePageConstraints(ctx context.Context, res *types.Page) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_pages.go b/store/rdbms/compose_pages.go
deleted file mode 100644
index ef00f2a73..000000000
--- a/store/rdbms/compose_pages.go
+++ /dev/null
@@ -1,107 +0,0 @@
-package rdbms
-
-import (
- "context"
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-func (s Store) convertComposePageFilter(f types.PageFilter) (query squirrel.SelectBuilder, err error) {
- query = s.composePagesSelectBuilder()
-
- query = filter.StateCondition(query, "cpg.deleted_at", f.Deleted)
-
- if f.NamespaceID > 0 {
- query = query.Where("cpg.rel_namespace = ?", f.NamespaceID)
- }
-
- if f.ModuleID > 0 {
- query = query.Where("cpg.rel_module = ?", f.ModuleID)
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"cpg.id": f.LabeledIDs})
- }
-
- if f.ParentID > 0 {
- query = query.Where("self_id = ?", f.ParentID)
- } else if f.Root {
- query = query.Where("self_id = 0")
- }
-
- if f.Query != "" {
- q := "%" + strings.ToLower(f.Query) + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"LOWER(cpg.handle)": q},
- squirrel.Like{"LOWER(cpg.title)": q},
- squirrel.Like{"LOWER(cpg.description)": q},
- })
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"LOWER(cpg.handle)": strings.ToLower(f.Handle)})
- }
-
- if f.Title != "" {
- query = query.Where(squirrel.Eq{"LOWER(cpg.title)": strings.ToLower(f.Title)})
- }
-
- return
-}
-
-func (s Store) ReorderComposePages(ctx context.Context, namespaceID, parentID uint64, pageIDs []uint64) (err error) {
- var (
- pages types.PageSet
- pageMap = map[uint64]bool{}
- weight = 1
-
- f = types.PageFilter{ParentID: parentID, NamespaceID: namespaceID}
- )
-
- if pages, _, err = s.SearchComposePages(ctx, f); err != nil {
- return
- }
-
- for _, page := range pages {
- pageMap[page.ID] = true
- }
-
- // honor parameter first
- for _, pageID := range pageIDs {
- if pageMap[pageID] {
- pageMap[pageID] = false
- err = s.execUpdateComposePages(ctx,
- squirrel.Eq{"cpg.id": pageID, "cpg.self_id": parentID},
- store.Payload{"weight": weight})
-
- if err != nil {
- return
- }
-
- weight++
- }
- }
-
- for pageID, update := range pageMap {
- if !update {
- continue
- }
-
- err = s.execUpdateComposePages(ctx,
- squirrel.Eq{"cpg.id": pageID, "cpg.self_id": parentID},
- store.Payload{"weight": weight})
-
- if err != nil {
- return
- }
-
- weight++
-
- }
-
- return
-}
diff --git a/store/rdbms/compose_record_datasource.go b/store/rdbms/compose_record_datasource.go
deleted file mode 100644
index 722a7c4f7..000000000
--- a/store/rdbms/compose_record_datasource.go
+++ /dev/null
@@ -1,703 +0,0 @@
-package rdbms
-
-import (
- "context"
- "database/sql"
- "errors"
- "fmt"
- "reflect"
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/pkg/qlng"
- "github.com/cortezaproject/corteza-server/pkg/report"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/jmoiron/sqlx"
-)
-
-type (
- recordDatasource struct {
- name string
- module *types.Module
-
- // @todo use these
- supportedAggregationFunctions map[string]string
- supportedFilterFunctions map[string]bool
-
- store *Store
- rows *sql.Rows
-
- partitioned bool
- partitionSize uint
- partitionCol string
-
- baseFilter *qlng.ASTNode
-
- cols report.FrameColumnSet
- q squirrel.SelectBuilder
- nestLevel int
- nestLabel string
- levelColumns map[string]string
- }
-)
-
-// ComposeRecordDatasourceBuilder initializes and returns a datasource builder for compose record resource
-//
-// @todo try to make the resulting query as flat as possible
-func ComposeRecordDatasourceBuilder(s *Store, module *types.Module, ld *report.LoadStepDefinition) (report.Datasource, error) {
- var err error
-
- r := &recordDatasource{
- name: ld.Name,
- module: module,
- store: s,
- cols: ld.Columns,
-
- // levelColumns help us keep track of what columns are currently available
- levelColumns: make(map[string]string),
- }
-
- r.q, err = r.baseQuery(ld.Filter)
- return r, err
-}
-
-// Name returns the name we should use when referencing this datasource
-//
-// The name is determined from the user-specified name, or implied from the context.
-func (r *recordDatasource) Name() string {
- if r.name != "" {
- return r.name
- }
-
- if r.module == nil {
- return ""
- }
-
- if r.module.Handle == "" {
- return r.module.Name
- }
- return r.module.Handle
-}
-
-func (r *recordDatasource) Describe() report.FrameDescriptionSet {
- return report.FrameDescriptionSet{
- &report.FrameDescription{
- Source: r.Name(),
- Ref: r.Name(),
- Columns: r.cols,
- },
- }
-}
-
-func (r *recordDatasource) Load(ctx context.Context, dd ...*report.FrameDefinition) (l report.Loader, c report.Closer, err error) {
- if r.partitioned {
- return r.partition(ctx, r.partitionSize, r.partitionCol, dd...)
- }
-
- def := dd[0]
- q, err := r.preloadQuery(def)
- if err != nil {
- return nil, nil, err
- }
-
- return r.load(ctx, def, q)
-}
-
-func (r *recordDatasource) prepASTTransformer(node *qlng.ASTNode) *astTransformer {
- tr := r.store.ASTTransformer(node)
- tr.onSymbol = wrapCol
- return tr
-}
-
-// Group instructs the datasource to provide grouped and aggregated output
-func (r *recordDatasource) Group(d report.GroupDefinition, name string) (bool, error) {
- defer func() {
- r.nestLevel++
- r.nestLabel = "group"
- r.name = name
- }()
-
- var (
- q = squirrel.Select().PlaceholderFormat(r.store.config.PlaceholderFormat)
- err error
- )
-
- auxLevelColumns := r.levelColumns
- r.levelColumns = make(map[string]string)
- groupCols := make(report.FrameColumnSet, 0, 10)
-
- // firstly handle GROUP BY definitions
- for _, k := range d.Keys {
- // - validate columns & functions
- err = k.Def.Traverse(func(n *qlng.ASTNode) (bool, *qlng.ASTNode, error) {
- if n.Symbol != "" {
- if _, ok := auxLevelColumns[n.Symbol]; !ok {
- return false, nil, fmt.Errorf("column %s does not exist on level %d", n.Symbol, r.nestLevel)
- }
- }
-
- // @todo do we need additional function validation besides the built-in one?
-
- return true, n, nil
- })
- if err != nil {
- return false, err
- }
-
- // AST transformation tasks
- tr := r.prepASTTransformer(k.Def.ASTNode)
- outType, err := tr.Analyze(auxLevelColumns)
- if err != nil {
- return false, err
- }
- // - prepare frame col. definition
- c := report.MakeColumnOfKind(outType)
- c.Name = k.Name
- c.Label = k.Label
- if c.Label == "" {
- c.Label = c.Name
- }
- groupCols = append(groupCols, c)
- r.levelColumns[k.Name] = outType
-
- // - SQL things
- tr.SetPlaceholder(false)
- sql, _, err := tr.ToSql()
- if err != nil {
- return false, err
- }
-
- q = q.Column(squirrel.Alias(tr, wrapCol(c.Name))).
- GroupBy(sql)
- }
-
- // secondly handle column definitions
- for _, k := range d.Columns {
- // - make sure the column results with an aggregated value
- if !r.isAggregated(k.Def.ASTNode) {
- return false, fmt.Errorf("group column %s does not aggregate data", k.Name)
- }
-
- // - validate columns & functions
- err = k.Def.Traverse(func(n *qlng.ASTNode) (bool, *qlng.ASTNode, error) {
- if n.Symbol != "" {
- if _, ok := auxLevelColumns[n.Symbol]; !ok {
- return false, nil, fmt.Errorf("column %s does not exist on level %d", n.Symbol, r.nestLevel)
- }
- }
-
- // @todo do we need additional function validation besides the built-in one?
-
- return true, n, nil
- })
- if err != nil {
- return false, err
- }
-
- // AST transformation tasks
- tr := r.prepASTTransformer(k.Def.ASTNode)
- outType, err := tr.Analyze(auxLevelColumns)
- if err != nil {
- return false, err
- }
- // - prepare frame col. definition
- c := report.MakeColumnOfKind(outType)
- c.Name = k.Name
- c.Label = k.Label
- if c.Label == "" {
- c.Label = c.Name
- }
- groupCols = append(groupCols, c)
- r.levelColumns[k.Name] = outType
-
- // - SQL things
- q = q.Column(squirrel.Alias(tr, wrapCol(c.Name)))
- }
-
- if d.Filter != nil && d.Filter.ASTNode != nil {
- q = q.Having(r.prepASTTransformer(d.Filter.ASTNode))
- }
-
- r.cols = groupCols
- r.q = q.FromSelect(r.q, fmt.Sprintf("l%d", r.nestLevel))
- return true, nil
-}
-
-// @todo add Transform
-
-func (r *recordDatasource) Partition(partitionSize uint, partitionCol string) (bool, error) {
- if r.partitioned {
- return true, nil
- }
- if partitionCol == "" {
- return false, errors.New("unable to partition: partition column not defined")
- }
-
- r.partitioned = true
- r.partitionCol = partitionCol
- r.partitionSize = partitionSize
- return true, nil
-}
-
-func (r *recordDatasource) partition(ctx context.Context, partitionSize uint, partitionCol string, dd ...*report.FrameDefinition) (l report.Loader, c report.Closer, err error) {
- def := dd[0]
-
- q, err := r.preloadQuery(def)
- if err != nil {
- return nil, nil, err
- }
-
- var ss []string
- if len(def.Sort) > 0 {
- ss, err = r.sortExpr(def.Sort)
- if err != nil {
- return nil, nil, err
- }
- }
-
- // the partitioning wrap
- // @todo move this to the DB driver package?
- // @todo squash the query a bit? try to move most of this to the base query to remove
- // one sub-select
- var prt squirrel.SelectBuilder
- if len(ss) > 0 {
- prt = squirrel.Select(fmt.Sprintf("*, row_number() over(partition by %s order by %s) as pp_rank", wrapCol(partitionCol), strings.Join(ss, ","))).
- PlaceholderFormat(r.store.config.PlaceholderFormat).
- FromSelect(q, "partition_base")
- } else {
- prt = squirrel.Select(fmt.Sprintf("*, row_number() over(partition by %s) as pp_rank", wrapCol(partitionCol))).
- PlaceholderFormat(r.store.config.PlaceholderFormat).
- FromSelect(q, "partition_base")
- }
-
- // the sort is already defined when partitioning so it's unneeded here
- q = squirrel.Select("*").
- PlaceholderFormat(r.store.config.PlaceholderFormat).
- FromSelect(prt, "partition_wrap").
- Where(fmt.Sprintf("pp_rank <= %d", partitionSize))
-
- return r.load(ctx, def, q)
-}
-
-func (r *recordDatasource) preloadQuery(def *report.FrameDefinition) (squirrel.SelectBuilder, error) {
- q := r.q
-
- // assure columns
- // - undefined columns = all columns
- if len(def.Columns) == 0 {
- def.Columns = r.cols
- } else {
- // - make sure they exist
- cc := make(report.FrameColumnSet, len(def.Columns))
- for i, c := range def.Columns {
- ci := r.cols.Find(c.Name)
- if ci == -1 {
- return q, fmt.Errorf("column not found: %s", c.Name)
- }
- cc[i] = r.cols[ci]
- }
- def.Columns = cc
- }
-
- // when filtering/sorting, wrap the base query in a sub-select, so we don't need to
- // worry about exact column names.
- if def.Filter != nil && def.Filter.ASTNode != nil || def.Sort != nil {
- q = squirrel.Select("*").PlaceholderFormat(r.store.config.PlaceholderFormat).FromSelect(q, "w_base")
- }
-
- // - filtering
- if def.Filter != nil && def.Filter.ASTNode != nil {
- q = q.Where(r.prepASTTransformer(def.Filter.ASTNode))
- }
-
- return q, nil
-}
-
-func (r *recordDatasource) load(ctx context.Context, def *report.FrameDefinition, q squirrel.SelectBuilder) (l report.Loader, c report.Closer, err error) {
- sort := def.Sort
-
- // - paging related stuff
- if def.Paging.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if def.Sort, err = def.Paging.PageCursor.Sort(def.Sort); err != nil {
- return nil, nil, err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- var canPage bool
- if canPage, err = r.validateSort(def); err != nil {
- return
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original must be kept for cursor creation
- sort = def.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if def.Paging.PageCursor != nil && def.Paging.PageCursor.ROrder {
- sort.Reverse()
- }
-
- if def.Paging.PageCursor != nil {
- q = q.Where(builders.CursorCondition(def.Paging.PageCursor,
- func(s string) (builders.KeyMap, error) {
- return builders.KeyMap{
- FieldCast: "r_" + s,
- TypeCast: "r_" + s,
- TypeCastPtrn: "%s",
- }, nil
- }))
- }
-
- if len(sort) > 0 {
- ss, err := r.sortExpr(sort)
- if err != nil {
- return nil, nil, err
- }
-
- q = q.OrderBy(ss...)
- }
-
- r.rows, err = r.store.Query(ctx, q)
- if err != nil {
- return nil, nil, fmt.Errorf("cannot execute query: %w", err)
- }
-
- return func(cap int, processed bool) ([]*report.Frame, error) {
- f := &report.Frame{
- Name: def.Name,
- Source: def.Source,
- Ref: r.Name(),
- Sort: def.Sort,
- Filter: def.Filter,
- }
-
- checkCap := cap > 0
-
- // Fetch & convert the data.
- // Go 1 over the requested cap to be able to determine if there are
- // any additional pages
- i := 0
- f.Columns = def.Columns
- f.Rows = make(report.FrameRowSet, 0, cap)
-
- for r.rows.Next() {
- i++
-
- err = r.cast(r.rows, f)
- if err != nil {
- return nil, err
- }
-
- // If the count goes over the capacity, then we have a next page
- if checkCap && (processed && i > cap || !processed && i >= cap) {
- out := []*report.Frame{f}
- f = &report.Frame{
- Name: def.Name,
- Source: def.Source,
- Ref: r.Name(),
- Sort: def.Sort,
- Filter: def.Filter,
- }
- i = 0
- if processed {
- return r.calculatePaging(out, def.Sort, uint(cap), def.Paging.PageCursor, canPage), nil
- }
- return out, nil
- }
- }
-
- if i > 0 {
- if processed {
- return r.calculatePaging([]*report.Frame{f}, def.Sort, uint(cap), def.Paging.PageCursor, canPage), nil
- } else {
- return []*report.Frame{f}, nil
- }
- }
-
- if processed {
- return []*report.Frame{f}, nil
- }
-
- // This indicates that the DS is empty
- return nil, nil
- }, func() {
- if r.rows == nil {
- return
- }
- r.rows.Close()
- }, nil
-}
-
-// baseQuery prepares the initial SQL that will be used for data access
-//
-// The query includes all of the requested columns in the required types to avid the need to type cast.
-func (r *recordDatasource) baseQuery(f *report.Filter) (sqb squirrel.SelectBuilder, err error) {
- var (
- joinTpl = "compose_record_value AS r_%s ON (r_%s.record_id = r_crd.id AND r_%s.name = '%s' AND r_%s.deleted_at IS NULL)"
- )
-
- // - the initial set of available columns
- //
- // @todo at what level should the requested columns be validated?
- r.nestLevel = 0
- r.nestLabel = "base"
- for _, c := range r.cols {
- r.levelColumns[c.Name] = c.Kind
- }
-
- // - base query
- sqb = r.store.SelectBuilder("compose_record AS r_crd").
- Where("r_crd.deleted_at IS NULL").
- Where("r_crd.module_id = ?", r.module.ID).
- Where("r_crd.rel_namespace = ?", r.module.NamespaceID)
-
- // - based on the definition, preload the columns
- var (
- col string
- is bool
- isJoined = make(map[string]bool)
- )
- for _, c := range r.cols {
- if isJoined[c.Name] {
- continue
- }
- isJoined[c.Name] = true
-
- // native record columns don't need any extra handling
- if col, _, is = isRealRecordCol(c.Name); is {
- sqb = sqb.Column(squirrel.Alias(squirrel.Expr(wrapCol(col)), wrapCol(c.Name)))
- continue
- }
-
- // non-native record columns need to have their type casted before use
- _, _, tcp, _ := r.store.config.CastModuleFieldToColumnType(c, wrapCol(c.Name))
- sqb = sqb.LeftJoin(strings.ReplaceAll(joinTpl, "%s", c.Name)).
- Column(squirrel.Alias(squirrel.Expr(fmt.Sprintf(tcp, wrapCol(c.Name)+".value")), wrapCol(c.Name)))
- }
-
- // @todo this is temporary!!
- sqb = squirrel.Select("*").
- PlaceholderFormat(r.store.config.PlaceholderFormat).
- FromSelect(sqb, "q_base")
-
- // - any initial filtering we may need to do
- //
- // @todo better support functions and their validation.
- if f != nil {
- err = f.ASTNode.Traverse(func(n *qlng.ASTNode) (bool, *qlng.ASTNode, error) {
- // for now, a symbol indicates a column
- if n.Symbol != "" {
- if _, ok := r.levelColumns[n.Symbol]; !ok {
- return false, n, fmt.Errorf("column %s does not exist on level %d (%s)", n.Symbol, r.nestLevel, r.nestLabel)
- }
- }
-
- return true, n, nil
- })
- if err != nil {
- return
- }
-
- if f != nil && f.ASTNode != nil {
- sqb = sqb.Where(r.prepASTTransformer(f.ASTNode))
- }
- }
-
- return sqb, nil
-}
-
-func (b *recordDatasource) calculatePaging(out []*report.Frame, sorting filter.SortExprSet, limit uint, cursor *filter.PagingCursor, canPage bool) []*report.Frame {
- for _, o := range out {
- var (
- hasPrev = cursor != nil
- hasNext bool
- ignoreLimit = limit == 0
- reversedOrder = cursor != nil && cursor.ROrder
- )
-
- hasNext = uint(len(o.Rows)) > limit
- if !ignoreLimit && uint(len(o.Rows)) > limit {
- o.Rows = o.Rows[:limit]
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, len(o.Rows)-1; i < j; i, j = i+1, j-1 {
- o.Rows[i], o.Rows[j] = o.Rows[j], o.Rows[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if ignoreLimit || !canPage {
- return out
- }
-
- if hasPrev {
- o.Paging = &filter.Paging{}
- o.Paging.PrevPage = o.CollectCursorValues(o.FirstRow(), sorting...)
- o.Paging.PrevPage.ROrder = true
- o.Paging.PrevPage.LThen = !sorting.Reversed()
- }
-
- if hasNext {
- if o.Paging == nil {
- o.Paging = &filter.Paging{}
- }
- o.Paging.NextPage = o.CollectCursorValues(o.LastRow(), sorting...)
- o.Paging.NextPage.LThen = sorting.Reversed()
- }
- }
-
- return out
-}
-
-func (b *recordDatasource) mapRow(row sqlx.ColScanner) (out map[string]interface{}, err error) {
- aux := make(map[string]interface{})
- if err = sqlx.MapScan(row, aux); err != nil {
- return
- }
-
- // PgSQL treats idents as lowercase which would cause not lower-case field names
- // to not work.
- // Since fields can not be same with different capitalization, converting to lowercase
- // does the trick.
- out = make(map[string]interface{})
- for k, v := range aux {
- out[strings.ToLower(k)] = v
- }
-
- return
-}
-
-func (b *recordDatasource) cast(row sqlx.ColScanner, out *report.Frame) (err error) {
- aux, err := b.mapRow(row)
- r := make(report.FrameRow, len(out.Columns))
-
- k := ""
- for i, c := range out.Columns {
- k = "" + c.Name
- // cols are wrapped so we need to handle those properly
- v, ok := aux[strings.ToLower(wrapCol(k))]
- if !ok {
- continue
- }
-
- // @todo improve json value casting; I couldn't figure it out at the time
-
- // @todo this doesn't work...
- // var aux interface{}
- // err = json.Unmarshal(v.([]byte), &aux)
- // if err != nil {
- // return err
- // }
-
- switch cv := v.(type) {
- case []byte:
- c, err := c.Caster(string(cv))
- if err != nil {
- return err
- }
- r[i] = c
-
- case uint64, int64:
- r[i], err = c.Caster(cv)
- if err != nil {
- return err
- }
-
- default:
- if isNil(cv) {
- continue
- }
-
- c, err := c.Caster(cv)
- if err != nil {
- return err
- }
- r[i] = c
-
- }
-
- }
-
- out.Rows = append(out.Rows, r)
- return nil
-}
-
-func isNil(i interface{}) bool {
- if i == nil {
- return true
- }
- switch reflect.TypeOf(i).Kind() {
- case reflect.Ptr, reflect.Map, reflect.Array, reflect.Chan, reflect.Slice:
- return reflect.ValueOf(i).IsNil()
- }
- return false
-}
-
-func (r *recordDatasource) sortExpr(sorting filter.SortExprSet) ([]string, error) {
- ss := make([]string, len(sorting))
- for i, c := range sorting {
- ci := r.cols.Find(c.Column)
- if ci == -1 {
- return nil, fmt.Errorf("sort column not resolved: %s", c.Column)
- }
-
- _, _, typeCast, err := r.store.config.CastModuleFieldToColumnType(r.cols[ci], c.Column)
- if err != nil {
- return nil, err
- }
-
- ss[i] = r.store.config.SqlSortHandler(fmt.Sprintf(typeCast, wrapCol(c.Column)), c.Descending)
- }
-
- return ss, nil
-}
-
-func (r *recordDatasource) validateSort(def *report.FrameDefinition) (canPage bool, err error) {
- unique := ""
- def.Sort = func() filter.SortExprSet {
- for _, c := range r.cols {
- if c.Primary || c.Unique {
- if unique == "" {
- unique = c.Name
- }
- if def.Sort.Get(c.Name) != nil {
- unique = c.Name
- return def.Sort
- }
- }
- }
- if unique != "" {
- return append(def.Sort, &filter.SortExpr{Column: unique, Descending: def.Sort.LastDescending()})
- }
- return def.Sort
- }()
- return unique != "", nil
-}
-
-func (r *recordDatasource) isAggregated(n *qlng.ASTNode) bool {
- switch strings.ToLower(n.Ref) {
- case "count",
- "sum",
- "max",
- "min",
- "avg":
- return true
- }
- return false
-}
-
-func wrapCol(col string) string {
- return "r_" + col
-}
diff --git a/store/rdbms/compose_record_report_builder.go b/store/rdbms/compose_record_report_builder.go
deleted file mode 100644
index 8c56e038e..000000000
--- a/store/rdbms/compose_record_report_builder.go
+++ /dev/null
@@ -1,263 +0,0 @@
-package rdbms
-
-import (
- "context"
- "database/sql"
- "fmt"
- "strconv"
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/handle"
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "github.com/cortezaproject/corteza-server/pkg/slice"
- "github.com/jmoiron/sqlx"
-)
-
-type (
- ComposeRecordsReport []map[string]interface{}
-
- recordReportBuilder struct {
- // This is set by metric/column building to assist Cast()
- numerics []string
-
- parser *ql.Parser
-
- module *types.Module
- metrics string
- dimensions string
- filters string
-
- store recordReportBuilderStoreQuerier
-
- supportedAggregationFunctions map[string]bool
- supportedFilterFunctions map[string]bool
- }
-
- recordReportBuilderStoreQuerier interface {
- SelectBuilder(string, ...string) squirrel.SelectBuilder
- Query(context.Context, squirrel.Sqlizer) (*sql.Rows, error)
- SqlFunctionHandler(f ql.Function) (ql.ASTNode, error)
- FieldToColumnTypeCaster(f ModuleFieldTypeDetector, i ql.Ident) (ql.Ident, error)
- }
-)
-
-func ComposeRecordReportBuilder(s *Store, module *types.Module, metrics, dimensions, filters string) *recordReportBuilder {
- return &recordReportBuilder{
- parser: ql.NewParser(),
- store: s,
- module: module,
- metrics: metrics,
- dimensions: dimensions,
- filters: filters,
-
- supportedAggregationFunctions: slice.ToStringBoolMap([]string{
- "COUNT",
- "SUM",
- "MAX",
- "MIN",
- "AVG",
- "STD",
- }),
-
- supportedFilterFunctions: slice.ToStringBoolMap([]string{
- "CONCAT",
- "QUARTER",
- "YEAR",
- "DATE",
- "NOW",
- "DATE_ADD",
- "DATE_SUB",
- "DATE_FORMAT",
- }),
- }
-}
-
-func (b *recordReportBuilder) Run(ctx context.Context) (ComposeRecordsReport, error) {
- var (
- result = make(ComposeRecordsReport, 0)
- )
-
- if sb, err := b.Build(); err != nil {
- return nil, fmt.Errorf("cannot generate report query: %w", err)
- } else if rows, err := b.store.Query(ctx, sb); err != nil {
- return nil, fmt.Errorf("cannot execute report query: %w", err)
- } else {
- err = func() error {
- defer rows.Close()
- for rows.Next() {
- r, err := b.Cast(rows)
- if err != nil {
- return err
- }
- result = append(result, r)
- }
-
- return nil
- }()
-
- if err = rows.Err(); err != nil {
- return nil, err
- }
-
- return result, nil
- }
-}
-
-func (b recordReportBuilder) ToSql() (string, []interface{}, error) {
- if sb, err := b.Build(); err != nil {
- return "", nil, err
- } else {
- return sb.ToSql()
- }
-}
-
-// Identifiers should be names of the fields (physical table columns OR json fields, defined in module)
-func (b *recordReportBuilder) stdAggregationHandler(f ql.Function) (ql.ASTNode, error) {
- if !b.supportedAggregationFunctions[strings.ToUpper(f.Name)] {
- return f, fmt.Errorf("unsupported aggregate function %q", f.Name)
- }
-
- return b.store.SqlFunctionHandler(f)
-}
-
-// Identifiers should be names of the fields (physical table columns OR json fields, defined in module)
-func (b *recordReportBuilder) stdFilterFuncHandler(f ql.Function) (ql.ASTNode, error) {
- if !b.supportedFilterFunctions[strings.ToUpper(f.Name)] {
- return f, fmt.Errorf("unsupported filter function %q", f.Name)
- }
-
- return b.store.SqlFunctionHandler(f)
-}
-
-func (b *recordReportBuilder) Build() (sb squirrel.SelectBuilder, err error) {
- var (
- joinTpl = "compose_record_value AS rv_%s ON (rv_%s.record_id = crd.id AND rv_%s.name = '%s' AND rv_%s.deleted_at IS NULL)"
-
- report = b.store.SelectBuilder("compose_record AS crd").
- Column(squirrel.Alias(squirrel.Expr("COUNT(*)"), "count")).
- Where("crd.deleted_at IS NULL").
- Where("crd.module_id = ?", b.module.ID)
-
- joinedFields = []string{}
-
- alreadyJoined = func(f string) bool {
- for _, a := range joinedFields {
- if a == f {
- return true
- }
- }
-
- joinedFields = append(joinedFields, f)
- return false
- }
- )
-
- b.parser.OnIdent = func(i ql.Ident) (ql.Ident, error) {
- var is bool
- if i.Value, _, is = isRealRecordCol(i.Value); is {
- return i, nil
- }
-
- if !b.module.Fields.HasName(i.Value) {
- return i, fmt.Errorf("unknown field %q", i.Value)
- }
-
- if !handle.IsValid(i.Value) {
- return i, fmt.Errorf("invalid field name: %q", i.Value)
- }
-
- if !alreadyJoined(i.Value) {
- report = report.LeftJoin(strings.ReplaceAll(joinTpl, "%s", i.Value))
- }
-
- return b.store.FieldToColumnTypeCaster(b.module.Fields.FindByName(i.Value), i)
- }
-
- var columns ql.Columns
- b.parser.OnFunction = b.stdAggregationHandler
- if columns, err = b.parser.ParseColumns(b.metrics); err != nil {
- err = fmt.Errorf("could not parse metrics %q: %w", b.metrics, err)
- return
- }
-
- // Add all metrics to columns
- for i, m := range columns {
- if m.Alias == "" {
- // Generate alias
- m.Alias = fmt.Sprintf("metric_%d", i)
- }
-
- // Wrap to cast func to ensure numeric output
- col := squirrel.Alias(SquirrelConcatExpr("CAST(", m.Expr, " AS DECIMAL(14,2))"), m.Alias)
- report = report.Column(col)
-
- b.numerics = append(b.numerics, m.Alias)
- }
-
- b.parser.OnFunction = b.stdFilterFuncHandler
- if columns, err = b.parser.ParseColumns(b.dimensions); err != nil {
- err = fmt.Errorf("could not parse dimensions %q: %w", b.dimensions, err)
- return
- }
-
- // Add dimensions
- for i, d := range columns {
- if d.Alias == "" {
- d.Alias = fmt.Sprintf("dimension_%d", i)
- }
-
- report = report.
- Column(d).
- GroupBy(d.Alias).
- OrderBy(d.Alias)
- }
-
- // Use a different handler for filter functions for this
- b.parser.OnFunction = b.stdFilterFuncHandler
-
- if len(b.filters) > 0 {
- var filter ql.ASTNode
- if filter, err = b.parser.ParseExpression(b.filters); err != nil {
- err = fmt.Errorf("could not parse filters %q: %w", b.filters, err)
- return
- }
-
- // We need to wrap this one level deeper, since additional filters should
- // be evaluated as a whole.
- // For example A AND B OR C =should be> (A AND B OR C)
- // so the output becomes BASE AND (ADDITIONAL)
- report = report.Where(ql.ASTNodes{filter})
- }
-
- return report, nil
-}
-
-func (b recordReportBuilder) Cast(row sqlx.ColScanner) (out map[string]interface{}, err error) {
- out = map[string]interface{}{}
- if err = sqlx.MapScan(row, out); err != nil {
- return nil, err
- }
-
- for k, v := range out {
- switch cv := v.(type) {
- case []uint8:
- out[k] = string(cv)
- default:
- }
- }
-
- // Cast all metrics to float64
- for _, fname := range b.numerics {
- switch num := out[fname].(type) {
- case string:
- out[fname], err = strconv.ParseFloat(num, 64)
- if err != nil {
- return nil, err
- }
- }
- }
-
- return
-}
diff --git a/store/rdbms/compose_record_value.go b/store/rdbms/compose_record_value.go
deleted file mode 100644
index b5e09a99b..000000000
--- a/store/rdbms/compose_record_value.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package rdbms
-
-import (
- "context"
- "database/sql"
- "errors"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
-)
-
-func (s Store) convertComposeRecordValueFilter(_ *types.Module, f types.RecordValueFilter) (query squirrel.SelectBuilder, err error) {
- // Always filter by record IDs
- query = s.composeRecordValuesSelectBuilder().Where(squirrel.Eq{"crv.record_id": f.RecordID})
- query = filter.StateCondition(query, "crv.deleted_at", f.Deleted)
-
- return query, nil
-}
-
-func (s Store) ComposeRecordValueRefLookup(ctx context.Context, m *types.Module, field string, ref uint64) (uint64, error) {
- q := s.composeRecordValuesSelectBuilder().
- Join(s.composeRecordTable("crd"), "crv.record_id = crd.id").
- Where(squirrel.Eq{
- "crv.name": field,
- "crv.ref": ref,
- "crv.deleted_at": nil,
- "crd.module_id": m.ID,
- "crd.deleted_at": nil,
- }).
- Column("record_id").
- Limit(1)
-
- row, err := s.QueryRow(ctx, q)
- if errors.Is(err, sql.ErrNoRows) {
- return 0, nil
- } else if err != nil {
- return 0, err
- }
-
- var recordID uint64
- if err = row.Scan(&recordID); err != nil {
- return 0, err
- }
-
- return recordID, nil
-}
-
-// PartialComposeRecordValueUpdate updates specific record values across multiple records
-func (s Store) PartialComposeRecordValueUpdate(ctx context.Context, m *types.Module, vv ...*types.RecordValue) (err error) {
- {
- // handle standard record-value storage
- for _, v := range vv {
- if err = s.execUpsertComposeRecordValues(ctx, s.internalComposeRecordValueEncoder(v)); err != nil {
- return
- }
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_record_values.gen.go b/store/rdbms/compose_record_values.gen.go
deleted file mode 100644
index bb1961804..000000000
--- a/store/rdbms/compose_record_values.gen.go
+++ /dev/null
@@ -1,331 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_record_values.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// searchComposeRecordValues returns all matching rows
-//
-// This function calls convertComposeRecordValueFilter with the given
-// types.RecordValueFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) searchComposeRecordValues(ctx context.Context, _mod *types.Module, f types.RecordValueFilter) (types.RecordValueSet, types.RecordValueFilter, error) {
- var (
- err error
- set []*types.RecordValue
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertComposeRecordValueFilter(_mod, f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryComposeRecordValues(ctx, _mod, q, nil)
- return err
- }()
-}
-
-// QueryComposeRecordValues queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeRecordValues(
- ctx context.Context, _mod *types.Module,
- q squirrel.Sqlizer,
- check func(*types.RecordValue) (bool, error),
-) ([]*types.RecordValue, error) {
- var (
- tmp = make([]*types.RecordValue, 0, DefaultSliceCapacity)
- set = make([]*types.RecordValue, 0, DefaultSliceCapacity)
- res *types.RecordValue
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeRecordValueRowScanner(_mod, rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// createComposeRecordValue creates one or more rows in compose_record_value table
-func (s Store) createComposeRecordValue(ctx context.Context, _mod *types.Module, rr ...*types.RecordValue) (err error) {
- for _, res := range rr {
- err = s.checkComposeRecordValueConstraints(ctx, _mod, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeRecordValues(ctx, s.internalComposeRecordValueEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// updateComposeRecordValue updates one or more existing rows in compose_record_value
-func (s Store) updateComposeRecordValue(ctx context.Context, _mod *types.Module, rr ...*types.RecordValue) error {
- return s.partialComposeRecordValueUpdate(ctx, _mod, nil, rr...)
-}
-
-// partialComposeRecordValueUpdate updates one or more existing rows in compose_record_value
-func (s Store) partialComposeRecordValueUpdate(ctx context.Context, _mod *types.Module, onlyColumns []string, rr ...*types.RecordValue) (err error) {
- for _, res := range rr {
- err = s.checkComposeRecordValueConstraints(ctx, _mod, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeRecordValues(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("crv.record_id", ""): store.PreprocessValue(res.RecordID, ""), s.preprocessColumn("crv.name", ""): store.PreprocessValue(res.Name, ""), s.preprocessColumn("crv.place", ""): store.PreprocessValue(res.Place, ""),
- },
- s.internalComposeRecordValueEncoder(res).Skip("record_id", "name", "place").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// upsertComposeRecordValue updates one or more existing rows in compose_record_value
-func (s Store) upsertComposeRecordValue(ctx context.Context, _mod *types.Module, rr ...*types.RecordValue) (err error) {
- for _, res := range rr {
- err = s.checkComposeRecordValueConstraints(ctx, _mod, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeRecordValues(ctx, s.internalComposeRecordValueEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// deleteComposeRecordValue Deletes one or more rows from compose_record_value table
-func (s Store) deleteComposeRecordValue(ctx context.Context, _mod *types.Module, rr ...*types.RecordValue) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeRecordValues(ctx, squirrel.Eq{
- s.preprocessColumn("crv.record_id", ""): store.PreprocessValue(res.RecordID, ""), s.preprocessColumn("crv.name", ""): store.PreprocessValue(res.Name, ""), s.preprocessColumn("crv.place", ""): store.PreprocessValue(res.Place, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// deleteComposeRecordValueByRecordIDNamePlace Deletes row from the compose_record_value table
-func (s Store) deleteComposeRecordValueByRecordIDNamePlace(ctx context.Context, _mod *types.Module, recordID uint64, name string, place uint) error {
- return s.execDeleteComposeRecordValues(ctx, squirrel.Eq{
- s.preprocessColumn("crv.record_id", ""): store.PreprocessValue(recordID, ""),
- s.preprocessColumn("crv.name", ""): store.PreprocessValue(name, ""),
- s.preprocessColumn("crv.place", ""): store.PreprocessValue(place, ""),
- })
-}
-
-// truncateComposeRecordValues Deletes all rows from the compose_record_value table
-func (s Store) truncateComposeRecordValues(ctx context.Context, _mod *types.Module) error {
- return s.Truncate(ctx, s.composeRecordValueTable())
-}
-
-// execLookupComposeRecordValue prepares ComposeRecordValue query and executes it,
-// returning types.RecordValue (or error)
-func (s Store) execLookupComposeRecordValue(ctx context.Context, _mod *types.Module, cnd squirrel.Sqlizer) (res *types.RecordValue, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeRecordValuesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeRecordValueRowScanner(_mod, row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateComposeRecordValues updates all matched (by cnd) rows in compose_record_value with given data
-func (s Store) execCreateComposeRecordValues(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeRecordValueTable()).SetMap(payload))
-}
-
-// execUpdateComposeRecordValues updates all matched (by cnd) rows in compose_record_value with given data
-func (s Store) execUpdateComposeRecordValues(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeRecordValueTable("crv")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeRecordValues inserts new or updates matching (by-primary-key) rows in compose_record_value with given data
-func (s Store) execUpsertComposeRecordValues(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeRecordValueTable(),
- set,
- s.preprocessColumn("record_id", ""),
- s.preprocessColumn("name", ""),
- s.preprocessColumn("place", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeRecordValues Deletes all matched (by cnd) rows in compose_record_value with given data
-func (s Store) execDeleteComposeRecordValues(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeRecordValueTable("crv")).Where(cnd))
-}
-
-func (s Store) internalComposeRecordValueRowScanner(_mod *types.Module, row rowScanner) (res *types.RecordValue, err error) {
- res = &types.RecordValue{}
-
- err = row.Scan(
- &res.RecordID,
- &res.Name,
- &res.Place,
- &res.Value,
- &res.Ref,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeRecordValue db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeRecordValues returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeRecordValuesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeRecordValueTable("crv"), s.composeRecordValueColumns("crv")...)
-}
-
-// composeRecordValueTable name of the db table
-func (Store) composeRecordValueTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_record_value" + alias
-}
-
-// ComposeRecordValueColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeRecordValueColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "record_id",
- alias + "name",
- alias + "place",
- alias + "value",
- alias + "ref",
- alias + "deleted_at",
- }
-}
-
-// {true false false false false false}
-
-// internalComposeRecordValueEncoder encodes fields from types.RecordValue to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeRecordValue
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeRecordValueEncoder(res *types.RecordValue) store.Payload {
- return store.Payload{
- "record_id": res.RecordID,
- "name": res.Name,
- "place": res.Place,
- "value": res.Value,
- "ref": res.Ref,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkComposeRecordValueConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeRecordValueConstraints(ctx context.Context, _mod *types.Module, res *types.RecordValue) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_records.gen.go b/store/rdbms/compose_records.gen.go
deleted file mode 100644
index 6f40dcc53..000000000
--- a/store/rdbms/compose_records.gen.go
+++ /dev/null
@@ -1,496 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/compose_records.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// searchComposeRecords not generated
-// {search: {custom:true}}
-
-// fetchFullPageOfComposeRecords collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfComposeRecords(
- ctx context.Context, _mod *types.Module,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Record) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Record, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Record
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Record, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if tryQuery, err = s.composeRecordPreLoadProcessor(tryQuery); err != nil {
- return
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryComposeRecords(ctx, _mod, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectComposeRecordCursorValues(_mod, set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectComposeRecordCursorValues(_mod, set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectComposeRecordCursorValues(_mod, set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryComposeRecords queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryComposeRecords(
- ctx context.Context, _mod *types.Module,
- q squirrel.Sqlizer,
- check func(*types.Record) (bool, error),
-) ([]*types.Record, error) {
- var (
- tmp = make([]*types.Record, 0, DefaultSliceCapacity)
- set = make([]*types.Record, 0, DefaultSliceCapacity)
- res *types.Record
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeRecordRowScanner(_mod, rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- if err = s.composeRecordPostLoadProcessor(ctx, _mod, tmp...); err != nil {
- return nil, err
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// lookupComposeRecordByID searches for compose record by ID
-// It returns compose record even if deleted
-func (s Store) lookupComposeRecordByID(ctx context.Context, _mod *types.Module, id uint64) (*types.Record, error) {
- return s.execLookupComposeRecord(ctx, _mod, squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// createComposeRecord creates one or more rows in compose_record table
-func (s Store) createComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) (err error) {
- for _, res := range rr {
- err = s.checkComposeRecordConstraints(ctx, _mod, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateComposeRecords(ctx, s.internalComposeRecordEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// updateComposeRecord updates one or more existing rows in compose_record
-func (s Store) updateComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) error {
- return s.partialComposeRecordUpdate(ctx, _mod, nil, rr...)
-}
-
-// partialComposeRecordUpdate updates one or more existing rows in compose_record
-func (s Store) partialComposeRecordUpdate(ctx context.Context, _mod *types.Module, onlyColumns []string, rr ...*types.Record) (err error) {
- for _, res := range rr {
- err = s.checkComposeRecordConstraints(ctx, _mod, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateComposeRecords(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalComposeRecordEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// upsertComposeRecord updates one or more existing rows in compose_record
-func (s Store) upsertComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) (err error) {
- for _, res := range rr {
- err = s.checkComposeRecordConstraints(ctx, _mod, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertComposeRecords(ctx, s.internalComposeRecordEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// deleteComposeRecord Deletes one or more rows from compose_record table
-func (s Store) deleteComposeRecord(ctx context.Context, _mod *types.Module, rr ...*types.Record) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteComposeRecords(ctx, squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// deleteComposeRecordByID Deletes row from the compose_record table
-func (s Store) deleteComposeRecordByID(ctx context.Context, _mod *types.Module, ID uint64) error {
- return s.execDeleteComposeRecords(ctx, squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// truncateComposeRecords Deletes all rows from the compose_record table
-func (s Store) truncateComposeRecords(ctx context.Context, _mod *types.Module) error {
- return s.Truncate(ctx, s.composeRecordTable())
-}
-
-// execLookupComposeRecord prepares ComposeRecord query and executes it,
-// returning types.Record (or error)
-func (s Store) execLookupComposeRecord(ctx context.Context, _mod *types.Module, cnd squirrel.Sqlizer) (res *types.Record, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.composeRecordsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalComposeRecordRowScanner(_mod, row)
- if err != nil {
- return
- }
-
- if err = s.composeRecordPostLoadProcessor(ctx, _mod, res); err != nil {
- return nil, err
- }
-
- return res, nil
-}
-
-// execCreateComposeRecords updates all matched (by cnd) rows in compose_record with given data
-func (s Store) execCreateComposeRecords(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.composeRecordTable()).SetMap(payload))
-}
-
-// execUpdateComposeRecords updates all matched (by cnd) rows in compose_record with given data
-func (s Store) execUpdateComposeRecords(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.composeRecordTable("crd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertComposeRecords inserts new or updates matching (by-primary-key) rows in compose_record with given data
-func (s Store) execUpsertComposeRecords(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.composeRecordTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteComposeRecords Deletes all matched (by cnd) rows in compose_record with given data
-func (s Store) execDeleteComposeRecords(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.composeRecordTable("crd")).Where(cnd))
-}
-
-func (s Store) internalComposeRecordRowScanner(_mod *types.Module, row rowScanner) (res *types.Record, err error) {
- res = &types.Record{}
-
- err = row.Scan(
- &res.ID,
- &res.ModuleID,
- &res.NamespaceID,
- &res.OwnedBy,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan composeRecord db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryComposeRecords returns squirrel.SelectBuilder with set table and all columns
-func (s Store) composeRecordsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.composeRecordTable("crd"), s.composeRecordColumns("crd")...)
-}
-
-// composeRecordTable name of the db table
-func (Store) composeRecordTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "compose_record" + alias
-}
-
-// ComposeRecordColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) composeRecordColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "module_id",
- alias + "rel_namespace",
- alias + "owned_by",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true false true true true true}
-
-// sortableComposeRecordColumns returns all ComposeRecord columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableComposeRecordColumns() map[string]string {
- return map[string]string{
- "id": "id", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalComposeRecordEncoder encodes fields from types.Record to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeComposeRecord
-// func when rdbms.customEncoder=true
-func (s Store) internalComposeRecordEncoder(res *types.Record) store.Payload {
- return store.Payload{
- "id": res.ID,
- "module_id": res.ModuleID,
- "rel_namespace": res.NamespaceID,
- "owned_by": res.OwnedBy,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkComposeRecordConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkComposeRecordConstraints(ctx context.Context, _mod *types.Module, res *types.Record) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/compose_records.go b/store/rdbms/compose_records.go
deleted file mode 100644
index 3068d892a..000000000
--- a/store/rdbms/compose_records.go
+++ /dev/null
@@ -1,793 +0,0 @@
-package rdbms
-
-import (
- "context"
- "database/sql"
- "fmt"
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/compose/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "github.com/cortezaproject/corteza-server/pkg/report"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-const (
- composeRecordValueAliasPfx = "rv_"
- composeRecordValueJoinTpl = "compose_record_value AS {alias} ON ({alias}.record_id = crd.id AND {alias}.name = '{field}' AND {alias}.deleted_at IS NULL)"
-)
-
-type (
- mftd struct {
- boolean bool
- numeric bool
- dateTime bool
- dateOnly bool
- timeOnly bool
- ref bool
- }
-)
-
-func buildComposeRecordsCursor(cfg *Config, m *types.Module) func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, func(key string) (builders.KeyMap, error) {
- if col, fd, is := isRealRecordCol(key); is {
- _, _, tcp, _ := cfg.CastModuleFieldToColumnType(fd, key)
- // These values here won't be casted
- return builders.KeyMap{
- FieldCast: col,
- TypeCast: col,
- TypeCastPtrn: tcp,
- }, nil
- }
-
- f := m.Fields.FindByName(key)
- if f == nil {
- return builders.KeyMap{}, fmt.Errorf("unknown module field %q used in a cursor", key)
- }
-
- _, fcp, tcp, err := cfg.CastModuleFieldToColumnType(f, f.Name)
- if err != nil {
- return builders.KeyMap{}, err
- }
-
- fc := fmt.Sprintf(fcp, key)
- tc := fmt.Sprintf(tcp, fc)
- rr := builders.KeyMap{
- FieldCast: fc,
- TypeCast: tc,
- TypeCastPtrn: tcp,
- }
-
- return rr, nil
- })
- }
-}
-
-// @todo support for partitioned records (records are partitioned into multiple record tables
-// in this case, values are no longer separated into record_value (key-value) table but encoded as JSON
-// @todo support for partitioned record with (optional) physical columns for record values
-// physical columns are part of module-field configuration
-
-// SearchComposeRecords returns all matching ComposeRecords from store
-func (s Store) SearchComposeRecords(ctx context.Context, m *types.Module, f types.RecordFilter) (types.RecordSet, types.RecordFilter, error) {
- var (
- set []*types.Record
- q squirrel.SelectBuilder
- )
-
- return set, f, func() (err error) {
- q, err = s.convertComposeRecordFilter(m, f)
- if err != nil {
- return
- }
-
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- if f.IncPageNavigation || f.IncTotal {
- return fmt.Errorf("not allowed to fetch page navigation or total item count with page cursor")
- }
-
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(nil); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Prevent sorting over multi-value fields
- //
- // Due to how values are currently stored, this causes duplication.
- // For now, we'll prevent this and address in future releases.
- for _, s := range f.Sort {
- f := m.Fields.FindByName(s.Column)
- if f != nil && f.Multi {
- return fmt.Errorf("not allowed to sort by multi-value fields: %s", s.Column)
- }
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = s.composeRecordsSorter(m, q, sort); err != nil {
- return
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfComposeRecords(
- ctx, m, q,
- f.Sort, f.PageCursor, f.Limit,
- f.Check,
- buildComposeRecordsCursor(s.config, m),
- )
-
- if err != nil {
- return
- }
-
- if f.IncPageNavigation || f.IncTotal {
- if f.IncTotal {
- // Calc total from the number of items fetched
- // even if we do build the page navigation
- f.Total = uint(len(set))
- }
- if f.Limit > 0 && uint(len(set)) == f.Limit {
- // Build page navigation ONLY when limit is set and
- // there are less items fetched then requested limit
- if nav, err := s.composeRecordsPageNavigation(ctx, m, q, f, f.Sort, buildComposeRecordsCursor(s.config, m)); err != nil {
- return err
- } else {
- f.Total = nav.Total
- f.PageNavigation = nav.PageNavigation
- }
-
- if !f.IncPageNavigation {
- // remove page navigation if not requested
- f.PageNavigation = nil
- }
-
- }
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetches a large number of records and generates page navigation and/or counts all records
-//
-// Func tries to minimize amount of data fetched & processed by loading 1000x set of records per page
-// We're storing only records (and fetch their values) used for generating values
-//
-// Caveats:
-// - this will only work if Check function DOES NOT RELY on record values
-func (s Store) composeRecordsPageNavigation(
- ctx context.Context,
- m *types.Module,
- q squirrel.SelectBuilder,
- f types.RecordFilter,
- sort filter.SortExprSet,
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (types.RecordFilter, error) {
- return f, func() (err error) {
- var (
- // holds set of last records from each page
- set []*types.Record
-
- supPageLimitFactor = 1000
- supPageLimit = f.Limit * uint(supPageLimitFactor)
- // super-page query; fetches large number of records to optimize page navigation and counting
- supPageQuery = q.Limit(uint64(supPageLimit))
-
- rows *sql.Rows
- res *types.Record
-
- cursor *filter.PagingCursor
- )
-
- // reset output on filter
- f.Total = 0
- f.PageNavigation = make([]*filter.Page, 0, supPageLimitFactor)
-
- for {
- rowsValid, rowsProcessed := 0, 0
-
- // reuse q for query with/without cursor
- if cursor == nil {
- // first page
- q = supPageQuery
- } else {
- //cursor.LThen = sort.Reversed()
- q = supPageQuery.Where(cursorCond(cursor))
- }
-
- if q, err = s.composeRecordPreLoadProcessor(q); err != nil {
- return
- }
-
- rows, err = s.Query(ctx, q)
- if err != nil {
- return err
- }
-
- defer rows.Close()
- for rows.Next() {
- rowsProcessed++
- if err = rows.Err(); err == nil {
- res, err = s.internalComposeRecordRowScanner(m, rows)
- }
-
- if err != nil {
- return err
- }
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if f.Check != nil {
- if chk, err := f.Check(res); err != nil {
- return err
- } else if !chk {
- continue
- }
- }
-
- rowsValid++
- f.Total++
-
- if f.Total%f.Limit == 0 {
- set = append(set, res)
- }
- }
-
- if f.Total%f.Limit != 0 {
- // append the rest
- set = append(set, res)
- }
-
- // fetch values for all last-records fetched in this iteration
- if err = s.composeRecordPostLoadProcessor(ctx, m, set[len(f.PageNavigation):]...); err != nil {
- return err
- }
-
- // generate cursor values for all records fetched in this iteration
- for _, r := range set[len(f.PageNavigation):] {
- f.PageNavigation = append(f.PageNavigation, &filter.Page{
- Page: uint(len(f.PageNavigation) + 1),
- Count: uint(rowsValid),
- Cursor: s.collectComposeRecordCursorValues(m, r, sort...),
- })
- }
-
- if uint(rowsProcessed) < supPageLimit {
- // fetched less than planned, assume entire matching record set is processed
- break
- }
-
- // get ready for next iteration and generate cursor
- cursor = f.PageNavigation[len(f.PageNavigation)-1].Cursor
- }
-
- // And prefix on at the beginning to point to 1st page (for consistency)
- if len(f.PageNavigation) > 0 {
- // reorder cursors and move them forward for 1 page,
- // going from last to 1st
- for p := len(f.PageNavigation) - 1; p > 0; p-- {
- f.PageNavigation[p].Cursor = f.PageNavigation[p-1].Cursor
- }
-
- // no need for cursor on the 1st page.
- f.PageNavigation[0].Cursor = nil
- }
-
- return nil
- }()
-}
-
-// LookupComposeRecordByID searches for compose record by ID
-// It returns compose record even if deleted
-func (s Store) LookupComposeRecordByID(ctx context.Context, m *types.Module, id uint64) (res *types.Record, err error) {
- res, err = s.lookupComposeRecordByID(ctx, m, id)
- if err != nil {
- return
- }
-
- return
-}
-
-// CreateComposeRecord creates one or more ComposeRecords in store
-func (s Store) CreateComposeRecord(ctx context.Context, m *types.Module, rr ...*types.Record) (err error) {
- if err = validateRecordModule(m, rr...); err != nil {
- return
- }
-
- for _, res := range rr {
-
- err = s.createComposeRecord(ctx, m, res)
- if err != nil {
- return
- }
-
- // Make sure all record-values are linked to the record
- res.Values.SetRecordID(res.ID)
-
- err = s.createComposeRecordValue(ctx, m, res.Values...)
- if err != nil {
- return
- }
- }
-
- return
-}
-
-// UpdateComposeRecord updates one or more (existing) ComposeRecords in store
-func (s Store) UpdateComposeRecord(ctx context.Context, m *types.Module, rr ...*types.Record) (err error) {
- if err = validateRecordModule(m, rr...); err != nil {
- return
- }
-
- for _, res := range rr {
- err = s.updateComposeRecord(ctx, m, res)
- if err != nil {
- return
- }
-
- cnd := squirrel.Eq{"record_id": res.ID}
-
- if res.DeletedAt != nil {
- // Record was deleted, set all values to deleted too
- err = s.execUpdateComposeRecordValues(ctx, cnd, store.Payload{"deleted_at": res.DeletedAt})
- if err != nil {
- return
- }
- } else {
- // we're following the old implementation here for now
- // all old values are Deleted and new inserted
- err = s.execDeleteComposeRecordValues(ctx, cnd)
- if err != nil {
- return
- }
-
- // Make sure all record-values are linked to the record
- res.Values.SetRecordID(res.ID)
-
- err = s.createComposeRecordValue(ctx, m, res.Values.GetClean()...)
- }
- }
-
- return
-}
-
-// PartialComposeRecordUpdate updates one or more existing ComposeRecords in store
-func (s Store) PartialComposeRecordUpdate(ctx context.Context, m *types.Module, onlyColumns []string, rr ...*types.Record) (err error) {
- if err = validateRecordModule(m, rr...); err != nil {
- return
- }
-
- return fmt.Errorf("partial compose record update is not supported")
-}
-
-// DeleteComposeRecord Deletes one or more ComposeRecords from store
-func (s Store) DeleteComposeRecord(ctx context.Context, m *types.Module, rr ...*types.Record) (err error) {
- if err = validateRecordModule(m, rr...); err != nil {
- return
- }
-
- for _, res := range rr {
- err = s.DeleteComposeRecordByID(ctx, m, res.ID)
- if err != nil {
- return
- }
- }
-
- return
-}
-
-// DeleteComposeRecord Deletes one or more ComposeRecords from store
-func (s Store) UpsertComposeRecord(ctx context.Context, m *types.Module, rr ...*types.Record) (err error) {
- if err = validateRecordModule(m, rr...); err != nil {
- return
- }
-
- for _, res := range rr {
- err = s.upsertComposeRecord(ctx, m, res)
- if err != nil {
- return
- }
- }
-
- return
-}
-
-// DeleteComposeRecordByID Deletes ComposeRecord from store
-func (s Store) DeleteComposeRecordByID(ctx context.Context, m *types.Module, ID uint64) (err error) {
- err = s.deleteComposeRecordByID(ctx, m, ID)
- if err != nil {
- return
- }
-
- err = s.Exec(ctx, s.DeleteBuilder(s.composeRecordValueTable("crv")).Where(squirrel.Eq{"crv.record_id": ID}))
- if err != nil {
- return
- }
-
- return
-}
-
-// TruncateComposeRecords Deletes all ComposeRecords from store
-func (s Store) TruncateComposeRecords(ctx context.Context, m *types.Module) (err error) {
- err = s.truncateComposeRecords(ctx, m)
- if err != nil {
- return
- }
-
- err = s.truncateComposeRecordValues(ctx, m)
- if err != nil {
- return
- }
-
- return
-}
-
-func (s Store) ComposeRecordReport(ctx context.Context, m *types.Module, metrics, dimensions, filter string) ([]map[string]interface{}, error) {
- return ComposeRecordReportBuilder(&s, m, metrics, dimensions, filter).Run(ctx)
-}
-
-func (s Store) ComposeRecordDatasource(ctx context.Context, m *types.Module, ld *report.LoadStepDefinition) (report.Datasource, error) {
- return ComposeRecordDatasourceBuilder(&s, m, ld)
-}
-
-func (s Store) convertComposeRecordFilter(m *types.Module, f types.RecordFilter) (query squirrel.SelectBuilder, err error) {
- if m == nil {
- err = fmt.Errorf("module not provided")
- return
- }
-
- if f.ModuleID == 0 {
- // In case Module ID on filter is not set,
- // values from provided module can be used
- f.ModuleID = m.ID
- } else if m.ID != f.ModuleID {
- err = fmt.Errorf("provided module does not match filter module ID")
- }
-
- if f.NamespaceID == 0 {
- // In case Namespace ID on filter is not set,
- // values from provided module can be used
- f.NamespaceID = m.NamespaceID
- } else if m.NamespaceID != f.NamespaceID {
- err = fmt.Errorf("provided module namespace ID does not match filter namespace ID")
- }
-
- var (
- joinedFields = []string{}
- alreadyJoined = func(f string) bool {
- for _, a := range joinedFields {
- if a == f {
- return true
- }
- }
-
- joinedFields = append(joinedFields, f)
- return false
- }
-
- identResolver = func(i ql.Ident) (ql.Ident, error) {
- var is bool
- if i.Value, _, is = isRealRecordCol(i.Value); is {
- i.Value += " "
- return i, nil
- }
-
- if !m.Fields.HasName(i.Value) {
- return i, fmt.Errorf("unknown field %q", i.Value)
- }
-
- if !alreadyJoined(i.Value) {
- join := composeRecordValueJoinTpl
- join = strings.ReplaceAll(join, "{alias}", composeRecordValueAliasPfx+i.Value)
- join = strings.ReplaceAll(join, "{field}", i.Value)
- query = query.LeftJoin(join)
- }
-
- return s.FieldToColumnTypeCaster(m.Fields.FindByName(i.Value), i)
- }
- )
-
- // Create query for fetching and counting records.
- query = s.composeRecordsSelectBuilder().
- Where("crd.module_id = ?", m.ID).
- Where("crd.rel_namespace = ?", m.NamespaceID)
-
- // Inc/exclude deleted records according to filter settings
- query = filter.StateCondition(query, "crd.deleted_at", f.Deleted)
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"crd.id": f.LabeledIDs})
- }
-
- // Parse filters.
- if f.Query != "" {
- var (
- // Filter parser
- fp = ql.NewParser()
-
- // Filter node
- fn ql.ASTNode
- )
-
- // Resolve all identifiers found in the query
- // into their table/column counterparts
- fp.OnIdent = identResolver
- fp.OnFunction = s.SqlFunctionHandler
-
- if fn, err = fp.ParseExpression(f.Query); err != nil {
- return
- } else if filterSql, filterArgs, err := fn.ToSql(); err != nil {
- return query, err
- } else {
- query = query.Where("("+filterSql+")", filterArgs...)
- }
- }
-
- if len(f.Sort) > 0 {
- var (
- // Sort parser
- sp = ql.NewParser()
- )
-
- // Resolve all identifiers found in sort
- // into their table/column counterparts
- sp.OnIdent = identResolver
- sp.OnFunction = s.SqlFunctionHandler
-
- if _, err = sp.ParseColumns(f.Sort.String()); err != nil {
- return
- }
- }
-
- if f.PageCursor != nil {
- var (
- // Sort parser
- sp = ql.NewParser()
- )
-
- // Resolve all identifiers found in sort
- // into their table/column counterparts
- sp.OnIdent = identResolver
-
- if _, err = sp.ParseColumns(strings.Join(f.PageCursor.Keys(), ", ")); err != nil {
- return
- }
- }
-
- return
-}
-
-//func (s Store) convertComposeRecordCursor(m *types.Module, from *filter.PagingCursor) (to *filter.PagingCursor) {
-// if from != nil {
-// to = &filter.PagingCursor{ROrder: from.ROrder, LThen: from.LThen}
-// // convert cursor keys field names (if used)
-// from.Walk(func(key string, val interface{}, desc bool) {
-// if col, has := s.sortableComposeRecordColumns()[strings.ToLower(key)]; has {
-// key = col
-// } else if f := m.Fields.FindByName(key); f != nil {
-// key, _ = s.config.CastModuleFieldToColumnType(f, key)
-// } else {
-// return
-// }
-//
-// to.Set(key, val, desc)
-// })
-//
-// }
-//
-// return to
-//}
-
-func (s Store) composeRecordPostLoadProcessor(ctx context.Context, m *types.Module, set ...*types.Record) (err error) {
- if len(set) > 0 {
- // Load all related record values and append them to each record
- var (
- rvs types.RecordValueSet
- )
-
- rvs, _, err = s.searchComposeRecordValues(ctx, nil, types.RecordValueFilter{
- RecordID: types.RecordSet(set).IDs(),
- Deleted: filter.StateInclusive,
- })
-
- if err != nil {
- return
- }
-
- for r := range set {
- set[r].SetModule(m)
- set[r].Values = rvs.FilterByRecordID(set[r].ID)
- }
- }
-
- return nil
-}
-
-func (s Store) composeRecordPreLoadProcessor(q squirrel.SelectBuilder) (squirrel.SelectBuilder, error) {
- // When filtering over multi value record values we can get multiple rows of the same record
- // causing it to show as a duplicate in the output.
- // This partitioning removes any duplicate rows (rows where the index is not 1).
- return squirrel.Select(s.composeRecordColumns()...).
- PlaceholderFormat(s.config.PlaceholderFormat).
- FromSelect(q.Column("row_number() over (partition by id) as pp_rn"), "base").
- Where("pp_rn = 1"), nil
-}
-
-func (s Store) composeRecordsSorter(m *types.Module, q squirrel.SelectBuilder, sort filter.SortExprSet) (squirrel.SelectBuilder, error) {
- var (
- sortable = s.sortableComposeRecordColumns()
- sqlSort = make([]string, len(sort))
- )
-
- for i, c := range sort {
- var err error
- if col, has := sortable[strings.ToLower(c.Column)]; has {
- sqlSort[i] = col
- } else if f := m.Fields.FindByName(c.Column); f != nil {
-
- sqlSort[i], _, _, err = s.config.CastModuleFieldToColumnType(f, c.Column)
- } else {
- err = fmt.Errorf("could not sort by unknown column: %s", c.Column)
- }
-
- if err != nil {
- return q, err
- }
-
- // Apply proper sorting param
- sqlSort[i] = s.config.SqlSortHandler(sqlSort[i], sort[i].Descending)
- }
-
- return q.OrderBy(sqlSort...), nil
-}
-
-// Custom implementation for collecting cursor values from compose records AND it's values!
-func (s Store) collectComposeRecordCursorValues(m *types.Module, res *types.Record, sort ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(sort).Reversed()}
-
- hasUnique bool
- pkID bool
-
- conv = s.sortableComposeRecordColumns()
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch conv[strings.ToLower(c.Column)] {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
- pkID = true
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
- case "created_by":
- cursor.Set(c.Column, res.CreatedBy, c.Descending)
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
- case "updated_by":
- cursor.Set(c.Column, res.UpdatedBy, c.Descending)
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
- case "deleted_by":
- cursor.Set(c.Column, res.DeletedBy, c.Descending)
- case "owned_by":
- cursor.Set(c.Column, res.OwnedBy, c.Descending)
- default:
- if rv := res.Values.Get(c.Column, 0); rv != nil {
- cursor.Set(c.Column, rv.Value, c.Descending)
- } else {
- cursor.Set(c.Column, nil, c.Descending)
- }
- }
- }
- }
- )
-
- collect(sort...)
- if !hasUnique || !pkID {
- collect(&filter.SortExpr{Column: "id"})
- }
-
- return cursor
-}
-
-//// Checks if field name is "real column", reformats it and returns
-func isRealRecordCol(name string) (string, mftd, bool) {
- switch name {
- case
- "recordID",
- "id":
- return "crd.id", mftd{ref: true}, true
-
- case
- "module_id",
- "owned_by",
- "created_by",
- "updated_by",
- "deleted_by":
- return "crd." + name, mftd{ref: true}, true
-
- case
- "created_at",
- "updated_at",
- "deleted_at":
- return "crd." + name, mftd{dateTime: true}, true
-
- case
- "moduleID",
- "ownedBy",
- "createdBy",
- "updatedBy",
- "deletedBy":
- return "crd." + name[0:len(name)-2] + "_" + strings.ToLower(name[len(name)-2:]), mftd{ref: true}, true
-
- case
- "createdAt",
- "updatedAt",
- "deletedAt":
- return "crd." + name[0:len(name)-2] + "_" + strings.ToLower(name[len(name)-2:]), mftd{dateTime: true}, true
- }
-
- return name, mftd{}, false
-}
-
-// Verifies if module and namespace ID on record match IDs on module
-func validateRecordModule(m *types.Module, rr ...*types.Record) error {
- for _, r := range rr {
- if m.ID != r.ModuleID {
- return fmt.Errorf("provided module does not match module ID on record")
- }
-
- if m.NamespaceID != r.NamespaceID {
- return fmt.Errorf("provided module namespace ID does not match namespace ID on record")
- }
- }
-
- return nil
-}
-
-func (t mftd) IsBoolean() bool {
- return t.boolean
-}
-func (t mftd) IsNumeric() bool {
- return t.numeric
-}
-func (t mftd) IsDateTime() bool {
- return t.dateTime
-}
-func (t mftd) IsDateOnly() bool {
- return t.dateOnly
-}
-func (t mftd) IsTimeOnly() bool {
- return t.timeOnly
-}
-func (t mftd) IsRef() bool {
- return t.ref
-}
diff --git a/store/rdbms/credentials.gen.go b/store/rdbms/credentials.gen.go
deleted file mode 100644
index 6616b024a..000000000
--- a/store/rdbms/credentials.gen.go
+++ /dev/null
@@ -1,351 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/credentials.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchCredentials returns all matching rows
-//
-// This function calls convertCredentialsFilter with the given
-// types.CredentialsFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchCredentials(ctx context.Context, f types.CredentialsFilter) (types.CredentialsSet, types.CredentialsFilter, error) {
- var (
- err error
- set []*types.Credentials
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertCredentialsFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryCredentials(ctx, q, nil)
- return err
- }()
-}
-
-// QueryCredentials queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryCredentials(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Credentials) (bool, error),
-) ([]*types.Credentials, error) {
- var (
- tmp = make([]*types.Credentials, 0, DefaultSliceCapacity)
- set = make([]*types.Credentials, 0, DefaultSliceCapacity)
- res *types.Credentials
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalCredentialsRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupCredentialsByID searches for credentials by ID
-//
-// It returns credentials even if deleted
-func (s Store) LookupCredentialsByID(ctx context.Context, id uint64) (*types.Credentials, error) {
- return s.execLookupCredentials(ctx, squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateCredentials creates one or more rows in credentials table
-func (s Store) CreateCredentials(ctx context.Context, rr ...*types.Credentials) (err error) {
- for _, res := range rr {
- err = s.checkCredentialsConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateCredentials(ctx, s.internalCredentialsEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateCredentials updates one or more existing rows in credentials
-func (s Store) UpdateCredentials(ctx context.Context, rr ...*types.Credentials) error {
- return s.partialCredentialsUpdate(ctx, nil, rr...)
-}
-
-// partialCredentialsUpdate updates one or more existing rows in credentials
-func (s Store) partialCredentialsUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Credentials) (err error) {
- for _, res := range rr {
- err = s.checkCredentialsConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateCredentials(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalCredentialsEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertCredentials updates one or more existing rows in credentials
-func (s Store) UpsertCredentials(ctx context.Context, rr ...*types.Credentials) (err error) {
- for _, res := range rr {
- err = s.checkCredentialsConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertCredentials(ctx, s.internalCredentialsEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteCredentials Deletes one or more rows from credentials table
-func (s Store) DeleteCredentials(ctx context.Context, rr ...*types.Credentials) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteCredentials(ctx, squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteCredentialsByID Deletes row from the credentials table
-func (s Store) DeleteCredentialsByID(ctx context.Context, ID uint64) error {
- return s.execDeleteCredentials(ctx, squirrel.Eq{
- s.preprocessColumn("crd.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateCredentials Deletes all rows from the credentials table
-func (s Store) TruncateCredentials(ctx context.Context) error {
- return s.Truncate(ctx, s.credentialsTable())
-}
-
-// execLookupCredentials prepares Credentials query and executes it,
-// returning types.Credentials (or error)
-func (s Store) execLookupCredentials(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Credentials, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.credentialsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalCredentialsRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateCredentials updates all matched (by cnd) rows in credentials with given data
-func (s Store) execCreateCredentials(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.credentialsTable()).SetMap(payload))
-}
-
-// execUpdateCredentials updates all matched (by cnd) rows in credentials with given data
-func (s Store) execUpdateCredentials(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.credentialsTable("crd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertCredentials inserts new or updates matching (by-primary-key) rows in credentials with given data
-func (s Store) execUpsertCredentials(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.credentialsTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteCredentials Deletes all matched (by cnd) rows in credentials with given data
-func (s Store) execDeleteCredentials(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.credentialsTable("crd")).Where(cnd))
-}
-
-func (s Store) internalCredentialsRowScanner(row rowScanner) (res *types.Credentials, err error) {
- res = &types.Credentials{}
-
- err = row.Scan(
- &res.ID,
- &res.OwnerID,
- &res.Kind,
- &res.Label,
- &res.Credentials,
- &res.Meta,
- &res.LastUsedAt,
- &res.ExpiresAt,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan credentials db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryCredentials returns squirrel.SelectBuilder with set table and all columns
-func (s Store) credentialsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.credentialsTable("crd"), s.credentialsColumns("crd")...)
-}
-
-// credentialsTable name of the db table
-func (Store) credentialsTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "credentials" + alias
-}
-
-// CredentialsColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) credentialsColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_owner",
- alias + "kind",
- alias + "label",
- alias + "credentials",
- alias + "meta",
- alias + "last_used_at",
- alias + "expires_at",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false false false false}
-
-// internalCredentialsEncoder encodes fields from types.Credentials to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeCredentials
-// func when rdbms.customEncoder=true
-func (s Store) internalCredentialsEncoder(res *types.Credentials) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_owner": res.OwnerID,
- "kind": res.Kind,
- "label": res.Label,
- "credentials": res.Credentials,
- "meta": res.Meta,
- "last_used_at": res.LastUsedAt,
- "expires_at": res.ExpiresAt,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkCredentialsConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkCredentialsConstraints(ctx context.Context, res *types.Credentials) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/credentials.go b/store/rdbms/credentials.go
deleted file mode 100644
index 1db5a5bbc..000000000
--- a/store/rdbms/credentials.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertCredentialsFilter(f types.CredentialsFilter) (query squirrel.SelectBuilder, err error) {
- query = s.credentialsSelectBuilder()
-
- query = filter.StateCondition(query, "crd.deleted_at", f.Deleted)
-
- if f.Kind != "" {
- query = query.Where(squirrel.Eq{"crd.kind": f.Kind})
- }
-
- if f.Credentials != "" {
- query = query.Where(squirrel.Eq{"crd.credentials": f.Credentials})
- }
-
- if f.OwnerID > 0 {
- query = query.Where(squirrel.Eq{"crd.rel_owner": f.OwnerID})
- }
-
- return
-}
diff --git a/store/rdbms/federation_exposed_modules.gen.go b/store/rdbms/federation_exposed_modules.gen.go
deleted file mode 100644
index 583bbae30..000000000
--- a/store/rdbms/federation_exposed_modules.gen.go
+++ /dev/null
@@ -1,602 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/federation_exposed_modules.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchFederationExposedModules returns all matching rows
-//
-// This function calls convertFederationExposedModuleFilter with the given
-// types.ExposedModuleFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchFederationExposedModules(ctx context.Context, f types.ExposedModuleFilter) (types.ExposedModuleSet, types.ExposedModuleFilter, error) {
- var (
- err error
- set []*types.ExposedModule
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertFederationExposedModuleFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableFederationExposedModuleColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationExposedModules(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfFederationExposedModules collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfFederationExposedModules(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.ExposedModule) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.ExposedModule, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.ExposedModule
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.ExposedModule, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryFederationExposedModules(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectFederationExposedModuleCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectFederationExposedModuleCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectFederationExposedModuleCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryFederationExposedModules queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryFederationExposedModules(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ExposedModule) (bool, error),
-) ([]*types.ExposedModule, error) {
- var (
- tmp = make([]*types.ExposedModule, 0, DefaultSliceCapacity)
- set = make([]*types.ExposedModule, 0, DefaultSliceCapacity)
- res *types.ExposedModule
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalFederationExposedModuleRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupFederationExposedModuleByID searches for federation module by ID
-//
-// It returns federation module
-func (s Store) LookupFederationExposedModuleByID(ctx context.Context, id uint64) (*types.ExposedModule, error) {
- return s.execLookupFederationExposedModule(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateFederationExposedModule creates one or more rows in federation_module_exposed table
-func (s Store) CreateFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) (err error) {
- for _, res := range rr {
- err = s.checkFederationExposedModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateFederationExposedModules(ctx, s.internalFederationExposedModuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateFederationExposedModule updates one or more existing rows in federation_module_exposed
-func (s Store) UpdateFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) error {
- return s.partialFederationExposedModuleUpdate(ctx, nil, rr...)
-}
-
-// partialFederationExposedModuleUpdate updates one or more existing rows in federation_module_exposed
-func (s Store) partialFederationExposedModuleUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ExposedModule) (err error) {
- for _, res := range rr {
- err = s.checkFederationExposedModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateFederationExposedModules(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalFederationExposedModuleEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertFederationExposedModule updates one or more existing rows in federation_module_exposed
-func (s Store) UpsertFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) (err error) {
- for _, res := range rr {
- err = s.checkFederationExposedModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertFederationExposedModules(ctx, s.internalFederationExposedModuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationExposedModule Deletes one or more rows from federation_module_exposed table
-func (s Store) DeleteFederationExposedModule(ctx context.Context, rr ...*types.ExposedModule) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteFederationExposedModules(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationExposedModuleByID Deletes row from the federation_module_exposed table
-func (s Store) DeleteFederationExposedModuleByID(ctx context.Context, ID uint64) error {
- return s.execDeleteFederationExposedModules(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateFederationExposedModules Deletes all rows from the federation_module_exposed table
-func (s Store) TruncateFederationExposedModules(ctx context.Context) error {
- return s.Truncate(ctx, s.federationExposedModuleTable())
-}
-
-// execLookupFederationExposedModule prepares FederationExposedModule query and executes it,
-// returning types.ExposedModule (or error)
-func (s Store) execLookupFederationExposedModule(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ExposedModule, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.federationExposedModulesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalFederationExposedModuleRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateFederationExposedModules updates all matched (by cnd) rows in federation_module_exposed with given data
-func (s Store) execCreateFederationExposedModules(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.federationExposedModuleTable()).SetMap(payload))
-}
-
-// execUpdateFederationExposedModules updates all matched (by cnd) rows in federation_module_exposed with given data
-func (s Store) execUpdateFederationExposedModules(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.federationExposedModuleTable("cmd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertFederationExposedModules inserts new or updates matching (by-primary-key) rows in federation_module_exposed with given data
-func (s Store) execUpsertFederationExposedModules(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.federationExposedModuleTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteFederationExposedModules Deletes all matched (by cnd) rows in federation_module_exposed with given data
-func (s Store) execDeleteFederationExposedModules(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.federationExposedModuleTable("cmd")).Where(cnd))
-}
-
-func (s Store) internalFederationExposedModuleRowScanner(row rowScanner) (res *types.ExposedModule, err error) {
- res = &types.ExposedModule{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Name,
- &res.NodeID,
- &res.ComposeModuleID,
- &res.ComposeNamespaceID,
- &res.Fields,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan federationExposedModule db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryFederationExposedModules returns squirrel.SelectBuilder with set table and all columns
-func (s Store) federationExposedModulesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.federationExposedModuleTable("cmd"), s.federationExposedModuleColumns("cmd")...)
-}
-
-// federationExposedModuleTable name of the db table
-func (Store) federationExposedModuleTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "federation_module_exposed" + alias
-}
-
-// FederationExposedModuleColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) federationExposedModuleColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "name",
- alias + "rel_node",
- alias + "rel_compose_module",
- alias + "rel_compose_namespace",
- alias + "fields",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableFederationExposedModuleColumns returns all FederationExposedModule columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableFederationExposedModuleColumns() map[string]string {
- return map[string]string{
- "id": "id",
- }
-}
-
-// internalFederationExposedModuleEncoder encodes fields from types.ExposedModule to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeFederationExposedModule
-// func when rdbms.customEncoder=true
-func (s Store) internalFederationExposedModuleEncoder(res *types.ExposedModule) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "name": res.Name,
- "rel_node": res.NodeID,
- "rel_compose_module": res.ComposeModuleID,
- "rel_compose_namespace": res.ComposeNamespaceID,
- "fields": res.Fields,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectFederationExposedModuleCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectFederationExposedModuleCursorValues(res *types.ExposedModule, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkFederationExposedModuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkFederationExposedModuleConstraints(ctx context.Context, res *types.ExposedModule) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/federation_exposed_modules.go b/store/rdbms/federation_exposed_modules.go
deleted file mode 100644
index 9833ff6d4..000000000
--- a/store/rdbms/federation_exposed_modules.go
+++ /dev/null
@@ -1,34 +0,0 @@
-package rdbms
-
-import (
- "time"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-func (s Store) convertFederationExposedModuleFilter(f types.ExposedModuleFilter) (query squirrel.SelectBuilder, err error) {
- query = s.federationExposedModulesSelectBuilder()
-
- if f.NodeID > 0 {
- query = query.Where("cmd.rel_node = ?", f.NodeID)
- }
-
- if f.ComposeModuleID > 0 {
- query = query.Where("cmd.rel_compose_module = ?", f.ComposeModuleID)
- }
-
- if f.ComposeNamespaceID > 0 {
- query = query.Where("cmd.rel_compose_namespace = ?", f.ComposeNamespaceID)
- }
-
- if f.LastSync > 0 {
- t := time.Unix(int64(f.LastSync), 0)
-
- if !t.IsZero() {
- query = query.Where("(cmd.updated_at >= ? OR cmd.created_at >= ?)", t.UTC().Format(time.RFC3339), t.UTC().Format(time.RFC3339))
- }
- }
-
- return
-}
diff --git a/store/rdbms/federation_module_mappings.gen.go b/store/rdbms/federation_module_mappings.gen.go
deleted file mode 100644
index 5194a94e4..000000000
--- a/store/rdbms/federation_module_mappings.gen.go
+++ /dev/null
@@ -1,619 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/federation_module_mappings.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchFederationModuleMappings returns all matching rows
-//
-// This function calls convertFederationModuleMappingFilter with the given
-// types.ModuleMappingFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchFederationModuleMappings(ctx context.Context, f types.ModuleMappingFilter) (types.ModuleMappingSet, types.ModuleMappingFilter, error) {
- var (
- err error
- set []*types.ModuleMapping
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertFederationModuleMappingFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("rel_federation_module") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "rel_federation_module",
- Descending: f.Sort.LastDescending(),
- })
- }
- if f.Sort.Get("rel_compose_module") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "rel_compose_module",
- Descending: f.Sort.LastDescending(),
- })
- }
- if f.Sort.Get("rel_compose_namespace") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "rel_compose_namespace",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableFederationModuleMappingColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationModuleMappings(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfFederationModuleMappings collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfFederationModuleMappings(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.ModuleMapping) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.ModuleMapping, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.ModuleMapping
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.ModuleMapping, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryFederationModuleMappings(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectFederationModuleMappingCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectFederationModuleMappingCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectFederationModuleMappingCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryFederationModuleMappings queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryFederationModuleMappings(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ModuleMapping) (bool, error),
-) ([]*types.ModuleMapping, error) {
- var (
- tmp = make([]*types.ModuleMapping, 0, DefaultSliceCapacity)
- set = make([]*types.ModuleMapping, 0, DefaultSliceCapacity)
- res *types.ModuleMapping
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalFederationModuleMappingRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID searches for module mapping by federation module id and compose module id
-//
-// It returns module mapping
-func (s Store) LookupFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, federation_module_id uint64, compose_module_id uint64, compose_namespace_id uint64) (*types.ModuleMapping, error) {
- return s.execLookupFederationModuleMapping(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.rel_federation_module", ""): store.PreprocessValue(federation_module_id, ""),
- s.preprocessColumn("cmd.rel_compose_module", ""): store.PreprocessValue(compose_module_id, ""),
- s.preprocessColumn("cmd.rel_compose_namespace", ""): store.PreprocessValue(compose_namespace_id, ""),
- })
-}
-
-// LookupFederationModuleMappingByFederationModuleID searches for module mapping by federation module id
-//
-// It returns module mapping
-func (s Store) LookupFederationModuleMappingByFederationModuleID(ctx context.Context, federation_module_id uint64) (*types.ModuleMapping, error) {
- return s.execLookupFederationModuleMapping(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.rel_federation_module", ""): store.PreprocessValue(federation_module_id, ""),
- })
-}
-
-// CreateFederationModuleMapping creates one or more rows in federation_module_mapping table
-func (s Store) CreateFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) (err error) {
- for _, res := range rr {
- err = s.checkFederationModuleMappingConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateFederationModuleMappings(ctx, s.internalFederationModuleMappingEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateFederationModuleMapping updates one or more existing rows in federation_module_mapping
-func (s Store) UpdateFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) error {
- return s.partialFederationModuleMappingUpdate(ctx, nil, rr...)
-}
-
-// partialFederationModuleMappingUpdate updates one or more existing rows in federation_module_mapping
-func (s Store) partialFederationModuleMappingUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ModuleMapping) (err error) {
- for _, res := range rr {
- err = s.checkFederationModuleMappingConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateFederationModuleMappings(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cmd.rel_federation_module", ""): store.PreprocessValue(res.FederationModuleID, ""), s.preprocessColumn("cmd.rel_compose_module", ""): store.PreprocessValue(res.ComposeModuleID, ""), s.preprocessColumn("cmd.rel_compose_namespace", ""): store.PreprocessValue(res.ComposeNamespaceID, ""),
- },
- s.internalFederationModuleMappingEncoder(res).Skip("rel_federation_module", "rel_compose_module", "rel_compose_namespace").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertFederationModuleMapping updates one or more existing rows in federation_module_mapping
-func (s Store) UpsertFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) (err error) {
- for _, res := range rr {
- err = s.checkFederationModuleMappingConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertFederationModuleMappings(ctx, s.internalFederationModuleMappingEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationModuleMapping Deletes one or more rows from federation_module_mapping table
-func (s Store) DeleteFederationModuleMapping(ctx context.Context, rr ...*types.ModuleMapping) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteFederationModuleMappings(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.rel_federation_module", ""): store.PreprocessValue(res.FederationModuleID, ""), s.preprocessColumn("cmd.rel_compose_module", ""): store.PreprocessValue(res.ComposeModuleID, ""), s.preprocessColumn("cmd.rel_compose_namespace", ""): store.PreprocessValue(res.ComposeNamespaceID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID Deletes row from the federation_module_mapping table
-func (s Store) DeleteFederationModuleMappingByFederationModuleIDComposeModuleIDComposeNamespaceID(ctx context.Context, federationModuleID uint64, composeModuleID uint64, composeNamespaceID uint64) error {
- return s.execDeleteFederationModuleMappings(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.rel_federation_module", ""): store.PreprocessValue(federationModuleID, ""),
- s.preprocessColumn("cmd.rel_compose_module", ""): store.PreprocessValue(composeModuleID, ""),
- s.preprocessColumn("cmd.rel_compose_namespace", ""): store.PreprocessValue(composeNamespaceID, ""),
- })
-}
-
-// TruncateFederationModuleMappings Deletes all rows from the federation_module_mapping table
-func (s Store) TruncateFederationModuleMappings(ctx context.Context) error {
- return s.Truncate(ctx, s.federationModuleMappingTable())
-}
-
-// execLookupFederationModuleMapping prepares FederationModuleMapping query and executes it,
-// returning types.ModuleMapping (or error)
-func (s Store) execLookupFederationModuleMapping(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ModuleMapping, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.federationModuleMappingsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalFederationModuleMappingRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateFederationModuleMappings updates all matched (by cnd) rows in federation_module_mapping with given data
-func (s Store) execCreateFederationModuleMappings(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.federationModuleMappingTable()).SetMap(payload))
-}
-
-// execUpdateFederationModuleMappings updates all matched (by cnd) rows in federation_module_mapping with given data
-func (s Store) execUpdateFederationModuleMappings(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.federationModuleMappingTable("cmd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertFederationModuleMappings inserts new or updates matching (by-primary-key) rows in federation_module_mapping with given data
-func (s Store) execUpsertFederationModuleMappings(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.federationModuleMappingTable(),
- set,
- s.preprocessColumn("rel_federation_module", ""),
- s.preprocessColumn("rel_compose_module", ""),
- s.preprocessColumn("rel_compose_namespace", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteFederationModuleMappings Deletes all matched (by cnd) rows in federation_module_mapping with given data
-func (s Store) execDeleteFederationModuleMappings(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.federationModuleMappingTable("cmd")).Where(cnd))
-}
-
-func (s Store) internalFederationModuleMappingRowScanner(row rowScanner) (res *types.ModuleMapping, err error) {
- res = &types.ModuleMapping{}
-
- err = row.Scan(
- &res.FederationModuleID,
- &res.ComposeModuleID,
- &res.ComposeNamespaceID,
- &res.FieldMapping,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan federationModuleMapping db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryFederationModuleMappings returns squirrel.SelectBuilder with set table and all columns
-func (s Store) federationModuleMappingsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.federationModuleMappingTable("cmd"), s.federationModuleMappingColumns("cmd")...)
-}
-
-// federationModuleMappingTable name of the db table
-func (Store) federationModuleMappingTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "federation_module_mapping" + alias
-}
-
-// FederationModuleMappingColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) federationModuleMappingColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "rel_federation_module",
- alias + "rel_compose_module",
- alias + "rel_compose_namespace",
- alias + "field_mapping",
- }
-}
-
-// {true true false true true true}
-
-// sortableFederationModuleMappingColumns returns all FederationModuleMapping columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableFederationModuleMappingColumns() map[string]string {
- return map[string]string{
- "rel_federation_module": "rel_federation_module",
- "federationmoduleid": "rel_federation_module",
- "rel_compose_module": "rel_compose_module",
- "composemoduleid": "rel_compose_module",
- "rel_compose_namespace": "rel_compose_namespace",
- "composenamespaceid": "rel_compose_namespace",
- }
-}
-
-// internalFederationModuleMappingEncoder encodes fields from types.ModuleMapping to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeFederationModuleMapping
-// func when rdbms.customEncoder=true
-func (s Store) internalFederationModuleMappingEncoder(res *types.ModuleMapping) store.Payload {
- return store.Payload{
- "rel_federation_module": res.FederationModuleID,
- "rel_compose_module": res.ComposeModuleID,
- "rel_compose_namespace": res.ComposeNamespaceID,
- "field_mapping": res.FieldMapping,
- }
-}
-
-// collectFederationModuleMappingCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectFederationModuleMappingCursorValues(res *types.ModuleMapping, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkRel_federation_module bool
-
- pkRel_compose_module bool
-
- pkRel_compose_namespace bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "rel_federation_module":
- cursor.Set(c.Column, res.FederationModuleID, c.Descending)
-
- pkRel_federation_module = true
- case "rel_compose_module":
- cursor.Set(c.Column, res.ComposeModuleID, c.Descending)
-
- pkRel_compose_module = true
- case "rel_compose_namespace":
- cursor.Set(c.Column, res.ComposeNamespaceID, c.Descending)
-
- pkRel_compose_namespace = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkRel_federation_module && pkRel_compose_module && pkRel_compose_namespace && true) {
- collect(&filter.SortExpr{Column: "rel_federation_module", Descending: false}, &filter.SortExpr{Column: "rel_compose_module", Descending: false}, &filter.SortExpr{Column: "rel_compose_namespace", Descending: false})
- }
-
- return cursor
-}
-
-// checkFederationModuleMappingConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkFederationModuleMappingConstraints(ctx context.Context, res *types.ModuleMapping) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/federation_module_mappings.go b/store/rdbms/federation_module_mappings.go
deleted file mode 100644
index 8ad5e3d43..000000000
--- a/store/rdbms/federation_module_mappings.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-func (s Store) convertFederationModuleMappingFilter(f types.ModuleMappingFilter) (query squirrel.SelectBuilder, err error) {
- query = s.federationModuleMappingsSelectBuilder()
-
- if f.ComposeModuleID > 0 {
- query = query.Where("cmd.rel_compose_module = ?", f.ComposeModuleID)
- }
-
- if f.FederationModuleID > 0 {
- query = query.Where("cmd.rel_federation_module = ?", f.FederationModuleID)
- }
-
- if f.ComposeNamespaceID > 0 {
- query = query.Where("cmd.rel_compose_namespace = ?", f.ComposeNamespaceID)
- }
-
- return
-}
diff --git a/store/rdbms/federation_nodes.gen.go b/store/rdbms/federation_nodes.gen.go
deleted file mode 100644
index 590e6b0b9..000000000
--- a/store/rdbms/federation_nodes.gen.go
+++ /dev/null
@@ -1,385 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/federation_nodes.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchFederationNodes returns all matching rows
-//
-// This function calls convertFederationNodeFilter with the given
-// types.NodeFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchFederationNodes(ctx context.Context, f types.NodeFilter) (types.NodeSet, types.NodeFilter, error) {
- var (
- err error
- set []*types.Node
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertFederationNodeFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryFederationNodes(ctx, q, f.Check)
- return err
- }()
-}
-
-// QueryFederationNodes queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryFederationNodes(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Node) (bool, error),
-) ([]*types.Node, error) {
- var (
- tmp = make([]*types.Node, 0, DefaultSliceCapacity)
- set = make([]*types.Node, 0, DefaultSliceCapacity)
- res *types.Node
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalFederationNodeRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupFederationNodeByID searches for federation node by ID
-//
-// It returns federation node
-func (s Store) LookupFederationNodeByID(ctx context.Context, id uint64) (*types.Node, error) {
- return s.execLookupFederationNode(ctx, squirrel.Eq{
- s.preprocessColumn("fdn.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupFederationNodeByBaseURLSharedNodeID searches for node by shared-node-id and base-url
-func (s Store) LookupFederationNodeByBaseURLSharedNodeID(ctx context.Context, base_url string, shared_node_id uint64) (*types.Node, error) {
- return s.execLookupFederationNode(ctx, squirrel.Eq{
- s.preprocessColumn("fdn.base_url", ""): store.PreprocessValue(base_url, ""),
- s.preprocessColumn("fdn.shared_node_id", ""): store.PreprocessValue(shared_node_id, ""),
- })
-}
-
-// LookupFederationNodeBySharedNodeID searches for node by shared-node-id
-func (s Store) LookupFederationNodeBySharedNodeID(ctx context.Context, shared_node_id uint64) (*types.Node, error) {
- return s.execLookupFederationNode(ctx, squirrel.Eq{
- s.preprocessColumn("fdn.shared_node_id", ""): store.PreprocessValue(shared_node_id, ""),
- })
-}
-
-// CreateFederationNode creates one or more rows in federation_nodes table
-func (s Store) CreateFederationNode(ctx context.Context, rr ...*types.Node) (err error) {
- for _, res := range rr {
- err = s.checkFederationNodeConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateFederationNodes(ctx, s.internalFederationNodeEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateFederationNode updates one or more existing rows in federation_nodes
-func (s Store) UpdateFederationNode(ctx context.Context, rr ...*types.Node) error {
- return s.partialFederationNodeUpdate(ctx, nil, rr...)
-}
-
-// partialFederationNodeUpdate updates one or more existing rows in federation_nodes
-func (s Store) partialFederationNodeUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Node) (err error) {
- for _, res := range rr {
- err = s.checkFederationNodeConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateFederationNodes(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("fdn.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalFederationNodeEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertFederationNode updates one or more existing rows in federation_nodes
-func (s Store) UpsertFederationNode(ctx context.Context, rr ...*types.Node) (err error) {
- for _, res := range rr {
- err = s.checkFederationNodeConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertFederationNodes(ctx, s.internalFederationNodeEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationNode Deletes one or more rows from federation_nodes table
-func (s Store) DeleteFederationNode(ctx context.Context, rr ...*types.Node) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteFederationNodes(ctx, squirrel.Eq{
- s.preprocessColumn("fdn.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationNodeByID Deletes row from the federation_nodes table
-func (s Store) DeleteFederationNodeByID(ctx context.Context, ID uint64) error {
- return s.execDeleteFederationNodes(ctx, squirrel.Eq{
- s.preprocessColumn("fdn.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateFederationNodes Deletes all rows from the federation_nodes table
-func (s Store) TruncateFederationNodes(ctx context.Context) error {
- return s.Truncate(ctx, s.federationNodeTable())
-}
-
-// execLookupFederationNode prepares FederationNode query and executes it,
-// returning types.Node (or error)
-func (s Store) execLookupFederationNode(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Node, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.federationNodesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalFederationNodeRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateFederationNodes updates all matched (by cnd) rows in federation_nodes with given data
-func (s Store) execCreateFederationNodes(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.federationNodeTable()).SetMap(payload))
-}
-
-// execUpdateFederationNodes updates all matched (by cnd) rows in federation_nodes with given data
-func (s Store) execUpdateFederationNodes(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.federationNodeTable("fdn")).Where(cnd).SetMap(set))
-}
-
-// execUpsertFederationNodes inserts new or updates matching (by-primary-key) rows in federation_nodes with given data
-func (s Store) execUpsertFederationNodes(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.federationNodeTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteFederationNodes Deletes all matched (by cnd) rows in federation_nodes with given data
-func (s Store) execDeleteFederationNodes(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.federationNodeTable("fdn")).Where(cnd))
-}
-
-func (s Store) internalFederationNodeRowScanner(row rowScanner) (res *types.Node, err error) {
- res = &types.Node{}
-
- err = row.Scan(
- &res.ID,
- &res.Name,
- &res.SharedNodeID,
- &res.BaseURL,
- &res.Status,
- &res.Contact,
- &res.PairToken,
- &res.AuthToken,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan federationNode db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryFederationNodes returns squirrel.SelectBuilder with set table and all columns
-func (s Store) federationNodesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.federationNodeTable("fdn"), s.federationNodeColumns("fdn")...)
-}
-
-// federationNodeTable name of the db table
-func (Store) federationNodeTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "federation_nodes" + alias
-}
-
-// FederationNodeColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) federationNodeColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "name",
- alias + "shared_node_id",
- alias + "base_url",
- alias + "status",
- alias + "contact",
- alias + "pair_token",
- alias + "auth_token",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false false false true}
-
-// internalFederationNodeEncoder encodes fields from types.Node to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeFederationNode
-// func when rdbms.customEncoder=true
-func (s Store) internalFederationNodeEncoder(res *types.Node) store.Payload {
- return store.Payload{
- "id": res.ID,
- "name": res.Name,
- "shared_node_id": res.SharedNodeID,
- "base_url": res.BaseURL,
- "status": res.Status,
- "contact": res.Contact,
- "pair_token": res.PairToken,
- "auth_token": res.AuthToken,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// checkFederationNodeConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkFederationNodeConstraints(ctx context.Context, res *types.Node) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/federation_nodes.go b/store/rdbms/federation_nodes.go
deleted file mode 100644
index abbb257e9..000000000
--- a/store/rdbms/federation_nodes.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "strings"
-)
-
-func (s Store) convertFederationNodeFilter(f types.NodeFilter) (query squirrel.SelectBuilder, err error) {
- query = s.federationNodesSelectBuilder()
-
- query = filter.StateCondition(query, "fdn.deleted_at", f.Deleted)
-
- if f.Query != "" {
- q := "%" + strings.ToLower(f.Query) + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"LOWER(fdn.name)": q},
- squirrel.Like{"LOWER(fdn.base_url)": q},
- })
- }
-
- if f.Status != "" {
- query = query.Where(squirrel.Eq{"fdn.status": strings.ToLower(f.Status)})
- }
-
- return
-}
diff --git a/store/rdbms/federation_nodes_sync.gen.go b/store/rdbms/federation_nodes_sync.gen.go
deleted file mode 100644
index 2d6bf9650..000000000
--- a/store/rdbms/federation_nodes_sync.gen.go
+++ /dev/null
@@ -1,595 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/federation_nodes_sync.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchFederationNodesSyncs returns all matching rows
-//
-// This function calls convertFederationNodesSyncFilter with the given
-// types.NodeSyncFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchFederationNodesSyncs(ctx context.Context, f types.NodeSyncFilter) (types.NodeSyncSet, types.NodeSyncFilter, error) {
- var (
- err error
- set []*types.NodeSync
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertFederationNodesSyncFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("rel_node") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "rel_node",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableFederationNodesSyncColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationNodesSyncs(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfFederationNodesSyncs collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfFederationNodesSyncs(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.NodeSync) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.NodeSync, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.NodeSync
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.NodeSync, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryFederationNodesSyncs(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectFederationNodesSyncCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectFederationNodesSyncCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectFederationNodesSyncCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryFederationNodesSyncs queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryFederationNodesSyncs(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.NodeSync) (bool, error),
-) ([]*types.NodeSync, error) {
- var (
- tmp = make([]*types.NodeSync, 0, DefaultSliceCapacity)
- set = make([]*types.NodeSync, 0, DefaultSliceCapacity)
- res *types.NodeSync
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalFederationNodesSyncRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupFederationNodesSyncByNodeID searches for sync activity by node ID
-//
-// It returns sync activity
-func (s Store) LookupFederationNodesSyncByNodeID(ctx context.Context, node_id uint64) (*types.NodeSync, error) {
- return s.execLookupFederationNodesSync(ctx, squirrel.Eq{
- s.preprocessColumn("fdns.rel_node", ""): store.PreprocessValue(node_id, ""),
- })
-}
-
-// LookupFederationNodesSyncByNodeIDModuleIDSyncTypeSyncStatus searches for activity by node, type and status
-//
-// It returns sync activity
-func (s Store) LookupFederationNodesSyncByNodeIDModuleIDSyncTypeSyncStatus(ctx context.Context, node_id uint64, module_id uint64, sync_type string, sync_status string) (*types.NodeSync, error) {
- return s.execLookupFederationNodesSync(ctx, squirrel.Eq{
- s.preprocessColumn("fdns.rel_node", ""): store.PreprocessValue(node_id, ""),
- s.preprocessColumn("fdns.rel_module", ""): store.PreprocessValue(module_id, ""),
- s.preprocessColumn("fdns.sync_type", ""): store.PreprocessValue(sync_type, ""),
- s.preprocessColumn("fdns.sync_status", ""): store.PreprocessValue(sync_status, ""),
- })
-}
-
-// CreateFederationNodesSync creates one or more rows in federation_nodes_sync table
-func (s Store) CreateFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) (err error) {
- for _, res := range rr {
- err = s.checkFederationNodesSyncConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateFederationNodesSyncs(ctx, s.internalFederationNodesSyncEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateFederationNodesSync updates one or more existing rows in federation_nodes_sync
-func (s Store) UpdateFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) error {
- return s.partialFederationNodesSyncUpdate(ctx, nil, rr...)
-}
-
-// partialFederationNodesSyncUpdate updates one or more existing rows in federation_nodes_sync
-func (s Store) partialFederationNodesSyncUpdate(ctx context.Context, onlyColumns []string, rr ...*types.NodeSync) (err error) {
- for _, res := range rr {
- err = s.checkFederationNodesSyncConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateFederationNodesSyncs(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("fdns.rel_node", ""): store.PreprocessValue(res.NodeID, ""),
- },
- s.internalFederationNodesSyncEncoder(res).Skip("rel_node").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertFederationNodesSync updates one or more existing rows in federation_nodes_sync
-func (s Store) UpsertFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) (err error) {
- for _, res := range rr {
- err = s.checkFederationNodesSyncConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertFederationNodesSyncs(ctx, s.internalFederationNodesSyncEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationNodesSync Deletes one or more rows from federation_nodes_sync table
-func (s Store) DeleteFederationNodesSync(ctx context.Context, rr ...*types.NodeSync) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteFederationNodesSyncs(ctx, squirrel.Eq{
- s.preprocessColumn("fdns.rel_node", ""): store.PreprocessValue(res.NodeID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationNodesSyncByNodeID Deletes row from the federation_nodes_sync table
-func (s Store) DeleteFederationNodesSyncByNodeID(ctx context.Context, nodeID uint64) error {
- return s.execDeleteFederationNodesSyncs(ctx, squirrel.Eq{
- s.preprocessColumn("fdns.rel_node", ""): store.PreprocessValue(nodeID, ""),
- })
-}
-
-// TruncateFederationNodesSyncs Deletes all rows from the federation_nodes_sync table
-func (s Store) TruncateFederationNodesSyncs(ctx context.Context) error {
- return s.Truncate(ctx, s.federationNodesSyncTable())
-}
-
-// execLookupFederationNodesSync prepares FederationNodesSync query and executes it,
-// returning types.NodeSync (or error)
-func (s Store) execLookupFederationNodesSync(ctx context.Context, cnd squirrel.Sqlizer) (res *types.NodeSync, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.federationNodesSyncsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalFederationNodesSyncRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateFederationNodesSyncs updates all matched (by cnd) rows in federation_nodes_sync with given data
-func (s Store) execCreateFederationNodesSyncs(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.federationNodesSyncTable()).SetMap(payload))
-}
-
-// execUpdateFederationNodesSyncs updates all matched (by cnd) rows in federation_nodes_sync with given data
-func (s Store) execUpdateFederationNodesSyncs(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.federationNodesSyncTable("fdns")).Where(cnd).SetMap(set))
-}
-
-// execUpsertFederationNodesSyncs inserts new or updates matching (by-primary-key) rows in federation_nodes_sync with given data
-func (s Store) execUpsertFederationNodesSyncs(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.federationNodesSyncTable(),
- set,
- s.preprocessColumn("rel_node", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteFederationNodesSyncs Deletes all matched (by cnd) rows in federation_nodes_sync with given data
-func (s Store) execDeleteFederationNodesSyncs(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.federationNodesSyncTable("fdns")).Where(cnd))
-}
-
-func (s Store) internalFederationNodesSyncRowScanner(row rowScanner) (res *types.NodeSync, err error) {
- res = &types.NodeSync{}
-
- err = row.Scan(
- &res.NodeID,
- &res.ModuleID,
- &res.SyncType,
- &res.SyncStatus,
- &res.TimeOfAction,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan federationNodesSync db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryFederationNodesSyncs returns squirrel.SelectBuilder with set table and all columns
-func (s Store) federationNodesSyncsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.federationNodesSyncTable("fdns"), s.federationNodesSyncColumns("fdns")...)
-}
-
-// federationNodesSyncTable name of the db table
-func (Store) federationNodesSyncTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "federation_nodes_sync" + alias
-}
-
-// FederationNodesSyncColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) federationNodesSyncColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "rel_node",
- alias + "rel_module",
- alias + "sync_type",
- alias + "sync_status",
- alias + "time_action",
- }
-}
-
-// {true true false true true true}
-
-// sortableFederationNodesSyncColumns returns all FederationNodesSync columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableFederationNodesSyncColumns() map[string]string {
- return map[string]string{
- "rel_node": "rel_node",
- "nodeid": "rel_node",
- "time_action": "time_action",
- "timeofaction": "time_action",
- }
-}
-
-// internalFederationNodesSyncEncoder encodes fields from types.NodeSync to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeFederationNodesSync
-// func when rdbms.customEncoder=true
-func (s Store) internalFederationNodesSyncEncoder(res *types.NodeSync) store.Payload {
- return store.Payload{
- "rel_node": res.NodeID,
- "rel_module": res.ModuleID,
- "sync_type": res.SyncType,
- "sync_status": res.SyncStatus,
- "time_action": res.TimeOfAction,
- }
-}
-
-// collectFederationNodesSyncCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectFederationNodesSyncCursorValues(res *types.NodeSync, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkRel_node bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "rel_node":
- cursor.Set(c.Column, res.NodeID, c.Descending)
-
- pkRel_node = true
- case "time_action":
- cursor.Set(c.Column, res.TimeOfAction, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkRel_node && true) {
- collect(&filter.SortExpr{Column: "rel_node", Descending: false})
- }
-
- return cursor
-}
-
-// checkFederationNodesSyncConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkFederationNodesSyncConstraints(ctx context.Context, res *types.NodeSync) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/federation_nodes_sync.go b/store/rdbms/federation_nodes_sync.go
deleted file mode 100644
index 7f01cefcf..000000000
--- a/store/rdbms/federation_nodes_sync.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-func (s Store) convertFederationNodesSyncFilter(f types.NodeSyncFilter) (query squirrel.SelectBuilder, err error) {
- query = s.federationNodesSyncsSelectBuilder()
-
- if f.NodeID > 0 {
- query = query.Where("fdns.rel_node = ?", f.NodeID)
- }
-
- if f.ModuleID > 0 {
- query = query.Where("fdns.rel_module = ?", f.ModuleID)
- }
-
- if f.SyncStatus != "" {
- query = query.Where("fdns.sync_status = ?", f.SyncStatus)
- }
-
- if f.SyncType != "" {
- query = query.Where("fdns.sync_type = ?", f.SyncType)
- }
-
- return
-}
diff --git a/store/rdbms/federation_shared_modules.gen.go b/store/rdbms/federation_shared_modules.gen.go
deleted file mode 100644
index af4ee169a..000000000
--- a/store/rdbms/federation_shared_modules.gen.go
+++ /dev/null
@@ -1,599 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/federation_shared_modules.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchFederationSharedModules returns all matching rows
-//
-// This function calls convertFederationSharedModuleFilter with the given
-// types.SharedModuleFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchFederationSharedModules(ctx context.Context, f types.SharedModuleFilter) (types.SharedModuleSet, types.SharedModuleFilter, error) {
- var (
- err error
- set []*types.SharedModule
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertFederationSharedModuleFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableFederationSharedModuleColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfFederationSharedModules(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfFederationSharedModules collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfFederationSharedModules(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.SharedModule) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.SharedModule, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.SharedModule
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.SharedModule, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryFederationSharedModules(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectFederationSharedModuleCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectFederationSharedModuleCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectFederationSharedModuleCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryFederationSharedModules queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryFederationSharedModules(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.SharedModule) (bool, error),
-) ([]*types.SharedModule, error) {
- var (
- tmp = make([]*types.SharedModule, 0, DefaultSliceCapacity)
- set = make([]*types.SharedModule, 0, DefaultSliceCapacity)
- res *types.SharedModule
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalFederationSharedModuleRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupFederationSharedModuleByID searches for shared federation module by ID
-//
-// It returns shared federation module
-func (s Store) LookupFederationSharedModuleByID(ctx context.Context, id uint64) (*types.SharedModule, error) {
- return s.execLookupFederationSharedModule(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateFederationSharedModule creates one or more rows in federation_module_shared table
-func (s Store) CreateFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) (err error) {
- for _, res := range rr {
- err = s.checkFederationSharedModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateFederationSharedModules(ctx, s.internalFederationSharedModuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateFederationSharedModule updates one or more existing rows in federation_module_shared
-func (s Store) UpdateFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) error {
- return s.partialFederationSharedModuleUpdate(ctx, nil, rr...)
-}
-
-// partialFederationSharedModuleUpdate updates one or more existing rows in federation_module_shared
-func (s Store) partialFederationSharedModuleUpdate(ctx context.Context, onlyColumns []string, rr ...*types.SharedModule) (err error) {
- for _, res := range rr {
- err = s.checkFederationSharedModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateFederationSharedModules(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalFederationSharedModuleEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertFederationSharedModule updates one or more existing rows in federation_module_shared
-func (s Store) UpsertFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) (err error) {
- for _, res := range rr {
- err = s.checkFederationSharedModuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertFederationSharedModules(ctx, s.internalFederationSharedModuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationSharedModule Deletes one or more rows from federation_module_shared table
-func (s Store) DeleteFederationSharedModule(ctx context.Context, rr ...*types.SharedModule) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteFederationSharedModules(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFederationSharedModuleByID Deletes row from the federation_module_shared table
-func (s Store) DeleteFederationSharedModuleByID(ctx context.Context, ID uint64) error {
- return s.execDeleteFederationSharedModules(ctx, squirrel.Eq{
- s.preprocessColumn("cmd.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateFederationSharedModules Deletes all rows from the federation_module_shared table
-func (s Store) TruncateFederationSharedModules(ctx context.Context) error {
- return s.Truncate(ctx, s.federationSharedModuleTable())
-}
-
-// execLookupFederationSharedModule prepares FederationSharedModule query and executes it,
-// returning types.SharedModule (or error)
-func (s Store) execLookupFederationSharedModule(ctx context.Context, cnd squirrel.Sqlizer) (res *types.SharedModule, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.federationSharedModulesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalFederationSharedModuleRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateFederationSharedModules updates all matched (by cnd) rows in federation_module_shared with given data
-func (s Store) execCreateFederationSharedModules(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.federationSharedModuleTable()).SetMap(payload))
-}
-
-// execUpdateFederationSharedModules updates all matched (by cnd) rows in federation_module_shared with given data
-func (s Store) execUpdateFederationSharedModules(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.federationSharedModuleTable("cmd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertFederationSharedModules inserts new or updates matching (by-primary-key) rows in federation_module_shared with given data
-func (s Store) execUpsertFederationSharedModules(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.federationSharedModuleTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteFederationSharedModules Deletes all matched (by cnd) rows in federation_module_shared with given data
-func (s Store) execDeleteFederationSharedModules(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.federationSharedModuleTable("cmd")).Where(cnd))
-}
-
-func (s Store) internalFederationSharedModuleRowScanner(row rowScanner) (res *types.SharedModule, err error) {
- res = &types.SharedModule{}
-
- err = row.Scan(
- &res.ID,
- &res.NodeID,
- &res.Handle,
- &res.Name,
- &res.ExternalFederationModuleID,
- &res.Fields,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan federationSharedModule db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryFederationSharedModules returns squirrel.SelectBuilder with set table and all columns
-func (s Store) federationSharedModulesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.federationSharedModuleTable("cmd"), s.federationSharedModuleColumns("cmd")...)
-}
-
-// federationSharedModuleTable name of the db table
-func (Store) federationSharedModuleTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "federation_module_shared" + alias
-}
-
-// FederationSharedModuleColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) federationSharedModuleColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_node",
- alias + "handle",
- alias + "name",
- alias + "xref_module",
- alias + "fields",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableFederationSharedModuleColumns returns all FederationSharedModule columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableFederationSharedModuleColumns() map[string]string {
- return map[string]string{
- "id": "id",
- }
-}
-
-// internalFederationSharedModuleEncoder encodes fields from types.SharedModule to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeFederationSharedModule
-// func when rdbms.customEncoder=true
-func (s Store) internalFederationSharedModuleEncoder(res *types.SharedModule) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_node": res.NodeID,
- "handle": res.Handle,
- "name": res.Name,
- "xref_module": res.ExternalFederationModuleID,
- "fields": res.Fields,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectFederationSharedModuleCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectFederationSharedModuleCursorValues(res *types.SharedModule, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkFederationSharedModuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkFederationSharedModuleConstraints(ctx context.Context, res *types.SharedModule) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/federation_shared_modules.go b/store/rdbms/federation_shared_modules.go
deleted file mode 100644
index 049ae4c75..000000000
--- a/store/rdbms/federation_shared_modules.go
+++ /dev/null
@@ -1,40 +0,0 @@
-package rdbms
-
-import (
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/federation/types"
-)
-
-func (s Store) convertFederationSharedModuleFilter(f types.SharedModuleFilter) (query squirrel.SelectBuilder, err error) {
- query = s.federationSharedModulesSelectBuilder()
-
- // query = filter.StateCondition(query, "cmd.deleted_at", f.Deleted)
-
- if f.NodeID > 0 {
- query = query.Where("cmd.rel_node = ?", f.NodeID)
- }
-
- if f.Handle != "" {
- query = query.Where("cmd.handle = ?", f.Handle)
- }
-
- if f.Name != "" {
- query = query.Where("cmd.name = ?", f.Name)
- }
-
- if f.ExternalFederationModuleID > 0 {
- query = query.Where("cmd.xref_module = ?", f.ExternalFederationModuleID)
- }
-
- if f.Query != "" {
- q := "%" + strings.ToLower(f.Query) + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"LOWER(cmd.name)": q},
- squirrel.Like{"LOWER(cmd.handle)": q},
- })
- }
-
- return
-}
diff --git a/store/rdbms/flags.gen.go b/store/rdbms/flags.gen.go
deleted file mode 100644
index 0b7a4615c..000000000
--- a/store/rdbms/flags.gen.go
+++ /dev/null
@@ -1,442 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/flags.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/flag/types"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchFlags returns all matching rows
-//
-// This function calls convertFlagFilter with the given
-// types.FlagFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchFlags(ctx context.Context, f types.FlagFilter) (types.FlagSet, types.FlagFilter, error) {
- var (
- err error
- set []*types.Flag
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertFlagFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryFlags(ctx, q, nil)
- return err
- }()
-}
-
-// QueryFlags queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryFlags(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Flag) (bool, error),
-) ([]*types.Flag, error) {
- var (
- tmp = make([]*types.Flag, 0, DefaultSliceCapacity)
- set = make([]*types.Flag, 0, DefaultSliceCapacity)
- res *types.Flag
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalFlagRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupFlagByKindResourceIDName Flag lookup by kind, resource, name
-func (s Store) LookupFlagByKindResourceIDName(ctx context.Context, kind string, resource_id uint64, name string) (*types.Flag, error) {
- return s.execLookupFlag(ctx, squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(resource_id, ""),
- s.preprocessColumn("flg.name", "lower"): store.PreprocessValue(name, "lower"),
- })
-}
-
-// LookupFlagByKindResourceID Flag lookup by kind, resource
-func (s Store) LookupFlagByKindResourceID(ctx context.Context, kind string, resource_id uint64) (*types.Flag, error) {
- return s.execLookupFlag(ctx, squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(resource_id, ""),
- })
-}
-
-// LookupFlagByKindResourceIDOwnedBy Flag lookup by kind, resource, owner
-func (s Store) LookupFlagByKindResourceIDOwnedBy(ctx context.Context, kind string, resource_id uint64, owned_by uint64) (*types.Flag, error) {
- return s.execLookupFlag(ctx, squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(resource_id, ""),
- s.preprocessColumn("flg.owned_by", ""): store.PreprocessValue(owned_by, ""),
- })
-}
-
-// LookupFlagByKindResourceIDOwnedByName Flag lookup by kind, resource, owner, name
-func (s Store) LookupFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resource_id uint64, owned_by uint64, name string) (*types.Flag, error) {
- return s.execLookupFlag(ctx, squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(resource_id, ""),
- s.preprocessColumn("flg.owned_by", ""): store.PreprocessValue(owned_by, ""),
- s.preprocessColumn("flg.name", "lower"): store.PreprocessValue(name, "lower"),
- })
-}
-
-// CreateFlag creates one or more rows in flags table
-func (s Store) CreateFlag(ctx context.Context, rr ...*types.Flag) (err error) {
- for _, res := range rr {
- err = s.checkFlagConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateFlags(ctx, s.internalFlagEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateFlag updates one or more existing rows in flags
-func (s Store) UpdateFlag(ctx context.Context, rr ...*types.Flag) error {
- return s.partialFlagUpdate(ctx, nil, rr...)
-}
-
-// partialFlagUpdate updates one or more existing rows in flags
-func (s Store) partialFlagUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Flag) (err error) {
- for _, res := range rr {
- err = s.checkFlagConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateFlags(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(res.Kind, ""), s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(res.ResourceID, ""), s.preprocessColumn("flg.owned_by", ""): store.PreprocessValue(res.OwnedBy, ""), s.preprocessColumn("flg.name", "lower"): store.PreprocessValue(res.Name, "lower"),
- },
- s.internalFlagEncoder(res).Skip("kind", "rel_resource", "owned_by", "name").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertFlag updates one or more existing rows in flags
-func (s Store) UpsertFlag(ctx context.Context, rr ...*types.Flag) (err error) {
- for _, res := range rr {
- err = s.checkFlagConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertFlags(ctx, s.internalFlagEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFlag Deletes one or more rows from flags table
-func (s Store) DeleteFlag(ctx context.Context, rr ...*types.Flag) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteFlags(ctx, squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(res.Kind, ""), s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(res.ResourceID, ""), s.preprocessColumn("flg.owned_by", ""): store.PreprocessValue(res.OwnedBy, ""), s.preprocessColumn("flg.name", "lower"): store.PreprocessValue(res.Name, "lower"),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteFlagByKindResourceIDOwnedByName Deletes row from the flags table
-func (s Store) DeleteFlagByKindResourceIDOwnedByName(ctx context.Context, kind string, resourceID uint64, ownedBy uint64, name string) error {
- return s.execDeleteFlags(ctx, squirrel.Eq{
- s.preprocessColumn("flg.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("flg.rel_resource", ""): store.PreprocessValue(resourceID, ""),
- s.preprocessColumn("flg.owned_by", ""): store.PreprocessValue(ownedBy, ""),
- s.preprocessColumn("flg.name", "lower"): store.PreprocessValue(name, "lower"),
- })
-}
-
-// TruncateFlags Deletes all rows from the flags table
-func (s Store) TruncateFlags(ctx context.Context) error {
- return s.Truncate(ctx, s.flagTable())
-}
-
-// execLookupFlag prepares Flag query and executes it,
-// returning types.Flag (or error)
-func (s Store) execLookupFlag(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Flag, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.flagsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalFlagRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateFlags updates all matched (by cnd) rows in flags with given data
-func (s Store) execCreateFlags(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.flagTable()).SetMap(payload))
-}
-
-// execUpdateFlags updates all matched (by cnd) rows in flags with given data
-func (s Store) execUpdateFlags(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.flagTable("flg")).Where(cnd).SetMap(set))
-}
-
-// execUpsertFlags inserts new or updates matching (by-primary-key) rows in flags with given data
-func (s Store) execUpsertFlags(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.flagTable(),
- set,
- s.preprocessColumn("kind", ""),
- s.preprocessColumn("rel_resource", ""),
- s.preprocessColumn("owned_by", ""),
- s.preprocessColumn("name", "lower"),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteFlags Deletes all matched (by cnd) rows in flags with given data
-func (s Store) execDeleteFlags(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.flagTable("flg")).Where(cnd))
-}
-
-func (s Store) internalFlagRowScanner(row rowScanner) (res *types.Flag, err error) {
- res = &types.Flag{}
-
- err = row.Scan(
- &res.Kind,
- &res.ResourceID,
- &res.OwnedBy,
- &res.Name,
- &res.Active,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan flag db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryFlags returns squirrel.SelectBuilder with set table and all columns
-func (s Store) flagsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.flagTable("flg"), s.flagColumns("flg")...)
-}
-
-// flagTable name of the db table
-func (Store) flagTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "flags" + alias
-}
-
-// FlagColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) flagColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "kind",
- alias + "rel_resource",
- alias + "owned_by",
- alias + "name",
- alias + "active",
- }
-}
-
-// {true true false false false false}
-
-// internalFlagEncoder encodes fields from types.Flag to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeFlag
-// func when rdbms.customEncoder=true
-func (s Store) internalFlagEncoder(res *types.Flag) store.Payload {
- return store.Payload{
- "kind": res.Kind,
- "rel_resource": res.ResourceID,
- "owned_by": res.OwnedBy,
- "name": res.Name,
- "active": res.Active,
- }
-}
-
-// checkFlagConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkFlagConstraints(ctx context.Context, res *types.Flag) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Kind) > 0
-
- valid = valid && res.ResourceID > 0
-
- valid = valid && len(res.Name) > 0
-
- valid = valid && len(res.Kind) > 0
-
- valid = valid && res.ResourceID > 0
-
- valid = valid && len(res.Kind) > 0
-
- valid = valid && res.ResourceID > 0
-
- valid = valid && res.OwnedBy > 0
-
- valid = valid && len(res.Kind) > 0
-
- valid = valid && res.ResourceID > 0
-
- valid = valid && res.OwnedBy > 0
-
- valid = valid && len(res.Name) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by KindResourceIDName if Flag does not match filters
-
- ex, err := s.LookupFlagByKindResourceIDName(ctx, res.Kind, res.ResourceID, res.Name)
- if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by KindResourceID if Flag does not match filters
-
- ex, err := s.LookupFlagByKindResourceID(ctx, res.Kind, res.ResourceID)
- if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by KindResourceIDOwnedBy if Flag does not match filters
-
- ex, err := s.LookupFlagByKindResourceIDOwnedBy(ctx, res.Kind, res.ResourceID, res.OwnedBy)
- if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by KindResourceIDOwnedByName if Flag does not match filters
-
- ex, err := s.LookupFlagByKindResourceIDOwnedByName(ctx, res.Kind, res.ResourceID, res.OwnedBy, res.Name)
- if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.OwnedBy != res.OwnedBy && ex.Name != res.Name {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/flags.go b/store/rdbms/flags.go
deleted file mode 100644
index 2b92057f1..000000000
--- a/store/rdbms/flags.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/flag/types"
-)
-
-func (s Store) convertFlagFilter(f types.FlagFilter) (query squirrel.SelectBuilder, err error) {
- query = s.flagsSelectBuilder()
-
- query = query.Where(squirrel.Eq{"flg.kind": f.Kind})
-
- if len(f.ResourceID) > 0 {
- query = query.Where(squirrel.Eq{"flg.rel_resource": f.ResourceID})
- }
-
- if len(f.OwnedBy) > 0 {
- query = query.Where(squirrel.Eq{"flg.owned_by": f.OwnedBy})
- }
-
- if len(f.Name) > 0 {
- query = query.Where(squirrel.Eq{"flg.name": f.Name})
- }
-
- return
-}
diff --git a/store/rdbms/generic_selectors.go b/store/rdbms/generic_selectors.go
deleted file mode 100644
index 4c728bc89..000000000
--- a/store/rdbms/generic_selectors.go
+++ /dev/null
@@ -1,26 +0,0 @@
-package rdbms
-
-import (
- "context"
- "github.com/Masterminds/squirrel"
- "github.com/lann/builder"
-)
-
-// Count counts all rows that match conditions from given query builder
-func Count(ctx context.Context, db dbLayer, q squirrel.SelectBuilder) (count uint, err error) {
- // Delete order-bys for counting
- q = builder.Delete(q, "OrderByParts").(squirrel.SelectBuilder)
-
- // Replace columns with count(*)
- q = builder.Delete(q, "Columns").(squirrel.SelectBuilder).Column("COUNT(*)")
-
- if sqlSelect, argsSelect, err := q.ToSql(); err != nil {
- return 0, err
- } else {
- if err := db.GetContext(ctx, &count, sqlSelect, argsSelect...); err != nil {
- return 0, err
- }
- }
-
- return count, nil
-}
diff --git a/store/rdbms/labels.gen.go b/store/rdbms/labels.gen.go
deleted file mode 100644
index 6c57e06f0..000000000
--- a/store/rdbms/labels.gen.go
+++ /dev/null
@@ -1,353 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/labels.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/label/types"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchLabels returns all matching rows
-//
-// This function calls convertLabelFilter with the given
-// types.LabelFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchLabels(ctx context.Context, f types.LabelFilter) (types.LabelSet, types.LabelFilter, error) {
- var (
- err error
- set []*types.Label
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertLabelFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryLabels(ctx, q, nil)
- return err
- }()
-}
-
-// QueryLabels queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryLabels(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Label) (bool, error),
-) ([]*types.Label, error) {
- var (
- tmp = make([]*types.Label, 0, DefaultSliceCapacity)
- set = make([]*types.Label, 0, DefaultSliceCapacity)
- res *types.Label
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalLabelRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupLabelByKindResourceIDName Label lookup by kind, resource, name
-func (s Store) LookupLabelByKindResourceIDName(ctx context.Context, kind string, resource_id uint64, name string) (*types.Label, error) {
- return s.execLookupLabel(ctx, squirrel.Eq{
- s.preprocessColumn("lbl.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("lbl.rel_resource", ""): store.PreprocessValue(resource_id, ""),
- s.preprocessColumn("lbl.name", "lower"): store.PreprocessValue(name, "lower"),
- })
-}
-
-// CreateLabel creates one or more rows in labels table
-func (s Store) CreateLabel(ctx context.Context, rr ...*types.Label) (err error) {
- for _, res := range rr {
- err = s.checkLabelConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateLabels(ctx, s.internalLabelEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateLabel updates one or more existing rows in labels
-func (s Store) UpdateLabel(ctx context.Context, rr ...*types.Label) error {
- return s.partialLabelUpdate(ctx, nil, rr...)
-}
-
-// partialLabelUpdate updates one or more existing rows in labels
-func (s Store) partialLabelUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Label) (err error) {
- for _, res := range rr {
- err = s.checkLabelConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateLabels(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("lbl.kind", ""): store.PreprocessValue(res.Kind, ""), s.preprocessColumn("lbl.rel_resource", ""): store.PreprocessValue(res.ResourceID, ""), s.preprocessColumn("lbl.name", "lower"): store.PreprocessValue(res.Name, "lower"),
- },
- s.internalLabelEncoder(res).Skip("kind", "rel_resource", "name").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertLabel updates one or more existing rows in labels
-func (s Store) UpsertLabel(ctx context.Context, rr ...*types.Label) (err error) {
- for _, res := range rr {
- err = s.checkLabelConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertLabels(ctx, s.internalLabelEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteLabel Deletes one or more rows from labels table
-func (s Store) DeleteLabel(ctx context.Context, rr ...*types.Label) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteLabels(ctx, squirrel.Eq{
- s.preprocessColumn("lbl.kind", ""): store.PreprocessValue(res.Kind, ""), s.preprocessColumn("lbl.rel_resource", ""): store.PreprocessValue(res.ResourceID, ""), s.preprocessColumn("lbl.name", "lower"): store.PreprocessValue(res.Name, "lower"),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteLabelByKindResourceIDName Deletes row from the labels table
-func (s Store) DeleteLabelByKindResourceIDName(ctx context.Context, kind string, resourceID uint64, name string) error {
- return s.execDeleteLabels(ctx, squirrel.Eq{
- s.preprocessColumn("lbl.kind", ""): store.PreprocessValue(kind, ""),
- s.preprocessColumn("lbl.rel_resource", ""): store.PreprocessValue(resourceID, ""),
- s.preprocessColumn("lbl.name", "lower"): store.PreprocessValue(name, "lower"),
- })
-}
-
-// TruncateLabels Deletes all rows from the labels table
-func (s Store) TruncateLabels(ctx context.Context) error {
- return s.Truncate(ctx, s.labelTable())
-}
-
-// execLookupLabel prepares Label query and executes it,
-// returning types.Label (or error)
-func (s Store) execLookupLabel(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Label, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.labelsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalLabelRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateLabels updates all matched (by cnd) rows in labels with given data
-func (s Store) execCreateLabels(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.labelTable()).SetMap(payload))
-}
-
-// execUpdateLabels updates all matched (by cnd) rows in labels with given data
-func (s Store) execUpdateLabels(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.labelTable("lbl")).Where(cnd).SetMap(set))
-}
-
-// execUpsertLabels inserts new or updates matching (by-primary-key) rows in labels with given data
-func (s Store) execUpsertLabels(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.labelTable(),
- set,
- s.preprocessColumn("kind", ""),
- s.preprocessColumn("rel_resource", ""),
- s.preprocessColumn("name", "lower"),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteLabels Deletes all matched (by cnd) rows in labels with given data
-func (s Store) execDeleteLabels(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.labelTable("lbl")).Where(cnd))
-}
-
-func (s Store) internalLabelRowScanner(row rowScanner) (res *types.Label, err error) {
- res = &types.Label{}
-
- err = row.Scan(
- &res.Kind,
- &res.ResourceID,
- &res.Name,
- &res.Value,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan label db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryLabels returns squirrel.SelectBuilder with set table and all columns
-func (s Store) labelsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.labelTable("lbl"), s.labelColumns("lbl")...)
-}
-
-// labelTable name of the db table
-func (Store) labelTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "labels" + alias
-}
-
-// LabelColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) labelColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "kind",
- alias + "rel_resource",
- alias + "name",
- alias + "value",
- }
-}
-
-// {true true false false false false}
-
-// internalLabelEncoder encodes fields from types.Label to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeLabel
-// func when rdbms.customEncoder=true
-func (s Store) internalLabelEncoder(res *types.Label) store.Payload {
- return store.Payload{
- "kind": res.Kind,
- "rel_resource": res.ResourceID,
- "name": res.Name,
- "value": res.Value,
- }
-}
-
-// checkLabelConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkLabelConstraints(ctx context.Context, res *types.Label) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Kind) > 0
-
- valid = valid && res.ResourceID > 0
-
- valid = valid && len(res.Name) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by KindResourceIDName if Label does not match filters
-
- ex, err := s.LookupLabelByKindResourceIDName(ctx, res.Kind, res.ResourceID, res.Name)
- if err == nil && ex != nil && ex.Kind != res.Kind && ex.ResourceID != res.ResourceID && ex.Name != res.Name {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/labels.go b/store/rdbms/labels.go
deleted file mode 100644
index c26a5eba1..000000000
--- a/store/rdbms/labels.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package rdbms
-
-import (
- "context"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/label/types"
-)
-
-func (s Store) convertLabelFilter(f types.LabelFilter) (query squirrel.SelectBuilder, err error) {
- query = s.labelsSelectBuilder()
-
- query = query.Where(squirrel.Eq{"lbl.kind": f.Kind})
-
- if len(f.ResourceID) > 0 {
- query = query.Where(squirrel.Eq{"lbl.rel_resource": f.ResourceID})
- }
-
- if len(f.Filter) > 0 {
- kvOr := squirrel.Or{}
- for k, v := range f.Filter {
- kvOr = append(kvOr, squirrel.Eq{"name": k, "value": v})
- }
- query = query.Where(kvOr)
-
- }
-
- return
-}
-
-// DeleteExtraLabels removes all unlisted labels
-func (s Store) DeleteExtraLabels(ctx context.Context, kind string, resourceID uint64, names ...string) (err error) {
- return s.execDeleteLabels(ctx, squirrel.And{
- squirrel.Eq{
- "kind": kind,
- "rel_resource": resourceID,
- },
- squirrel.NotEq{
- "name": names,
- },
- })
-}
diff --git a/store/rdbms/metrics.go b/store/rdbms/metrics.go
deleted file mode 100644
index 9c742ef16..000000000
--- a/store/rdbms/metrics.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package rdbms
-
-import (
- "context"
- "database/sql"
- "fmt"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "time"
-)
-
-// multiDailyMetrics simplifies fetching of multiple daily metrics
-//
-// This function is copied from old repository and adapted to work under store,
-// might be good to refactor it to fit into this store pattern a bit more
-func (s Store) multiDailyMetrics(ctx context.Context, q squirrel.SelectBuilder, fields []string, mm ...*[]uint) (err error) {
- for m := 0; m < len(mm); m++ {
- *mm[m], err = s.dailyMetrics(ctx, q, fields[m])
- if err != nil {
- return
- }
- }
-
- return
-}
-
-// dailyMetrics aids repositories on simple stat building queries
-//
-// Returns a slice of numbers (timestamp + value pairs)
-//
-// This function is copied from old repository and adapted to work under store,
-// might be good to refactor it to fit into this store pattern a bit more
-func (s Store) dailyMetrics(ctx context.Context, q squirrel.SelectBuilder, field string) ([]uint, error) {
- sqlfn, err := s.SqlFunctionHandler(ql.Function{Name: "DATE", Arguments: ql.ASTSet{ql.Ident{Value: field}}})
- if err != nil {
- return nil, err
- }
-
- q = q.
- Column(sqlfn).
- Column("COUNT(*) AS value").
- Where(fmt.Sprintf("%s IS NOT NULL", field))
-
- // since orderBy & groupBy do not accept Sqlizer, we'll convert it up front
- // args are omitted because there should be none
- // error is checked when adding sqlfn to Column fn
- sqlfnStr, _, _ := sqlfn.ToSql()
-
- q = q.
- OrderBy(sqlfnStr).
- GroupBy(sqlfnStr)
-
- const (
- cap = 100
- )
-
- var (
- rval = make([]uint, 0, cap)
-
- d time.Time
- ts string
- c uint
-
- rows *sql.Rows
- )
-
- return rval, func() (err error) {
- rows, err = s.Query(ctx, q)
- if err != nil {
- return err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Scan(&ts, &c); err != nil {
- return err
- }
-
- d = time.Time{}
- if ts != "" {
- if d, err = time.Parse(time.RFC3339, ts); err != nil {
- return err
- }
- }
-
- rval = append(rval, uint(d.Unix()), c)
- }
-
- return
- }()
-}
diff --git a/store/rdbms/queue.gen.go b/store/rdbms/queue.gen.go
deleted file mode 100644
index ec72a2883..000000000
--- a/store/rdbms/queue.gen.go
+++ /dev/null
@@ -1,585 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/queue.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchQueues returns all matching rows
-//
-// This function calls convertQueueFilter with the given
-// types.QueueFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchQueues(ctx context.Context, f types.QueueFilter) (types.QueueSet, types.QueueFilter, error) {
- var (
- err error
- set []*types.Queue
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertQueueFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfQueues(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- nil,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfQueues collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfQueues(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Queue) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Queue, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Queue
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Queue, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryQueues(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectQueueCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectQueueCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectQueueCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryQueues queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryQueues(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Queue) (bool, error),
-) ([]*types.Queue, error) {
- var (
- tmp = make([]*types.Queue, 0, DefaultSliceCapacity)
- set = make([]*types.Queue, 0, DefaultSliceCapacity)
- res *types.Queue
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalQueueRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupQueueByID searches for queue by ID
-func (s Store) LookupQueueByID(ctx context.Context, id uint64) (*types.Queue, error) {
- return s.execLookupQueue(ctx, squirrel.Eq{
- s.preprocessColumn("mqs.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupQueueByQueue searches for queue by queue name
-func (s Store) LookupQueueByQueue(ctx context.Context, queue string) (*types.Queue, error) {
- return s.execLookupQueue(ctx, squirrel.Eq{
- s.preprocessColumn("mqs.queue", ""): store.PreprocessValue(queue, ""),
- })
-}
-
-// CreateQueue creates one or more rows in queue_settings table
-func (s Store) CreateQueue(ctx context.Context, rr ...*types.Queue) (err error) {
- for _, res := range rr {
- err = s.checkQueueConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateQueues(ctx, s.internalQueueEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateQueue updates one or more existing rows in queue_settings
-func (s Store) UpdateQueue(ctx context.Context, rr ...*types.Queue) error {
- return s.partialQueueUpdate(ctx, nil, rr...)
-}
-
-// partialQueueUpdate updates one or more existing rows in queue_settings
-func (s Store) partialQueueUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Queue) (err error) {
- for _, res := range rr {
- err = s.checkQueueConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateQueues(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("mqs.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalQueueEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertQueue updates one or more existing rows in queue_settings
-func (s Store) UpsertQueue(ctx context.Context, rr ...*types.Queue) (err error) {
- for _, res := range rr {
- err = s.checkQueueConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertQueues(ctx, s.internalQueueEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteQueue Deletes one or more rows from queue_settings table
-func (s Store) DeleteQueue(ctx context.Context, rr ...*types.Queue) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteQueues(ctx, squirrel.Eq{
- s.preprocessColumn("mqs.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteQueueByID Deletes row from the queue_settings table
-func (s Store) DeleteQueueByID(ctx context.Context, ID uint64) error {
- return s.execDeleteQueues(ctx, squirrel.Eq{
- s.preprocessColumn("mqs.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateQueues Deletes all rows from the queue_settings table
-func (s Store) TruncateQueues(ctx context.Context) error {
- return s.Truncate(ctx, s.queueTable())
-}
-
-// execLookupQueue prepares Queue query and executes it,
-// returning types.Queue (or error)
-func (s Store) execLookupQueue(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Queue, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.queuesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalQueueRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateQueues updates all matched (by cnd) rows in queue_settings with given data
-func (s Store) execCreateQueues(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.queueTable()).SetMap(payload))
-}
-
-// execUpdateQueues updates all matched (by cnd) rows in queue_settings with given data
-func (s Store) execUpdateQueues(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.queueTable("mqs")).Where(cnd).SetMap(set))
-}
-
-// execUpsertQueues inserts new or updates matching (by-primary-key) rows in queue_settings with given data
-func (s Store) execUpsertQueues(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.queueTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteQueues Deletes all matched (by cnd) rows in queue_settings with given data
-func (s Store) execDeleteQueues(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.queueTable("mqs")).Where(cnd))
-}
-
-func (s Store) internalQueueRowScanner(row rowScanner) (res *types.Queue, err error) {
- res = &types.Queue{}
-
- err = row.Scan(
- &res.ID,
- &res.Consumer,
- &res.Queue,
- &res.Meta,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan queue db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryQueues returns squirrel.SelectBuilder with set table and all columns
-func (s Store) queuesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.queueTable("mqs"), s.queueColumns("mqs")...)
-}
-
-// queueTable name of the db table
-func (Store) queueTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "queue_settings" + alias
-}
-
-// QueueColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) queueColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "consumer",
- alias + "queue",
- alias + "meta",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true false false}
-
-// internalQueueEncoder encodes fields from types.Queue to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeQueue
-// func when rdbms.customEncoder=true
-func (s Store) internalQueueEncoder(res *types.Queue) store.Payload {
- return store.Payload{
- "id": res.ID,
- "consumer": res.Consumer,
- "queue": res.Queue,
- "meta": res.Meta,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectQueueCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectQueueCursorValues(res *types.Queue, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "queue":
- cursor.Set(c.Column, res.Queue, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkQueueConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkQueueConstraints(ctx context.Context, res *types.Queue) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/queue.go b/store/rdbms/queue.go
deleted file mode 100644
index 73a0ec39c..000000000
--- a/store/rdbms/queue.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package rdbms
-
-import (
- "strings"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertQueueFilter(f types.QueueFilter) (query squirrel.SelectBuilder, err error) {
- query = s.queuesSelectBuilder()
- query = filter.StateCondition(query, "mqs.deleted_at", f.Deleted)
-
- if f.Queue != "" {
- query = query.Where(squirrel.Like{"LOWER(mqs.queue)": strings.ToLower(f.Queue)})
- }
-
- return
-}
diff --git a/store/rdbms/queue_message.gen.go b/store/rdbms/queue_message.gen.go
deleted file mode 100644
index 2ef8f3720..000000000
--- a/store/rdbms/queue_message.gen.go
+++ /dev/null
@@ -1,526 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/queue_message.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchQueueMessages returns all matching rows
-//
-// This function calls convertQueueMessageFilter with the given
-// types.QueueMessageFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchQueueMessages(ctx context.Context, f types.QueueMessageFilter) (types.QueueMessageSet, types.QueueMessageFilter, error) {
- var (
- err error
- set []*types.QueueMessage
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertQueueMessageFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableQueueMessageColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfQueueMessages(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- nil,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfQueueMessages collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfQueueMessages(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.QueueMessage) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.QueueMessage, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.QueueMessage
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.QueueMessage, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryQueueMessages(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectQueueMessageCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectQueueMessageCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectQueueMessageCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryQueueMessages queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryQueueMessages(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.QueueMessage) (bool, error),
-) ([]*types.QueueMessage, error) {
- var (
- tmp = make([]*types.QueueMessage, 0, DefaultSliceCapacity)
- set = make([]*types.QueueMessage, 0, DefaultSliceCapacity)
- res *types.QueueMessage
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalQueueMessageRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// CreateQueueMessage creates one or more rows in queue_messages table
-func (s Store) CreateQueueMessage(ctx context.Context, rr ...*types.QueueMessage) (err error) {
- for _, res := range rr {
- err = s.checkQueueMessageConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateQueueMessages(ctx, s.internalQueueMessageEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateQueueMessage updates one or more existing rows in queue_messages
-func (s Store) UpdateQueueMessage(ctx context.Context, rr ...*types.QueueMessage) error {
- return s.partialQueueMessageUpdate(ctx, nil, rr...)
-}
-
-// partialQueueMessageUpdate updates one or more existing rows in queue_messages
-func (s Store) partialQueueMessageUpdate(ctx context.Context, onlyColumns []string, rr ...*types.QueueMessage) (err error) {
- for _, res := range rr {
- err = s.checkQueueMessageConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateQueueMessages(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("mqm.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalQueueMessageEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// DeleteQueueMessage Deletes one or more rows from queue_messages table
-func (s Store) DeleteQueueMessage(ctx context.Context, rr ...*types.QueueMessage) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteQueueMessages(ctx, squirrel.Eq{
- s.preprocessColumn("mqm.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteQueueMessageByID Deletes row from the queue_messages table
-func (s Store) DeleteQueueMessageByID(ctx context.Context, ID uint64) error {
- return s.execDeleteQueueMessages(ctx, squirrel.Eq{
- s.preprocessColumn("mqm.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateQueueMessages Deletes all rows from the queue_messages table
-func (s Store) TruncateQueueMessages(ctx context.Context) error {
- return s.Truncate(ctx, s.queueMessageTable())
-}
-
-// execLookupQueueMessage prepares QueueMessage query and executes it,
-// returning types.QueueMessage (or error)
-func (s Store) execLookupQueueMessage(ctx context.Context, cnd squirrel.Sqlizer) (res *types.QueueMessage, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.queueMessagesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalQueueMessageRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateQueueMessages updates all matched (by cnd) rows in queue_messages with given data
-func (s Store) execCreateQueueMessages(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.queueMessageTable()).SetMap(payload))
-}
-
-// execUpdateQueueMessages updates all matched (by cnd) rows in queue_messages with given data
-func (s Store) execUpdateQueueMessages(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.queueMessageTable("mqm")).Where(cnd).SetMap(set))
-}
-
-// execDeleteQueueMessages Deletes all matched (by cnd) rows in queue_messages with given data
-func (s Store) execDeleteQueueMessages(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.queueMessageTable("mqm")).Where(cnd))
-}
-
-func (s Store) internalQueueMessageRowScanner(row rowScanner) (res *types.QueueMessage, err error) {
- res = &types.QueueMessage{}
-
- err = row.Scan(
- &res.ID,
- &res.Queue,
- &res.Payload,
- &res.Processed,
- &res.Created,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan queueMessage db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryQueueMessages returns squirrel.SelectBuilder with set table and all columns
-func (s Store) queueMessagesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.queueMessageTable("mqm"), s.queueMessageColumns("mqm")...)
-}
-
-// queueMessageTable name of the db table
-func (Store) queueMessageTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "queue_messages" + alias
-}
-
-// QueueMessageColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) queueMessageColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "queue",
- alias + "payload",
- alias + "processed",
- alias + "created",
- }
-}
-
-// {true true false true true false}
-
-// sortableQueueMessageColumns returns all QueueMessage columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableQueueMessageColumns() map[string]string {
- return map[string]string{
- "id": "id",
- }
-}
-
-// internalQueueMessageEncoder encodes fields from types.QueueMessage to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeQueueMessage
-// func when rdbms.customEncoder=true
-func (s Store) internalQueueMessageEncoder(res *types.QueueMessage) store.Payload {
- return store.Payload{
- "id": res.ID,
- "queue": res.Queue,
- "payload": res.Payload,
- "processed": res.Processed,
- "created": res.Created,
- }
-}
-
-// collectQueueMessageCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectQueueMessageCursorValues(res *types.QueueMessage, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkQueueMessageConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkQueueMessageConstraints(ctx context.Context, res *types.QueueMessage) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/queue_message.go b/store/rdbms/queue_message.go
deleted file mode 100644
index 76917301e..000000000
--- a/store/rdbms/queue_message.go
+++ /dev/null
@@ -1,18 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertQueueMessageFilter(f types.QueueMessageFilter) (query squirrel.SelectBuilder, err error) {
- query = s.queueMessagesSelectBuilder()
-
- if f.Queue != "" {
- query = query.Where("mqm.queue = ?", f.Queue)
- }
-
- query = filter.StateCondition(query, "mqm.processed", f.Processed)
- return
-}
diff --git a/store/rdbms/rbac_rules.gen.go b/store/rdbms/rbac_rules.gen.go
deleted file mode 100644
index 9c4a7d5c8..000000000
--- a/store/rdbms/rbac_rules.gen.go
+++ /dev/null
@@ -1,322 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/rbac_rules.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/rbac"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-var _ = errors.Is
-
-// SearchRbacRules returns all matching rows
-//
-// This function calls convertRbacRuleFilter with the given
-// rbac.RuleFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchRbacRules(ctx context.Context, f rbac.RuleFilter) (rbac.RuleSet, rbac.RuleFilter, error) {
- var (
- err error
- set []*rbac.Rule
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q = s.rbacRulesSelectBuilder()
-
- set, err = s.QueryRbacRules(ctx, q, nil)
- return err
- }()
-}
-
-// QueryRbacRules queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryRbacRules(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*rbac.Rule) (bool, error),
-) ([]*rbac.Rule, error) {
- var (
- tmp = make([]*rbac.Rule, 0, DefaultSliceCapacity)
- set = make([]*rbac.Rule, 0, DefaultSliceCapacity)
- res *rbac.Rule
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalRbacRuleRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// CreateRbacRule creates one or more rows in rbac_rules table
-func (s Store) CreateRbacRule(ctx context.Context, rr ...*rbac.Rule) (err error) {
- for _, res := range rr {
- err = s.checkRbacRuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateRbacRules(ctx, s.internalRbacRuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateRbacRule updates one or more existing rows in rbac_rules
-func (s Store) UpdateRbacRule(ctx context.Context, rr ...*rbac.Rule) error {
- return s.partialRbacRuleUpdate(ctx, nil, rr...)
-}
-
-// partialRbacRuleUpdate updates one or more existing rows in rbac_rules
-func (s Store) partialRbacRuleUpdate(ctx context.Context, onlyColumns []string, rr ...*rbac.Rule) (err error) {
- for _, res := range rr {
- err = s.checkRbacRuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateRbacRules(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("rls.rel_role", ""): store.PreprocessValue(res.RoleID, ""), s.preprocessColumn("rls.resource", ""): store.PreprocessValue(res.Resource, ""), s.preprocessColumn("rls.operation", ""): store.PreprocessValue(res.Operation, ""),
- },
- s.internalRbacRuleEncoder(res).Skip("rel_role", "resource", "operation").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertRbacRule updates one or more existing rows in rbac_rules
-func (s Store) UpsertRbacRule(ctx context.Context, rr ...*rbac.Rule) (err error) {
- for _, res := range rr {
- err = s.checkRbacRuleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertRbacRules(ctx, s.internalRbacRuleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteRbacRule Deletes one or more rows from rbac_rules table
-func (s Store) DeleteRbacRule(ctx context.Context, rr ...*rbac.Rule) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteRbacRules(ctx, squirrel.Eq{
- s.preprocessColumn("rls.rel_role", ""): store.PreprocessValue(res.RoleID, ""), s.preprocessColumn("rls.resource", ""): store.PreprocessValue(res.Resource, ""), s.preprocessColumn("rls.operation", ""): store.PreprocessValue(res.Operation, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteRbacRuleByRoleIDResourceOperation Deletes row from the rbac_rules table
-func (s Store) DeleteRbacRuleByRoleIDResourceOperation(ctx context.Context, roleID uint64, resource string, operation string) error {
- return s.execDeleteRbacRules(ctx, squirrel.Eq{
- s.preprocessColumn("rls.rel_role", ""): store.PreprocessValue(roleID, ""),
- s.preprocessColumn("rls.resource", ""): store.PreprocessValue(resource, ""),
- s.preprocessColumn("rls.operation", ""): store.PreprocessValue(operation, ""),
- })
-}
-
-// TruncateRbacRules Deletes all rows from the rbac_rules table
-func (s Store) TruncateRbacRules(ctx context.Context) error {
- return s.Truncate(ctx, s.rbacRuleTable())
-}
-
-// execLookupRbacRule prepares RbacRule query and executes it,
-// returning rbac.Rule (or error)
-func (s Store) execLookupRbacRule(ctx context.Context, cnd squirrel.Sqlizer) (res *rbac.Rule, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.rbacRulesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalRbacRuleRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateRbacRules updates all matched (by cnd) rows in rbac_rules with given data
-func (s Store) execCreateRbacRules(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.rbacRuleTable()).SetMap(payload))
-}
-
-// execUpdateRbacRules updates all matched (by cnd) rows in rbac_rules with given data
-func (s Store) execUpdateRbacRules(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.rbacRuleTable("rls")).Where(cnd).SetMap(set))
-}
-
-// execUpsertRbacRules inserts new or updates matching (by-primary-key) rows in rbac_rules with given data
-func (s Store) execUpsertRbacRules(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.rbacRuleTable(),
- set,
- s.preprocessColumn("rel_role", ""),
- s.preprocessColumn("resource", ""),
- s.preprocessColumn("operation", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteRbacRules Deletes all matched (by cnd) rows in rbac_rules with given data
-func (s Store) execDeleteRbacRules(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.rbacRuleTable("rls")).Where(cnd))
-}
-
-func (s Store) internalRbacRuleRowScanner(row rowScanner) (res *rbac.Rule, err error) {
- res = &rbac.Rule{}
-
- err = row.Scan(
- &res.RoleID,
- &res.Resource,
- &res.Operation,
- &res.Access,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan rbacRule db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryRbacRules returns squirrel.SelectBuilder with set table and all columns
-func (s Store) rbacRulesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.rbacRuleTable("rls"), s.rbacRuleColumns("rls")...)
-}
-
-// rbacRuleTable name of the db table
-func (Store) rbacRuleTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "rbac_rules" + alias
-}
-
-// RbacRuleColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) rbacRuleColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "rel_role",
- alias + "resource",
- alias + "operation",
- alias + "access",
- }
-}
-
-// {true true false false false false}
-
-// internalRbacRuleEncoder encodes fields from rbac.Rule to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeRbacRule
-// func when rdbms.customEncoder=true
-func (s Store) internalRbacRuleEncoder(res *rbac.Rule) store.Payload {
- return store.Payload{
- "rel_role": res.RoleID,
- "resource": res.Resource,
- "operation": res.Operation,
- "access": res.Access,
- }
-}
-
-// checkRbacRuleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkRbacRuleConstraints(ctx context.Context, res *rbac.Rule) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/rbac_rules.go b/store/rdbms/rbac_rules.go
deleted file mode 100644
index fde6b54ba..000000000
--- a/store/rdbms/rbac_rules.go
+++ /dev/null
@@ -1,12 +0,0 @@
-package rdbms
-
-import (
- "context"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-func (s Store) TransferRbacRules(ctx context.Context, src, dst uint64) (err error) {
- return s.execUpdateRbacRules(ctx, squirrel.Eq{"rel_role": src}, store.Payload{"rel_role": dst})
-}
diff --git a/store/rdbms/rdbms.go b/store/rdbms/rdbms.go
deleted file mode 100644
index b9a945f80..000000000
--- a/store/rdbms/rdbms.go
+++ /dev/null
@@ -1,466 +0,0 @@
-package rdbms
-
-import (
- "context"
- "database/sql"
- "fmt"
- "strings"
- "time"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/pkg/healthcheck"
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "github.com/cortezaproject/corteza-server/pkg/qlng"
- "github.com/cortezaproject/corteza-server/pkg/sentry"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/store/rdbms/ddl"
- "github.com/jmoiron/sqlx"
- "go.uber.org/zap"
-)
-
-type (
- schemaUpgradeGenerator interface {
- TableExists(string) bool
- CreateTable(t *ddl.Table) string
- CreateIndexes(ii ...*ddl.Index) []string
- }
-
- // Store - Corteza RDBMS persistence layer
- Store struct {
- config *Config
-
- // Schema upgrade generator converts internal upgrade config
- // to implementation specific SQL
- sug schemaUpgradeGenerator
-
- db dbLayer
-
- // Logger for connection
- logger *zap.Logger
- }
-
- dbLayer interface {
- sqlx.ExecerContext
- SelectContext(context.Context, interface{}, string, ...interface{}) error
- GetContext(context.Context, interface{}, string, ...interface{}) error
- QueryRowContext(context.Context, string, ...interface{}) *sql.Row
- QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
- }
-
- ModuleFieldTypeDetector interface {
- IsBoolean() bool
- IsNumeric() bool
- IsDateTime() bool
- IsTimeOnly() bool
- IsDateOnly() bool
- IsRef() bool
- }
-
- dbTransactionMaker interface {
- BeginTxx(ctx context.Context, opts *sql.TxOptions) (*sqlx.Tx, error)
- }
-)
-
-const (
- // TxRetryHardLimit is the absolute maximum retries we'll allow
- TxRetryHardLimit = 100
-
- DefaultSliceCapacity = 1000
-
- MinEnsureFetchLimit = 10
- MaxRefetches = 100
-
- MaxLimit = 1000
-)
-
-func Connect(ctx context.Context, cfg *Config) (s *Store, err error) {
- return s, func() error {
- if err = cfg.ParseExtra(); err != nil {
- return err
- }
-
- cfg.SetDefaults()
- s = &Store{
- config: cfg,
- }
-
- return s.Connect(ctx)
- }()
-}
-
-// WithTx spins up new store instance with transaction
-func (s *Store) withTx(tx dbLayer) *Store {
- return &Store{
- config: s.config,
- sug: s.sug,
- db: tx,
- }
-}
-
-func (s *Store) Connect(ctx context.Context) error {
- s.log(ctx).Debug("opening connection", zap.String("driver", s.config.DriverName), zap.String("dsn", s.config.MaskedDSN()))
-
- db, err := sql.Open(s.config.DriverName, s.config.DataSourceName)
- if err != nil {
- return err
- }
-
- healthcheck.Defaults().Add(dbHealthcheck(db), "Store/RDBMS/"+s.config.DriverName)
-
- dbx := sqlx.NewDb(db, s.config.DriverName)
- s.log(ctx).Debug(
- "setting connection parameters",
- zap.Int("MaxOpenConns", s.config.MaxOpenConns),
- zap.Duration("MaxLifetime", s.config.ConnMaxLifetime),
- zap.Int("MaxIdleConns", s.config.MaxIdleConns),
- )
-
- dbx.SetMaxOpenConns(s.config.MaxOpenConns)
- dbx.SetConnMaxLifetime(s.config.ConnMaxLifetime)
- dbx.SetMaxIdleConns(s.config.MaxIdleConns)
-
- if err = s.tryToConnect(ctx, dbx); err != nil {
- return err
- }
-
- s.db = dbx
- return err
-}
-
-func (s Store) tryToConnect(ctx context.Context, db *sqlx.DB) error {
- var (
- connErrCh = make(chan error, 1)
- patience = time.Now().Add(s.config.ConnTryPatience)
- )
-
- go func() {
- defer sentry.Recover()
-
- var (
- err error
- try = 0
-
- log = s.log(ctx).
- // Make a small adjustment when
- // collecting callers from the callstack for this
- WithOptions(zap.AddCallerSkip(-2))
- )
-
- for {
- try++
-
- if s.config.ConnTryMax <= try {
- connErrCh <- fmt.Errorf("could not connect in %d tries", try)
- return
- }
-
- if err = db.PingContext(ctx); err != nil {
-
- if time.Now().After(patience) {
- // don't make too much fuss
- // if we're in patience mode
- log.Warn(
- "could not connect to the database",
- zap.Error(err),
- zap.Int("try", try),
- zap.Float64("delay", s.config.ConnTryBackoffDelay.Seconds()),
- )
- }
-
- select {
- case <-ctx.Done():
- // Forced break
- break
- case <-time.After(s.config.ConnTryBackoffDelay):
- // Wait before next try
- continue
- }
- }
-
- log.Debug("connected to the database")
- break
- }
-
- connErrCh <- err
- }()
-
- to := s.config.ConnTryTimeout * time.Duration(s.config.ConnTryMax*2)
- select {
- case err := <-connErrCh:
- return err
- case <-time.After(to):
- // Wait before next try
- return fmt.Errorf("timedout after %.2fs", to.Seconds())
- case <-ctx.Done():
- return fmt.Errorf("connection cancelled")
- }
-}
-
-func dbHealthcheck(db *sql.DB) func(ctx context.Context) error {
- return db.PingContext
-}
-
-func (s Store) Query(ctx context.Context, q squirrel.Sqlizer) (*sql.Rows, error) {
- var (
- query, args, err = q.ToSql()
- )
-
- if err != nil {
- return nil, fmt.Errorf("could not build query: %w", err)
- }
-
- rr, err := s.db.QueryContext(ctx, query, args...)
- if err = store.HandleError(err, s.config.ErrorHandler); err != nil {
- return nil, err
- }
-
- return rr, nil
-}
-
-func (s Store) ASTTransformer(n *qlng.ASTNode) *astTransformer {
- return newASTFormatter(n, s.config.ASTFormatter)
-}
-
-// QueryRow returns row instead of filling in the passed struct
-func (s Store) QueryRow(ctx context.Context, q squirrel.SelectBuilder) (*sql.Row, error) {
- var (
- query, args, err = q.ToSql()
- )
-
- if err != nil {
- return nil, fmt.Errorf("could not build query: %w", err)
- }
-
- r, err := s.db.QueryRowContext(ctx, query, args...), nil
- if err = store.HandleError(err, s.config.ErrorHandler); err != nil {
- return nil, err
- }
-
- return r, nil
-}
-
-func (s Store) Exec(ctx context.Context, sqlizer squirrel.Sqlizer) error {
- var (
- query, args, err = sqlizer.ToSql()
- )
-
- if err != nil {
- return err
- }
-
- _, err = s.db.ExecContext(ctx, query, args...)
- return store.HandleError(err, s.config.ErrorHandler)
-}
-
-func (s Store) Tx(ctx context.Context, fn func(context.Context, store.Storer) error) error {
- return tx(ctx, s.db, s.config, nil, func(ctx context.Context, tx dbLayer) error {
- return fn(ctx, s.withTx(tx))
- })
-}
-
-func (s Store) Truncate(ctx context.Context, table string) error {
- _, err := s.db.ExecContext(ctx, "DELETE FROM "+table)
- return store.HandleError(err, s.config.ErrorHandler)
-}
-
-// SelectBuilder is a shorthand for squirrel.selectBuilder
-//
-// Sets passed table & columns and configured placeholder format
-func (s Store) SelectBuilder(table string, cc ...string) squirrel.SelectBuilder {
- return squirrel.Select(cc...).From(table).PlaceholderFormat(s.config.PlaceholderFormat)
-}
-
-// InsertBuilder is a shorthand for squirrel.insertBuilder
-//
-// Sets passed table and configured placeholder format
-func (s Store) InsertBuilder(table string) squirrel.InsertBuilder {
- return squirrel.Insert(table).PlaceholderFormat(s.config.PlaceholderFormat)
-}
-
-// UpdateBuilder is a shorthand for squirrel.updateBuilder
-//
-// Sets passed table and configured placeholder format
-func (s Store) UpdateBuilder(table string) squirrel.UpdateBuilder {
- return squirrel.Update(table).PlaceholderFormat(s.config.PlaceholderFormat)
-}
-
-// DeleteBuilder is a shorthand for squirrel.deleteBuilder
-//
-// Sets passed table and configured placeholder format
-func (s Store) DeleteBuilder(table string) squirrel.DeleteBuilder {
- return squirrel.Delete(table).PlaceholderFormat(s.config.PlaceholderFormat)
-}
-
-func (s Store) DB() dbLayer {
- return s.db
-}
-
-func (s Store) Config() *Config {
- return s.config
-}
-
-// column preprocessor logic to modify db value before using it in condition filter
-//
-// It checks registered ColumnPreprocessors from config
-// and then the standard set
-//
-// No preprocessor ("") is intentionally checked after checking registered list of preprocessors
-func (s Store) preprocessColumn(col string, p string) string {
- if fn, has := s.config.ColumnPreprocessors[p]; has {
- return fn(col)
- }
-
- switch p {
- case "":
- return col
- case "lower":
- return fmt.Sprintf("LOWER(%s)", col)
- default:
- panic(fmt.Sprintf("unknown preprocessor %q used for column %q", p, col))
- }
-}
-
-// SqlFunctionHandler calls configured sql function handler if set
-// otherwise returns passed arguments directly
-func (s Store) SqlFunctionHandler(f ql.Function) (ql.ASTNode, error) {
- if s.config.SqlFunctionHandler == nil {
- return f, nil
- }
-
- return s.config.SqlFunctionHandler(f)
-}
-
-// FieldToColumnTypeCaster calls configured field type caster if set
-// otherwise returns passed arguments directly
-func (s Store) FieldToColumnTypeCaster(f ModuleFieldTypeDetector, i ql.Ident) (ql.Ident, error) {
- var err error
- i.Value, _, _, err = s.config.CastModuleFieldToColumnType(f, i.Value)
- return i, err
-}
-
-// tx begins a new db transaction and handles it's retries when possible
-//
-// It utilizes configured transaction error handlers and max-retry limits
-// to determine if and how many times transaction should be retried
-//
-func tx(ctx context.Context, dbCandidate interface{}, cfg *Config, txOpt *sql.TxOptions, task func(context.Context, dbLayer) error) error {
- if cfg.TxDisabled {
- return task(ctx, dbCandidate.(dbLayer))
- }
-
- var (
- lastTaskErr error
- err error
- db *sqlx.DB
- tx *sqlx.Tx
- try = 1
- )
-
- switch dbCandidate.(type) {
- case dbTransactionMaker:
- // we can make a transaction, yay
- db = dbCandidate.(*sqlx.DB)
- case dbLayer:
- // Already in a transaction, run the given task and finish
- return task(ctx, dbCandidate.(dbLayer))
- default:
- return fmt.Errorf("could not use the db connection for transaction")
- }
-
- for {
- try++
-
- // Start transaction
- tx, err = db.BeginTxx(ctx, txOpt)
- if err != nil {
- return err
- }
-
- if lastTaskErr = task(ctx, tx); lastTaskErr == nil {
- // Task completed successfully
- return tx.Commit()
- }
-
- // No matter the cause of the error, rollback the transaction
- if rollbackErr := tx.Rollback(); rollbackErr != nil {
- return fmt.Errorf("failed to rollback transaction (tries: %d) on error %v: %w", try, lastTaskErr, rollbackErr)
- }
-
- if errors.IsAny(lastTaskErr) {
- // not a store-internal/transaction error and can be returned right away,
- // no need to re-run the transaction
- return lastTaskErr
- }
-
- // Call the the configured transaction retry error handler
- // if this particular error should be retried or not
- //
- // We cannot generalize here because different store implementation have
- // different errors and we need to act accordingly
- if !cfg.TxRetryErrHandler(try, lastTaskErr) {
- return fmt.Errorf("failed to complete transaction: %w", lastTaskErr)
- }
-
- // tx error handlers can take current number of tries into account and
- // break the retry-loop earlier, but that might not be always the case
- //
- // We'll check the configured and hard-limit maximums
- if try >= cfg.TxMaxRetries || try >= TxRetryHardLimit {
- return fmt.Errorf("failed to perform transaction (tries: %d), last error: %w", try, lastTaskErr)
- }
-
- // Sleep (with a bit of kickback) before doing next retry
- time.Sleep(50 * time.Duration(try*50))
- }
-}
-
-func BuildCursor(q squirrel.SelectBuilder, cursor *filter.PagingCursor) squirrel.SelectBuilder {
- if cursor != nil && len(cursor.Keys()) > 0 {
- return q.Where(builders.CursorCondition(cursor, nil))
- }
-
- return q
-}
-
-func setOrderBy(q squirrel.SelectBuilder, sort filter.SortExprSet, sortable map[string]string, sortHandler func(exp string, desc bool) string) (squirrel.SelectBuilder, error) {
- var (
- col string
- has bool
- sqlSort = make([]string, len(sort))
- )
-
- for i, c := range sort {
- if sortable != nil {
- // When sortable map is given, test each sort column
- if col, has = sortable[strings.ToLower(c.Column)]; !has {
- return q, fmt.Errorf("column %q is not sortable", c.Column)
- }
-
- sqlSort[i] = col
- } else {
- sqlSort[i] = c.Column
- }
-
- // Let DB specific sort handler determine the appropriate syntax
- sqlSort[i] = sortHandler(sqlSort[i], sort[i].Descending)
- }
-
- return q.OrderBy(sqlSort...), nil
-}
-
-func SqlSortHandler(exp string, desc bool) string {
- if desc {
- return fmt.Sprintf("%s DESC NULLS LAST", exp)
- } else {
- return fmt.Sprintf("%s ASC NULLS FIRST", exp)
- }
-}
-
-// TxNoRetry - Transaction retry handler
-//
-// Only returns false so transactions will never retry
-func TxNoRetry(int, error) bool { return false }
-func ErrHandlerFallthrough(err error) error { return err }
diff --git a/store/rdbms/reminder.go b/store/rdbms/reminder.go
deleted file mode 100644
index a62343881..000000000
--- a/store/rdbms/reminder.go
+++ /dev/null
@@ -1,44 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/system/types"
- "time"
-)
-
-func (s Store) convertReminderFilter(f types.ReminderFilter) (query squirrel.SelectBuilder, err error) {
- query = s.remindersSelectBuilder()
-
- if len(f.ReminderID) > 0 {
- query = query.Where(squirrel.Eq{"rmd.ID": f.ReminderID})
- }
-
- if f.ExcludeDismissed {
- query = query.Where("rmd.dismissed_at IS NULL")
- }
-
- if !f.IncludeDeleted {
- query = query.Where("rmd.deleted_at IS NULL")
- }
-
- if f.ScheduledOnly {
- query = query.Where("rmd.remind_at IS NOT NULL")
- }
-
- if f.AssignedTo != 0 {
- query = query.Where("rmd.assigned_to = ?", f.AssignedTo)
- }
-
- if f.Resource != "" {
- query = query.Where("rmd.resource LIKE ?", f.Resource+"%")
- }
-
- if f.ScheduledFrom != nil {
- query = query.Where("rmd.remind_at >= ?", f.ScheduledFrom.Format(time.RFC3339))
- }
- if f.ScheduledUntil != nil {
- query = query.Where("rmd.remind_at <= ?", f.ScheduledUntil.Format(time.RFC3339))
- }
-
- return
-}
diff --git a/store/rdbms/reminders.gen.go b/store/rdbms/reminders.gen.go
deleted file mode 100644
index 822735d5f..000000000
--- a/store/rdbms/reminders.gen.go
+++ /dev/null
@@ -1,620 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/reminders.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchReminders returns all matching rows
-//
-// This function calls convertReminderFilter with the given
-// types.ReminderFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchReminders(ctx context.Context, f types.ReminderFilter) (types.ReminderSet, types.ReminderFilter, error) {
- var (
- err error
- set []*types.Reminder
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertReminderFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableReminderColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfReminders(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfReminders collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfReminders(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Reminder) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Reminder, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Reminder
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Reminder, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryReminders(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectReminderCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectReminderCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectReminderCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryReminders queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryReminders(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Reminder) (bool, error),
-) ([]*types.Reminder, error) {
- var (
- tmp = make([]*types.Reminder, 0, DefaultSliceCapacity)
- set = make([]*types.Reminder, 0, DefaultSliceCapacity)
- res *types.Reminder
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalReminderRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupReminderByID searches for reminder by its ID
-//
-// It returns reminder even if deleted or suspended
-func (s Store) LookupReminderByID(ctx context.Context, id uint64) (*types.Reminder, error) {
- return s.execLookupReminder(ctx, squirrel.Eq{
- s.preprocessColumn("rmd.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateReminder creates one or more rows in reminders table
-func (s Store) CreateReminder(ctx context.Context, rr ...*types.Reminder) (err error) {
- for _, res := range rr {
- err = s.checkReminderConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateReminders(ctx, s.internalReminderEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateReminder updates one or more existing rows in reminders
-func (s Store) UpdateReminder(ctx context.Context, rr ...*types.Reminder) error {
- return s.partialReminderUpdate(ctx, nil, rr...)
-}
-
-// partialReminderUpdate updates one or more existing rows in reminders
-func (s Store) partialReminderUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Reminder) (err error) {
- for _, res := range rr {
- err = s.checkReminderConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateReminders(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("rmd.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalReminderEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertReminder updates one or more existing rows in reminders
-func (s Store) UpsertReminder(ctx context.Context, rr ...*types.Reminder) (err error) {
- for _, res := range rr {
- err = s.checkReminderConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertReminders(ctx, s.internalReminderEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteReminder Deletes one or more rows from reminders table
-func (s Store) DeleteReminder(ctx context.Context, rr ...*types.Reminder) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteReminders(ctx, squirrel.Eq{
- s.preprocessColumn("rmd.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteReminderByID Deletes row from the reminders table
-func (s Store) DeleteReminderByID(ctx context.Context, ID uint64) error {
- return s.execDeleteReminders(ctx, squirrel.Eq{
- s.preprocessColumn("rmd.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateReminders Deletes all rows from the reminders table
-func (s Store) TruncateReminders(ctx context.Context) error {
- return s.Truncate(ctx, s.reminderTable())
-}
-
-// execLookupReminder prepares Reminder query and executes it,
-// returning types.Reminder (or error)
-func (s Store) execLookupReminder(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Reminder, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.remindersSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalReminderRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateReminders updates all matched (by cnd) rows in reminders with given data
-func (s Store) execCreateReminders(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.reminderTable()).SetMap(payload))
-}
-
-// execUpdateReminders updates all matched (by cnd) rows in reminders with given data
-func (s Store) execUpdateReminders(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.reminderTable("rmd")).Where(cnd).SetMap(set))
-}
-
-// execUpsertReminders inserts new or updates matching (by-primary-key) rows in reminders with given data
-func (s Store) execUpsertReminders(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.reminderTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteReminders Deletes all matched (by cnd) rows in reminders with given data
-func (s Store) execDeleteReminders(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.reminderTable("rmd")).Where(cnd))
-}
-
-func (s Store) internalReminderRowScanner(row rowScanner) (res *types.Reminder, err error) {
- res = &types.Reminder{}
-
- err = row.Scan(
- &res.ID,
- &res.Resource,
- &res.Payload,
- &res.SnoozeCount,
- &res.AssignedTo,
- &res.AssignedBy,
- &res.AssignedAt,
- &res.DismissedBy,
- &res.DismissedAt,
- &res.RemindAt,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan reminder db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryReminders returns squirrel.SelectBuilder with set table and all columns
-func (s Store) remindersSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.reminderTable("rmd"), s.reminderColumns("rmd")...)
-}
-
-// reminderTable name of the db table
-func (Store) reminderTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "reminders" + alias
-}
-
-// ReminderColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) reminderColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "resource",
- alias + "payload",
- alias + "snooze_count",
- alias + "assigned_to",
- alias + "assigned_by",
- alias + "assigned_at",
- alias + "dismissed_by",
- alias + "dismissed_at",
- alias + "remind_at",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableReminderColumns returns all Reminder columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableReminderColumns() map[string]string {
- return map[string]string{
- "id": "id", "remind_at": "remind_at",
- "remindat": "remind_at",
- "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalReminderEncoder encodes fields from types.Reminder to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeReminder
-// func when rdbms.customEncoder=true
-func (s Store) internalReminderEncoder(res *types.Reminder) store.Payload {
- return store.Payload{
- "id": res.ID,
- "resource": res.Resource,
- "payload": res.Payload,
- "snooze_count": res.SnoozeCount,
- "assigned_to": res.AssignedTo,
- "assigned_by": res.AssignedBy,
- "assigned_at": res.AssignedAt,
- "dismissed_by": res.DismissedBy,
- "dismissed_at": res.DismissedAt,
- "remind_at": res.RemindAt,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectReminderCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectReminderCursorValues(res *types.Reminder, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "remind_at":
- cursor.Set(c.Column, res.RemindAt, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkReminderConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkReminderConstraints(ctx context.Context, res *types.Reminder) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/reports.gen.go b/store/rdbms/reports.gen.go
deleted file mode 100644
index 337de31fc..000000000
--- a/store/rdbms/reports.gen.go
+++ /dev/null
@@ -1,647 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/reports.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchReports returns all matching rows
-//
-// This function calls convertReportFilter with the given
-// types.ReportFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchReports(ctx context.Context, f types.ReportFilter) (types.ReportSet, types.ReportFilter, error) {
- var (
- err error
- set []*types.Report
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertReportFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableReportColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfReports(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfReports collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfReports(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Report) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Report, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Report
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Report, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryReports(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectReportCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectReportCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectReportCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryReports queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryReports(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Report) (bool, error),
-) ([]*types.Report, error) {
- var (
- tmp = make([]*types.Report, 0, DefaultSliceCapacity)
- set = make([]*types.Report, 0, DefaultSliceCapacity)
- res *types.Report
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalReportRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupReportByID searches for report by ID
-//
-// It returns report even if deleted
-func (s Store) LookupReportByID(ctx context.Context, id uint64) (*types.Report, error) {
- return s.execLookupReport(ctx, squirrel.Eq{
- s.preprocessColumn("rp.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupReportByHandle searches for report by Handle
-//
-// It returns report even if deleted
-func (s Store) LookupReportByHandle(ctx context.Context, handle string) (*types.Report, error) {
- return s.execLookupReport(ctx, squirrel.Eq{
- s.preprocessColumn("rp.handle", ""): store.PreprocessValue(handle, ""),
-
- "rp.deleted_at": nil,
- })
-}
-
-// CreateReport creates one or more rows in reports table
-func (s Store) CreateReport(ctx context.Context, rr ...*types.Report) (err error) {
- for _, res := range rr {
- err = s.checkReportConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateReports(ctx, s.internalReportEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateReport updates one or more existing rows in reports
-func (s Store) UpdateReport(ctx context.Context, rr ...*types.Report) error {
- return s.partialReportUpdate(ctx, nil, rr...)
-}
-
-// partialReportUpdate updates one or more existing rows in reports
-func (s Store) partialReportUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Report) (err error) {
- for _, res := range rr {
- err = s.checkReportConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateReports(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("rp.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalReportEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertReport updates one or more existing rows in reports
-func (s Store) UpsertReport(ctx context.Context, rr ...*types.Report) (err error) {
- for _, res := range rr {
- err = s.checkReportConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertReports(ctx, s.internalReportEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteReport Deletes one or more rows from reports table
-func (s Store) DeleteReport(ctx context.Context, rr ...*types.Report) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteReports(ctx, squirrel.Eq{
- s.preprocessColumn("rp.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteReportByID Deletes row from the reports table
-func (s Store) DeleteReportByID(ctx context.Context, ID uint64) error {
- return s.execDeleteReports(ctx, squirrel.Eq{
- s.preprocessColumn("rp.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateReports Deletes all rows from the reports table
-func (s Store) TruncateReports(ctx context.Context) error {
- return s.Truncate(ctx, s.reportTable())
-}
-
-// execLookupReport prepares Report query and executes it,
-// returning types.Report (or error)
-func (s Store) execLookupReport(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Report, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.reportsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalReportRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateReports updates all matched (by cnd) rows in reports with given data
-func (s Store) execCreateReports(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.reportTable()).SetMap(payload))
-}
-
-// execUpdateReports updates all matched (by cnd) rows in reports with given data
-func (s Store) execUpdateReports(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.reportTable("rp")).Where(cnd).SetMap(set))
-}
-
-// execUpsertReports inserts new or updates matching (by-primary-key) rows in reports with given data
-func (s Store) execUpsertReports(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.reportTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteReports Deletes all matched (by cnd) rows in reports with given data
-func (s Store) execDeleteReports(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.reportTable("rp")).Where(cnd))
-}
-
-func (s Store) internalReportRowScanner(row rowScanner) (res *types.Report, err error) {
- res = &types.Report{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Meta,
- &res.Scenarios,
- &res.Sources,
- &res.Blocks,
- &res.OwnedBy,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan report db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryReports returns squirrel.SelectBuilder with set table and all columns
-func (s Store) reportsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.reportTable("rp"), s.reportColumns("rp")...)
-}
-
-// reportTable name of the db table
-func (Store) reportTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "reports" + alias
-}
-
-// ReportColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) reportColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "meta",
- alias + "scenarios",
- alias + "sources",
- alias + "blocks",
- alias + "owned_by",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableReportColumns returns all Report columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableReportColumns() map[string]string {
- return map[string]string{
- "id": "id", "handle": "handle", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalReportEncoder encodes fields from types.Report to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeReport
-// func when rdbms.customEncoder=true
-func (s Store) internalReportEncoder(res *types.Report) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "meta": res.Meta,
- "scenarios": res.Scenarios,
- "sources": res.Sources,
- "blocks": res.Blocks,
- "owned_by": res.OwnedBy,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectReportCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectReportCursorValues(res *types.Report, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkReportConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkReportConstraints(ctx context.Context, res *types.Report) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Handle) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Handle if Report does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupReportByHandle(ctx, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/reports.go b/store/rdbms/reports.go
deleted file mode 100644
index ef47b2933..000000000
--- a/store/rdbms/reports.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertReportFilter(f types.ReportFilter) (query squirrel.SelectBuilder, err error) {
- query = s.reportsSelectBuilder()
-
- query = filter.StateCondition(query, "rp.deleted_at", f.Deleted)
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"rp.id": f.LabeledIDs})
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"rp.handle": f.Handle})
- }
-
- return
-}
diff --git a/store/rdbms/resource_activity_log.gen.go b/store/rdbms/resource_activity_log.gen.go
deleted file mode 100644
index c8f2b137b..000000000
--- a/store/rdbms/resource_activity_log.gen.go
+++ /dev/null
@@ -1,570 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/resource_activity_log.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/discovery/types"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
-)
-
-var _ = errors.Is
-
-// SearchResourceActivityLogs returns all matching rows
-//
-// This function calls convertResourceActivityLogFilter with the given
-// types.ResourceActivityFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchResourceActivityLogs(ctx context.Context, f types.ResourceActivityFilter) (types.ResourceActivitySet, types.ResourceActivityFilter, error) {
- var (
- err error
- set []*types.ResourceActivity
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertResourceActivityLogFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableResourceActivityLogColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfResourceActivityLogs(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- nil,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfResourceActivityLogs collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfResourceActivityLogs(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.ResourceActivity) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.ResourceActivity, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.ResourceActivity
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.ResourceActivity, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryResourceActivityLogs(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectResourceActivityLogCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectResourceActivityLogCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectResourceActivityLogCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryResourceActivityLogs queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryResourceActivityLogs(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ResourceActivity) (bool, error),
-) ([]*types.ResourceActivity, error) {
- var (
- tmp = make([]*types.ResourceActivity, 0, DefaultSliceCapacity)
- set = make([]*types.ResourceActivity, 0, DefaultSliceCapacity)
- res *types.ResourceActivity
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalResourceActivityLogRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupResourceActivityLogByID searches for corteza resource activity by ID
-// It returns corteza resource activity even if deleted
-func (s Store) LookupResourceActivityLogByID(ctx context.Context, id uint64) (*types.ResourceActivity, error) {
- return s.execLookupResourceActivityLog(ctx, squirrel.Eq{
- s.preprocessColumn("ral.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateResourceActivityLog creates one or more rows in resource_activity_log table
-func (s Store) CreateResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) (err error) {
- for _, res := range rr {
- err = s.checkResourceActivityLogConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateResourceActivityLogs(ctx, s.internalResourceActivityLogEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateResourceActivityLog updates one or more existing rows in resource_activity_log
-func (s Store) UpdateResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) error {
- return s.partialResourceActivityLogUpdate(ctx, nil, rr...)
-}
-
-// partialResourceActivityLogUpdate updates one or more existing rows in resource_activity_log
-func (s Store) partialResourceActivityLogUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ResourceActivity) (err error) {
- for _, res := range rr {
- err = s.checkResourceActivityLogConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateResourceActivityLogs(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("ral.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalResourceActivityLogEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertResourceActivityLog updates one or more existing rows in resource_activity_log
-func (s Store) UpsertResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) (err error) {
- for _, res := range rr {
- err = s.checkResourceActivityLogConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertResourceActivityLogs(ctx, s.internalResourceActivityLogEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteResourceActivityLog Deletes one or more rows from resource_activity_log table
-func (s Store) DeleteResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteResourceActivityLogs(ctx, squirrel.Eq{
- s.preprocessColumn("ral.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteResourceActivityLogByID Deletes row from the resource_activity_log table
-func (s Store) DeleteResourceActivityLogByID(ctx context.Context, ID uint64) error {
- return s.execDeleteResourceActivityLogs(ctx, squirrel.Eq{
- s.preprocessColumn("ral.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateResourceActivityLogs Deletes all rows from the resource_activity_log table
-func (s Store) TruncateResourceActivityLogs(ctx context.Context) error {
- return s.Truncate(ctx, s.resourceActivityLogTable())
-}
-
-// execLookupResourceActivityLog prepares ResourceActivityLog query and executes it,
-// returning types.ResourceActivity (or error)
-func (s Store) execLookupResourceActivityLog(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ResourceActivity, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.resourceActivityLogsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalResourceActivityLogRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateResourceActivityLogs updates all matched (by cnd) rows in resource_activity_log with given data
-func (s Store) execCreateResourceActivityLogs(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.resourceActivityLogTable()).SetMap(payload))
-}
-
-// execUpdateResourceActivityLogs updates all matched (by cnd) rows in resource_activity_log with given data
-func (s Store) execUpdateResourceActivityLogs(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.resourceActivityLogTable("ral")).Where(cnd).SetMap(set))
-}
-
-// execUpsertResourceActivityLogs inserts new or updates matching (by-primary-key) rows in resource_activity_log with given data
-func (s Store) execUpsertResourceActivityLogs(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.resourceActivityLogTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteResourceActivityLogs Deletes all matched (by cnd) rows in resource_activity_log with given data
-func (s Store) execDeleteResourceActivityLogs(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.resourceActivityLogTable("ral")).Where(cnd))
-}
-
-func (s Store) internalResourceActivityLogRowScanner(row rowScanner) (res *types.ResourceActivity, err error) {
- res = &types.ResourceActivity{}
-
- err = row.Scan(
- &res.ID,
- &res.ResourceID,
- &res.ResourceType,
- &res.ResourceAction,
- &res.Timestamp,
- &res.Meta,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan resourceActivityLog db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryResourceActivityLogs returns squirrel.SelectBuilder with set table and all columns
-func (s Store) resourceActivityLogsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.resourceActivityLogTable("ral"), s.resourceActivityLogColumns("ral")...)
-}
-
-// resourceActivityLogTable name of the db table
-func (Store) resourceActivityLogTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "resource_activity_log" + alias
-}
-
-// ResourceActivityLogColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) resourceActivityLogColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "rel_resource",
- alias + "resource_type",
- alias + "resource_action",
- alias + "ts",
- alias + "meta",
- }
-}
-
-// {true true false true true false}
-
-// sortableResourceActivityLogColumns returns all ResourceActivityLog columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableResourceActivityLogColumns() map[string]string {
- return map[string]string{
- "id": "id",
- }
-}
-
-// internalResourceActivityLogEncoder encodes fields from types.ResourceActivity to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeResourceActivityLog
-// func when rdbms.customEncoder=true
-func (s Store) internalResourceActivityLogEncoder(res *types.ResourceActivity) store.Payload {
- return store.Payload{
- "id": res.ID,
- "rel_resource": res.ResourceID,
- "resource_type": res.ResourceType,
- "resource_action": res.ResourceAction,
- "ts": res.Timestamp,
- "meta": res.Meta,
- }
-}
-
-// collectResourceActivityLogCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectResourceActivityLogCursorValues(res *types.ResourceActivity, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkResourceActivityLogConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkResourceActivityLogConstraints(ctx context.Context, res *types.ResourceActivity) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/resource_activity_log.go b/store/rdbms/resource_activity_log.go
deleted file mode 100644
index 0ab6b496f..000000000
--- a/store/rdbms/resource_activity_log.go
+++ /dev/null
@@ -1,61 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/discovery/types"
- "github.com/cortezaproject/corteza-server/store"
-)
-
-func (s Store) convertResourceActivityLogFilter(f types.ResourceActivityFilter) (query squirrel.SelectBuilder, err error) {
- query = s.resourceActivityLogsSelectBuilder()
-
- // Always sort by ID descending
- query = query.OrderBy("id DESC")
-
- if f.FromTimestamp != nil {
- query = query.Where(squirrel.GtOrEq{"ts": f.FromTimestamp})
- }
-
- if f.ToTimestamp != nil {
- query = query.Where(squirrel.LtOrEq{"ts": f.ToTimestamp})
- }
-
- if f.Limit == 0 || f.Limit > MaxLimit {
- f.Limit = MaxLimit
- }
-
- query = query.Limit(uint64(f.Limit))
-
- return
-}
-
-func (s Store) scanResourceActivityLogRow(row rowScanner, res *types.ResourceActivity) (err error) {
- err = row.Scan(
- &res.ID,
- &res.ResourceID,
- &res.ResourceType,
- &res.ResourceAction,
- &res.Timestamp,
- &res.Meta,
- )
-
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (s Store) encodeResourceActivityLog(res *types.ResourceActivity) store.Payload {
- // ActivityLogEnc encodes fields from discovery.Action to store.Payload (map)
- out := store.Payload{
- "id": res.ID,
- "rel_resource": res.ResourceID,
- "resource_type": res.ResourceType,
- "resource_action": res.ResourceAction,
- "ts": res.Timestamp,
- "meta": res.Meta,
- }
-
- return out
-}
diff --git a/store/rdbms/resource_translation.gen.go b/store/rdbms/resource_translation.gen.go
deleted file mode 100644
index 300fe8c53..000000000
--- a/store/rdbms/resource_translation.gen.go
+++ /dev/null
@@ -1,621 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/resource_translation.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchResourceTranslations returns all matching rows
-//
-// This function calls convertResourceTranslationFilter with the given
-// types.ResourceTranslationFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchResourceTranslations(ctx context.Context, f types.ResourceTranslationFilter) (types.ResourceTranslationSet, types.ResourceTranslationFilter, error) {
- var (
- err error
- set []*types.ResourceTranslation
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertResourceTranslationFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableResourceTranslationColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfResourceTranslations(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- nil,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfResourceTranslations collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfResourceTranslations(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.ResourceTranslation) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.ResourceTranslation, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.ResourceTranslation
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.ResourceTranslation, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryResourceTranslations(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectResourceTranslationCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectResourceTranslationCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectResourceTranslationCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryResourceTranslations queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryResourceTranslations(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.ResourceTranslation) (bool, error),
-) ([]*types.ResourceTranslation, error) {
- var (
- tmp = make([]*types.ResourceTranslation, 0, DefaultSliceCapacity)
- set = make([]*types.ResourceTranslation, 0, DefaultSliceCapacity)
- res *types.ResourceTranslation
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalResourceTranslationRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupResourceTranslationByID searches for resource translation by ID
-// It also returns deleted resource translations.
-func (s Store) LookupResourceTranslationByID(ctx context.Context, id uint64) (*types.ResourceTranslation, error) {
- return s.execLookupResourceTranslation(ctx, squirrel.Eq{
- s.preprocessColumn("rt.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// CreateResourceTranslation creates one or more rows in resource_translations table
-func (s Store) CreateResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) (err error) {
- for _, res := range rr {
- err = s.checkResourceTranslationConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateResourceTranslations(ctx, s.internalResourceTranslationEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateResourceTranslation updates one or more existing rows in resource_translations
-func (s Store) UpdateResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) error {
- return s.partialResourceTranslationUpdate(ctx, nil, rr...)
-}
-
-// partialResourceTranslationUpdate updates one or more existing rows in resource_translations
-func (s Store) partialResourceTranslationUpdate(ctx context.Context, onlyColumns []string, rr ...*types.ResourceTranslation) (err error) {
- for _, res := range rr {
- err = s.checkResourceTranslationConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateResourceTranslations(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("rt.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalResourceTranslationEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertResourceTranslation updates one or more existing rows in resource_translations
-func (s Store) UpsertResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) (err error) {
- for _, res := range rr {
- err = s.checkResourceTranslationConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertResourceTranslations(ctx, s.internalResourceTranslationEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteResourceTranslation Deletes one or more rows from resource_translations table
-func (s Store) DeleteResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteResourceTranslations(ctx, squirrel.Eq{
- s.preprocessColumn("rt.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteResourceTranslationByID Deletes row from the resource_translations table
-func (s Store) DeleteResourceTranslationByID(ctx context.Context, ID uint64) error {
- return s.execDeleteResourceTranslations(ctx, squirrel.Eq{
- s.preprocessColumn("rt.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateResourceTranslations Deletes all rows from the resource_translations table
-func (s Store) TruncateResourceTranslations(ctx context.Context) error {
- return s.Truncate(ctx, s.resourceTranslationTable())
-}
-
-// execLookupResourceTranslation prepares ResourceTranslation query and executes it,
-// returning types.ResourceTranslation (or error)
-func (s Store) execLookupResourceTranslation(ctx context.Context, cnd squirrel.Sqlizer) (res *types.ResourceTranslation, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.resourceTranslationsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalResourceTranslationRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateResourceTranslations updates all matched (by cnd) rows in resource_translations with given data
-func (s Store) execCreateResourceTranslations(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.resourceTranslationTable()).SetMap(payload))
-}
-
-// execUpdateResourceTranslations updates all matched (by cnd) rows in resource_translations with given data
-func (s Store) execUpdateResourceTranslations(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.resourceTranslationTable("rt")).Where(cnd).SetMap(set))
-}
-
-// execUpsertResourceTranslations inserts new or updates matching (by-primary-key) rows in resource_translations with given data
-func (s Store) execUpsertResourceTranslations(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.resourceTranslationTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteResourceTranslations Deletes all matched (by cnd) rows in resource_translations with given data
-func (s Store) execDeleteResourceTranslations(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.resourceTranslationTable("rt")).Where(cnd))
-}
-
-func (s Store) internalResourceTranslationRowScanner(row rowScanner) (res *types.ResourceTranslation, err error) {
- res = &types.ResourceTranslation{}
-
- err = row.Scan(
- &res.ID,
- &res.Lang,
- &res.Resource,
- &res.K,
- &res.Message,
- &res.OwnedBy,
- &res.CreatedBy,
- &res.UpdatedBy,
- &res.DeletedBy,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan resourceTranslation db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryResourceTranslations returns squirrel.SelectBuilder with set table and all columns
-func (s Store) resourceTranslationsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.resourceTranslationTable("rt"), s.resourceTranslationColumns("rt")...)
-}
-
-// resourceTranslationTable name of the db table
-func (Store) resourceTranslationTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "resource_translations" + alias
-}
-
-// ResourceTranslationColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) resourceTranslationColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "lang",
- alias + "resource",
- alias + "k",
- alias + "message",
- alias + "owned_by",
- alias + "created_by",
- alias + "updated_by",
- alias + "deleted_by",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true false}
-
-// sortableResourceTranslationColumns returns all ResourceTranslation columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableResourceTranslationColumns() map[string]string {
- return map[string]string{
- "id": "id", "owned_by": "owned_by",
- "ownedby": "owned_by",
- "created_by": "created_by",
- "createdby": "created_by",
- "updated_by": "updated_by",
- "updatedby": "updated_by",
- "deleted_by": "deleted_by",
- "deletedby": "deleted_by",
- "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalResourceTranslationEncoder encodes fields from types.ResourceTranslation to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeResourceTranslation
-// func when rdbms.customEncoder=true
-func (s Store) internalResourceTranslationEncoder(res *types.ResourceTranslation) store.Payload {
- return store.Payload{
- "id": res.ID,
- "lang": res.Lang,
- "resource": res.Resource,
- "k": res.K,
- "message": res.Message,
- "owned_by": res.OwnedBy,
- "created_by": res.CreatedBy,
- "updated_by": res.UpdatedBy,
- "deleted_by": res.DeletedBy,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectResourceTranslationCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectResourceTranslationCursorValues(res *types.ResourceTranslation, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "owned_by":
- cursor.Set(c.Column, res.OwnedBy, c.Descending)
-
- case "created_by":
- cursor.Set(c.Column, res.CreatedBy, c.Descending)
-
- case "updated_by":
- cursor.Set(c.Column, res.UpdatedBy, c.Descending)
-
- case "deleted_by":
- cursor.Set(c.Column, res.DeletedBy, c.Descending)
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkResourceTranslationConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkResourceTranslationConstraints(ctx context.Context, res *types.ResourceTranslation) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/resource_translation.go b/store/rdbms/resource_translation.go
deleted file mode 100644
index 67096f494..000000000
--- a/store/rdbms/resource_translation.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package rdbms
-
-import (
- "context"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/pkg/locale"
- "github.com/cortezaproject/corteza-server/system/types"
- "golang.org/x/text/language"
-)
-
-func (s Store) convertResourceTranslationFilter(f types.ResourceTranslationFilter) (query squirrel.SelectBuilder, err error) {
- query = s.resourceTranslationsSelectBuilder()
-
- query = filter.StateCondition(query, "rt.deleted_at", f.Deleted)
-
- if len(f.TranslationID) > 0 {
- query = query.Where(squirrel.Eq{"rt.id": f.TranslationID})
- }
-
- if f.Lang != "" {
- query = query.Where(squirrel.Eq{"rt.lang": f.Lang})
- }
-
- if f.Resource != "" {
- query = query.Where(squirrel.Eq{"rt.resource": f.Resource})
- }
-
- if f.ResourceType != "" {
- query = query.Where(squirrel.Like{"rt.resource": f.ResourceType + "%"})
- }
-
- return
-}
-
-// TransformResource converts raw resource translations into the format used by
-// the locale package.
-//
-// @todo this function knows too much (locale pkg), move it out of store
-func (s *Store) TransformResource(ctx context.Context, lang language.Tag) (out map[string]map[string]*locale.ResourceTranslation, err error) {
- out = make(map[string]map[string]*locale.ResourceTranslation)
- var cc types.ResourceTranslationSet
- var ok bool
-
- cc, _, err = s.SearchResourceTranslations(ctx, types.ResourceTranslationFilter{
- Lang: lang.String(),
- })
- if err != nil {
- return
- }
-
- for _, c := range cc {
- if _, ok = out[c.Resource]; !ok {
- out[c.Resource] = make(map[string]*locale.ResourceTranslation)
- }
-
- out[c.Resource][c.K] = &locale.ResourceTranslation{
- Resource: c.Resource,
- Lang: c.Lang.String(),
- Key: c.K,
- Msg: c.Message,
- }
- }
-
- return
-}
diff --git a/store/rdbms/role_members.gen.go b/store/rdbms/role_members.gen.go
deleted file mode 100644
index 6f1ea406d..000000000
--- a/store/rdbms/role_members.gen.go
+++ /dev/null
@@ -1,317 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/role_members.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchRoleMembers returns all matching rows
-//
-// This function calls convertRoleMemberFilter with the given
-// types.RoleMemberFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchRoleMembers(ctx context.Context, f types.RoleMemberFilter) (types.RoleMemberSet, types.RoleMemberFilter, error) {
- var (
- err error
- set []*types.RoleMember
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertRoleMemberFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QueryRoleMembers(ctx, q, nil)
- return err
- }()
-}
-
-// QueryRoleMembers queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryRoleMembers(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.RoleMember) (bool, error),
-) ([]*types.RoleMember, error) {
- var (
- tmp = make([]*types.RoleMember, 0, DefaultSliceCapacity)
- set = make([]*types.RoleMember, 0, DefaultSliceCapacity)
- res *types.RoleMember
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalRoleMemberRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// CreateRoleMember creates one or more rows in role_members table
-func (s Store) CreateRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
- for _, res := range rr {
- err = s.checkRoleMemberConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateRoleMembers(ctx, s.internalRoleMemberEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateRoleMember updates one or more existing rows in role_members
-func (s Store) UpdateRoleMember(ctx context.Context, rr ...*types.RoleMember) error {
- return s.partialRoleMemberUpdate(ctx, nil, rr...)
-}
-
-// partialRoleMemberUpdate updates one or more existing rows in role_members
-func (s Store) partialRoleMemberUpdate(ctx context.Context, onlyColumns []string, rr ...*types.RoleMember) (err error) {
- for _, res := range rr {
- err = s.checkRoleMemberConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateRoleMembers(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("rm.rel_user", ""): store.PreprocessValue(res.UserID, ""), s.preprocessColumn("rm.rel_role", ""): store.PreprocessValue(res.RoleID, ""),
- },
- s.internalRoleMemberEncoder(res).Skip("rel_user", "rel_role").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertRoleMember updates one or more existing rows in role_members
-func (s Store) UpsertRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
- for _, res := range rr {
- err = s.checkRoleMemberConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertRoleMembers(ctx, s.internalRoleMemberEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteRoleMember Deletes one or more rows from role_members table
-func (s Store) DeleteRoleMember(ctx context.Context, rr ...*types.RoleMember) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteRoleMembers(ctx, squirrel.Eq{
- s.preprocessColumn("rm.rel_user", ""): store.PreprocessValue(res.UserID, ""), s.preprocessColumn("rm.rel_role", ""): store.PreprocessValue(res.RoleID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteRoleMemberByUserIDRoleID Deletes row from the role_members table
-func (s Store) DeleteRoleMemberByUserIDRoleID(ctx context.Context, userID uint64, roleID uint64) error {
- return s.execDeleteRoleMembers(ctx, squirrel.Eq{
- s.preprocessColumn("rm.rel_user", ""): store.PreprocessValue(userID, ""),
- s.preprocessColumn("rm.rel_role", ""): store.PreprocessValue(roleID, ""),
- })
-}
-
-// TruncateRoleMembers Deletes all rows from the role_members table
-func (s Store) TruncateRoleMembers(ctx context.Context) error {
- return s.Truncate(ctx, s.roleMemberTable())
-}
-
-// execLookupRoleMember prepares RoleMember query and executes it,
-// returning types.RoleMember (or error)
-func (s Store) execLookupRoleMember(ctx context.Context, cnd squirrel.Sqlizer) (res *types.RoleMember, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.roleMembersSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalRoleMemberRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateRoleMembers updates all matched (by cnd) rows in role_members with given data
-func (s Store) execCreateRoleMembers(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.roleMemberTable()).SetMap(payload))
-}
-
-// execUpdateRoleMembers updates all matched (by cnd) rows in role_members with given data
-func (s Store) execUpdateRoleMembers(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.roleMemberTable("rm")).Where(cnd).SetMap(set))
-}
-
-// execUpsertRoleMembers inserts new or updates matching (by-primary-key) rows in role_members with given data
-func (s Store) execUpsertRoleMembers(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.roleMemberTable(),
- set,
- s.preprocessColumn("rel_user", ""),
- s.preprocessColumn("rel_role", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteRoleMembers Deletes all matched (by cnd) rows in role_members with given data
-func (s Store) execDeleteRoleMembers(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.roleMemberTable("rm")).Where(cnd))
-}
-
-func (s Store) internalRoleMemberRowScanner(row rowScanner) (res *types.RoleMember, err error) {
- res = &types.RoleMember{}
-
- err = row.Scan(
- &res.UserID,
- &res.RoleID,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan roleMember db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryRoleMembers returns squirrel.SelectBuilder with set table and all columns
-func (s Store) roleMembersSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.roleMemberTable("rm"), s.roleMemberColumns("rm")...)
-}
-
-// roleMemberTable name of the db table
-func (Store) roleMemberTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "role_members" + alias
-}
-
-// RoleMemberColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) roleMemberColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "rel_user",
- alias + "rel_role",
- }
-}
-
-// {true true false false false false}
-
-// internalRoleMemberEncoder encodes fields from types.RoleMember to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeRoleMember
-// func when rdbms.customEncoder=true
-func (s Store) internalRoleMemberEncoder(res *types.RoleMember) store.Payload {
- return store.Payload{
- "rel_user": res.UserID,
- "rel_role": res.RoleID,
- }
-}
-
-// checkRoleMemberConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkRoleMemberConstraints(ctx context.Context, res *types.RoleMember) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/role_members.go b/store/rdbms/role_members.go
deleted file mode 100644
index 538a38a48..000000000
--- a/store/rdbms/role_members.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package rdbms
-
-import (
- "context"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertRoleMemberFilter(f types.RoleMemberFilter) (query squirrel.SelectBuilder, err error) {
- query = s.roleMembersSelectBuilder()
-
- if f.RoleID > 0 {
- query = query.Where(squirrel.Eq{"rm.rel_role": f.RoleID})
- }
-
- if f.UserID > 0 {
- query = query.Where(squirrel.Eq{"rm.rel_user": f.UserID})
- }
-
- return
-}
-
-func (s Store) TransferRoleMembers(ctx context.Context, src, dst uint64) (err error) {
- return s.execUpdateRoleMembers(ctx, squirrel.Eq{"rel_role": src}, store.Payload{"rel_role": dst})
-}
diff --git a/store/rdbms/roles.gen.go b/store/rdbms/roles.gen.go
deleted file mode 100644
index 2f5704829..000000000
--- a/store/rdbms/roles.gen.go
+++ /dev/null
@@ -1,658 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/roles.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchRoles returns all matching rows
-//
-// This function calls convertRoleFilter with the given
-// types.RoleFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchRoles(ctx context.Context, f types.RoleFilter) (types.RoleSet, types.RoleFilter, error) {
- var (
- err error
- set []*types.Role
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertRoleFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableRoleColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfRoles(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfRoles collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfRoles(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Role) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Role, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Role
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Role, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryRoles(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectRoleCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectRoleCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectRoleCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryRoles queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryRoles(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Role) (bool, error),
-) ([]*types.Role, error) {
- var (
- tmp = make([]*types.Role, 0, DefaultSliceCapacity)
- set = make([]*types.Role, 0, DefaultSliceCapacity)
- res *types.Role
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalRoleRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupRoleByID searches for role by ID
-//
-// It returns role even if deleted or suspended
-func (s Store) LookupRoleByID(ctx context.Context, id uint64) (*types.Role, error) {
- return s.execLookupRole(ctx, squirrel.Eq{
- s.preprocessColumn("rl.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupRoleByHandle searches for role by its handle
-//
-// It returns only valid roles (not deleted, not archived)
-func (s Store) LookupRoleByHandle(ctx context.Context, handle string) (*types.Role, error) {
- return s.execLookupRole(ctx, squirrel.Eq{
- s.preprocessColumn("rl.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "rl.archived_at": nil,
- "rl.deleted_at": nil,
- })
-}
-
-// LookupRoleByName searches for role by its name
-//
-// It returns only valid roles (not deleted, not archived)
-func (s Store) LookupRoleByName(ctx context.Context, name string) (*types.Role, error) {
- return s.execLookupRole(ctx, squirrel.Eq{
- s.preprocessColumn("rl.name", ""): store.PreprocessValue(name, ""),
-
- "rl.archived_at": nil,
- "rl.deleted_at": nil,
- })
-}
-
-// CreateRole creates one or more rows in roles table
-func (s Store) CreateRole(ctx context.Context, rr ...*types.Role) (err error) {
- for _, res := range rr {
- err = s.checkRoleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateRoles(ctx, s.internalRoleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateRole updates one or more existing rows in roles
-func (s Store) UpdateRole(ctx context.Context, rr ...*types.Role) error {
- return s.partialRoleUpdate(ctx, nil, rr...)
-}
-
-// partialRoleUpdate updates one or more existing rows in roles
-func (s Store) partialRoleUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Role) (err error) {
- for _, res := range rr {
- err = s.checkRoleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateRoles(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("rl.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalRoleEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertRole updates one or more existing rows in roles
-func (s Store) UpsertRole(ctx context.Context, rr ...*types.Role) (err error) {
- for _, res := range rr {
- err = s.checkRoleConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertRoles(ctx, s.internalRoleEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteRole Deletes one or more rows from roles table
-func (s Store) DeleteRole(ctx context.Context, rr ...*types.Role) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteRoles(ctx, squirrel.Eq{
- s.preprocessColumn("rl.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteRoleByID Deletes row from the roles table
-func (s Store) DeleteRoleByID(ctx context.Context, ID uint64) error {
- return s.execDeleteRoles(ctx, squirrel.Eq{
- s.preprocessColumn("rl.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateRoles Deletes all rows from the roles table
-func (s Store) TruncateRoles(ctx context.Context) error {
- return s.Truncate(ctx, s.roleTable())
-}
-
-// execLookupRole prepares Role query and executes it,
-// returning types.Role (or error)
-func (s Store) execLookupRole(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Role, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.rolesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalRoleRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateRoles updates all matched (by cnd) rows in roles with given data
-func (s Store) execCreateRoles(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.roleTable()).SetMap(payload))
-}
-
-// execUpdateRoles updates all matched (by cnd) rows in roles with given data
-func (s Store) execUpdateRoles(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.roleTable("rl")).Where(cnd).SetMap(set))
-}
-
-// execUpsertRoles inserts new or updates matching (by-primary-key) rows in roles with given data
-func (s Store) execUpsertRoles(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.roleTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteRoles Deletes all matched (by cnd) rows in roles with given data
-func (s Store) execDeleteRoles(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.roleTable("rl")).Where(cnd))
-}
-
-func (s Store) internalRoleRowScanner(row rowScanner) (res *types.Role, err error) {
- res = &types.Role{}
-
- err = row.Scan(
- &res.ID,
- &res.Name,
- &res.Handle,
- &res.Meta,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.ArchivedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan role db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryRoles returns squirrel.SelectBuilder with set table and all columns
-func (s Store) rolesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.roleTable("rl"), s.roleColumns("rl")...)
-}
-
-// roleTable name of the db table
-func (Store) roleTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "roles" + alias
-}
-
-// RoleColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) roleColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "name",
- alias + "handle",
- alias + "meta",
- alias + "created_at",
- alias + "updated_at",
- alias + "archived_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableRoleColumns returns all Role columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableRoleColumns() map[string]string {
- return map[string]string{
- "id": "id", "name": "name", "handle": "handle", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "archived_at": "archived_at",
- "archivedat": "archived_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalRoleEncoder encodes fields from types.Role to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeRole
-// func when rdbms.customEncoder=true
-func (s Store) internalRoleEncoder(res *types.Role) store.Payload {
- return store.Payload{
- "id": res.ID,
- "name": res.Name,
- "handle": res.Handle,
- "meta": res.Meta,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "archived_at": res.ArchivedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectRoleCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectRoleCursorValues(res *types.Role, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "name":
- cursor.Set(c.Column, res.Name, c.Descending)
-
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
- hasUnique = true
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "archived_at":
- cursor.Set(c.Column, res.ArchivedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkRoleConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkRoleConstraints(ctx context.Context, res *types.Role) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Handle) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Handle if Role does not match filters
- if res.ArchivedAt != nil {
- return nil
- }
-
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupRoleByHandle(ctx, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/roles.go b/store/rdbms/roles.go
deleted file mode 100644
index 0379365f1..000000000
--- a/store/rdbms/roles.go
+++ /dev/null
@@ -1,96 +0,0 @@
-package rdbms
-
-import (
- "context"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertRoleFilter(f types.RoleFilter) (query squirrel.SelectBuilder, err error) {
- query = s.rolesSelectBuilder()
-
- query = filter.StateCondition(query, "rl.deleted_at", f.Deleted)
- query = filter.StateCondition(query, "rl.archived_at", f.Archived)
-
- if len(f.RoleID) > 0 {
- query = query.Where(squirrel.Eq{"rl.ID": f.RoleID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"rl.id": f.LabeledIDs})
- }
-
- if f.MemberID > 0 {
- query = query.Where(squirrel.Expr("rl.ID IN (SELECT rel_role FROM role_members AS m WHERE m.rel_user = ?)", f.MemberID))
- }
-
- if f.Query != "" {
- qs := "%" + f.Query + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"rl.name": qs},
- squirrel.Like{"rl.handle": qs},
- })
- }
-
- if f.Name != "" {
- query = query.Where(squirrel.Eq{"rl.name": f.Name})
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"rl.handle": f.Handle})
- }
-
- return
-}
-
-func (s Store) RoleMetrics(ctx context.Context) (*types.RoleMetrics, error) {
- var (
- counters = squirrel.
- Select(
- "COUNT(*) as total",
- "SUM(CASE WHEN deleted_at IS NULL THEN 0 ELSE 1 END) as deleted",
- "SUM(CASE WHEN archived_at IS NULL THEN 0 ELSE 1 END) as archived",
- "SUM(CASE WHEN deleted_at IS NULL AND archived_at IS NULL THEN 1 ELSE 0 END) as valid",
- ).
- PlaceholderFormat(s.config.PlaceholderFormat).
- From(s.roleTable("u"))
-
- rval = &types.RoleMetrics{}
- row, err = s.QueryRow(ctx, counters)
- )
-
- if err != nil {
- return nil, err
- }
-
- err = row.Scan(&rval.Total, &rval.Deleted, &rval.Archived, &rval.Valid)
- if err != nil {
- return nil, err
- }
-
- // Fetch daily metrics for created, updated, deleted and suspended users
- err = s.multiDailyMetrics(
- ctx,
- squirrel.
- Select().
- PlaceholderFormat(s.config.PlaceholderFormat).
- From(s.roleTable("u")),
- []string{
- "created_at",
- "updated_at",
- "deleted_at",
- "archived_at",
- },
- &rval.DailyCreated,
- &rval.DailyUpdated,
- &rval.DailyDeleted,
- &rval.DailyArchived,
- )
-
- if err != nil {
- return nil, err
- }
-
- return rval, nil
-}
diff --git a/store/rdbms/settings.gen.go b/store/rdbms/settings.gen.go
deleted file mode 100644
index e90051154..000000000
--- a/store/rdbms/settings.gen.go
+++ /dev/null
@@ -1,344 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/settings.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchSettings returns all matching rows
-//
-// This function calls convertSettingFilter with the given
-// types.SettingsFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchSettings(ctx context.Context, f types.SettingsFilter) (types.SettingValueSet, types.SettingsFilter, error) {
- var (
- err error
- set []*types.SettingValue
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertSettingFilter(f)
- if err != nil {
- return err
- }
-
- set, err = s.QuerySettings(ctx, q, f.Check)
- return err
- }()
-}
-
-// QuerySettings queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QuerySettings(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.SettingValue) (bool, error),
-) ([]*types.SettingValue, error) {
- var (
- tmp = make([]*types.SettingValue, 0, DefaultSliceCapacity)
- set = make([]*types.SettingValue, 0, DefaultSliceCapacity)
- res *types.SettingValue
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalSettingRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupSettingByNameOwnedBy searches for settings by name and owner
-func (s Store) LookupSettingByNameOwnedBy(ctx context.Context, name string, owned_by uint64) (*types.SettingValue, error) {
- return s.execLookupSetting(ctx, squirrel.Eq{
- s.preprocessColumn("st.name", "lower"): store.PreprocessValue(name, "lower"),
- s.preprocessColumn("st.rel_owner", ""): store.PreprocessValue(owned_by, ""),
- })
-}
-
-// CreateSetting creates one or more rows in settings table
-func (s Store) CreateSetting(ctx context.Context, rr ...*types.SettingValue) (err error) {
- for _, res := range rr {
- err = s.checkSettingConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateSettings(ctx, s.internalSettingEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateSetting updates one or more existing rows in settings
-func (s Store) UpdateSetting(ctx context.Context, rr ...*types.SettingValue) error {
- return s.partialSettingUpdate(ctx, nil, rr...)
-}
-
-// partialSettingUpdate updates one or more existing rows in settings
-func (s Store) partialSettingUpdate(ctx context.Context, onlyColumns []string, rr ...*types.SettingValue) (err error) {
- for _, res := range rr {
- err = s.checkSettingConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateSettings(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("st.name", "lower"): store.PreprocessValue(res.Name, "lower"), s.preprocessColumn("st.rel_owner", ""): store.PreprocessValue(res.OwnedBy, ""),
- },
- s.internalSettingEncoder(res).Skip("name", "rel_owner").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertSetting updates one or more existing rows in settings
-func (s Store) UpsertSetting(ctx context.Context, rr ...*types.SettingValue) (err error) {
- for _, res := range rr {
- err = s.checkSettingConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertSettings(ctx, s.internalSettingEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteSetting Deletes one or more rows from settings table
-func (s Store) DeleteSetting(ctx context.Context, rr ...*types.SettingValue) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteSettings(ctx, squirrel.Eq{
- s.preprocessColumn("st.name", "lower"): store.PreprocessValue(res.Name, "lower"), s.preprocessColumn("st.rel_owner", ""): store.PreprocessValue(res.OwnedBy, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteSettingByNameOwnedBy Deletes row from the settings table
-func (s Store) DeleteSettingByNameOwnedBy(ctx context.Context, name string, ownedBy uint64) error {
- return s.execDeleteSettings(ctx, squirrel.Eq{
- s.preprocessColumn("st.name", "lower"): store.PreprocessValue(name, "lower"),
- s.preprocessColumn("st.rel_owner", ""): store.PreprocessValue(ownedBy, ""),
- })
-}
-
-// TruncateSettings Deletes all rows from the settings table
-func (s Store) TruncateSettings(ctx context.Context) error {
- return s.Truncate(ctx, s.settingTable())
-}
-
-// execLookupSetting prepares Setting query and executes it,
-// returning types.SettingValue (or error)
-func (s Store) execLookupSetting(ctx context.Context, cnd squirrel.Sqlizer) (res *types.SettingValue, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.settingsSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalSettingRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateSettings updates all matched (by cnd) rows in settings with given data
-func (s Store) execCreateSettings(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.settingTable()).SetMap(payload))
-}
-
-// execUpdateSettings updates all matched (by cnd) rows in settings with given data
-func (s Store) execUpdateSettings(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.settingTable("st")).Where(cnd).SetMap(set))
-}
-
-// execUpsertSettings inserts new or updates matching (by-primary-key) rows in settings with given data
-func (s Store) execUpsertSettings(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.settingTable(),
- set,
- s.preprocessColumn("name", "lower"),
- s.preprocessColumn("rel_owner", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteSettings Deletes all matched (by cnd) rows in settings with given data
-func (s Store) execDeleteSettings(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.settingTable("st")).Where(cnd))
-}
-
-func (s Store) internalSettingRowScanner(row rowScanner) (res *types.SettingValue, err error) {
- res = &types.SettingValue{}
-
- err = row.Scan(
- &res.Name,
- &res.OwnedBy,
- &res.Value,
- &res.UpdatedBy,
- &res.UpdatedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan setting db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QuerySettings returns squirrel.SelectBuilder with set table and all columns
-func (s Store) settingsSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.settingTable("st"), s.settingColumns("st")...)
-}
-
-// settingTable name of the db table
-func (Store) settingTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "settings" + alias
-}
-
-// SettingColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) settingColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "name",
- alias + "rel_owner",
- alias + "value",
- alias + "updated_by",
- alias + "updated_at",
- }
-}
-
-// {true true false false false true}
-
-// internalSettingEncoder encodes fields from types.SettingValue to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeSetting
-// func when rdbms.customEncoder=true
-func (s Store) internalSettingEncoder(res *types.SettingValue) store.Payload {
- return store.Payload{
- "name": res.Name,
- "rel_owner": res.OwnedBy,
- "value": res.Value,
- "updated_by": res.UpdatedBy,
- "updated_at": res.UpdatedAt,
- }
-}
-
-// checkSettingConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkSettingConstraints(ctx context.Context, res *types.SettingValue) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/settings.go b/store/rdbms/settings.go
deleted file mode 100644
index d34782624..000000000
--- a/store/rdbms/settings.go
+++ /dev/null
@@ -1,82 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) columns() []string {
- return []string{
- "name",
- "value",
- "rel_owner",
- "updated_at",
- "updated_by",
- }
-}
-
-func (s Store) convertSettingFilter(f types.SettingsFilter) (query squirrel.SelectBuilder, err error) {
- query = s.settingsSelectBuilder().Where(squirrel.Eq{"rel_owner": f.OwnedBy})
-
- if len(f.Prefix) > 0 {
- query = query.Where("name LIKE ?", f.Prefix+"%")
- }
-
- return
-}
-
-//func (s Store) BulkSet(ctx context.Context, vv ValueSet) error {
-// // Save all inside a db transaction
-// return r.db().Transaction(func() (err error) {
-// return vv.Walk(func(v *SettingValue) error {
-// return r.Set(v)
-// })
-// })
-//}
-//
-//func (s Store) UpdateSettings(ctx context.Context, value *SettingValue) error {
-// return s.DB().Replace(s.dbTable, value)
-//}
-//
-//func (s Store) DeleteSettings(name string, ownedBy uint64) error {
-// _, err := s.db().Exec(
-// fmt.Sprintf("DELETE FROM %s WHERE name = ? AND rel_owner = ? ", s.dbTable),
-// name,
-// ownedBy,
-// )
-// return err
-//}
-//
-//func (s Store) SettingsLookupByName(ctx context.Context, name string, ownedBy uint64) (*settings.SettingValue, error) {
-// var (
-// v = &settings.SettingValue{}
-// cnd = squirrel.Eq{"rel_owner": ownedBy, "name": name}
-// err = s.Lookup(ctx, v, s.QuerySettings(), cnd)
-// )
-//
-// if err != nil {
-// return
-// }
-//
-// return v, err
-//}
-//
-//// Returns squirrel.selectBuilder
-//func (s Store) QuerySettings() squirrel.selectBuilder {
-// return s.selectBuilder(s.SettingsTable()+" AS stngs", s.SettingsColumns()...)
-//}
-//
-//// Name of the db table
-//func (Store) SettingsTable() string {
-// return "sys_settings"
-//}
-//
-//func (Store) SettingsColumns() []string {
-// return []string{
-// "stngs.name",
-// "stngs.value",
-// "stngs.rel_owner",
-// "stngs.created_by",
-// "stngs.updated_at",
-// }
-//}
diff --git a/store/rdbms/squirrel.go b/store/rdbms/squirrel.go
deleted file mode 100644
index ff1b58841..000000000
--- a/store/rdbms/squirrel.go
+++ /dev/null
@@ -1,48 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
-)
-
-type (
- squirrelConcatExpr struct {
- f squirrel.PlaceholderFormat
- args []interface{}
- }
-)
-
-func SquirrelConcatExpr(args ...interface{}) *squirrelConcatExpr {
- return &squirrelConcatExpr{args: args, f: squirrel.Question}
-}
-
-func (w *squirrelConcatExpr) PlaceholderFormat(f squirrel.PlaceholderFormat) *squirrelConcatExpr {
- w.f = f
- return w
-}
-
-func (w *squirrelConcatExpr) ToSql() (sql string, args []interface{}, err error) {
- var (
- partSql string
- partArgs []interface{}
- )
-
- for _, a := range w.args {
- switch o := a.(type) {
- case string:
- sql += o
- case squirrel.Sqlizer:
- if partSql, partArgs, err = o.ToSql(); err != nil {
- return
- }
-
- sql += partSql
- args = append(args, partArgs...)
- }
- }
-
- if sql, err = w.f.ReplacePlaceholders(sql); err != nil {
- return
- }
-
- return
-}
diff --git a/store/rdbms/templates.gen.go b/store/rdbms/templates.gen.go
deleted file mode 100644
index fd40799b9..000000000
--- a/store/rdbms/templates.gen.go
+++ /dev/null
@@ -1,650 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/templates.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchTemplates returns all matching rows
-//
-// This function calls convertTemplateFilter with the given
-// types.TemplateFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchTemplates(ctx context.Context, f types.TemplateFilter) (types.TemplateSet, types.TemplateFilter, error) {
- var (
- err error
- set []*types.Template
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertTemplateFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableTemplateColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfTemplates(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfTemplates collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfTemplates(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.Template) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.Template, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.Template
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.Template, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryTemplates(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectTemplateCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectTemplateCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectTemplateCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryTemplates queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryTemplates(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.Template) (bool, error),
-) ([]*types.Template, error) {
- var (
- tmp = make([]*types.Template, 0, DefaultSliceCapacity)
- set = make([]*types.Template, 0, DefaultSliceCapacity)
- res *types.Template
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalTemplateRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupTemplateByID searches for template by ID
-//
-// It also returns deleted templates.
-func (s Store) LookupTemplateByID(ctx context.Context, id uint64) (*types.Template, error) {
- return s.execLookupTemplate(ctx, squirrel.Eq{
- s.preprocessColumn("tpl.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupTemplateByHandle searches for template by the handle
-//
-// It returns only valid templates (not deleted)
-func (s Store) LookupTemplateByHandle(ctx context.Context, handle string) (*types.Template, error) {
- return s.execLookupTemplate(ctx, squirrel.Eq{
- s.preprocessColumn("tpl.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "tpl.deleted_at": nil,
- })
-}
-
-// CreateTemplate creates one or more rows in templates table
-func (s Store) CreateTemplate(ctx context.Context, rr ...*types.Template) (err error) {
- for _, res := range rr {
- err = s.checkTemplateConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateTemplates(ctx, s.internalTemplateEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateTemplate updates one or more existing rows in templates
-func (s Store) UpdateTemplate(ctx context.Context, rr ...*types.Template) error {
- return s.partialTemplateUpdate(ctx, nil, rr...)
-}
-
-// partialTemplateUpdate updates one or more existing rows in templates
-func (s Store) partialTemplateUpdate(ctx context.Context, onlyColumns []string, rr ...*types.Template) (err error) {
- for _, res := range rr {
- err = s.checkTemplateConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateTemplates(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("tpl.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalTemplateEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertTemplate updates one or more existing rows in templates
-func (s Store) UpsertTemplate(ctx context.Context, rr ...*types.Template) (err error) {
- for _, res := range rr {
- err = s.checkTemplateConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertTemplates(ctx, s.internalTemplateEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteTemplate Deletes one or more rows from templates table
-func (s Store) DeleteTemplate(ctx context.Context, rr ...*types.Template) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteTemplates(ctx, squirrel.Eq{
- s.preprocessColumn("tpl.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteTemplateByID Deletes row from the templates table
-func (s Store) DeleteTemplateByID(ctx context.Context, ID uint64) error {
- return s.execDeleteTemplates(ctx, squirrel.Eq{
- s.preprocessColumn("tpl.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateTemplates Deletes all rows from the templates table
-func (s Store) TruncateTemplates(ctx context.Context) error {
- return s.Truncate(ctx, s.templateTable())
-}
-
-// execLookupTemplate prepares Template query and executes it,
-// returning types.Template (or error)
-func (s Store) execLookupTemplate(ctx context.Context, cnd squirrel.Sqlizer) (res *types.Template, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.templatesSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalTemplateRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateTemplates updates all matched (by cnd) rows in templates with given data
-func (s Store) execCreateTemplates(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.templateTable()).SetMap(payload))
-}
-
-// execUpdateTemplates updates all matched (by cnd) rows in templates with given data
-func (s Store) execUpdateTemplates(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.templateTable("tpl")).Where(cnd).SetMap(set))
-}
-
-// execUpsertTemplates inserts new or updates matching (by-primary-key) rows in templates with given data
-func (s Store) execUpsertTemplates(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.templateTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteTemplates Deletes all matched (by cnd) rows in templates with given data
-func (s Store) execDeleteTemplates(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.templateTable("tpl")).Where(cnd))
-}
-
-func (s Store) internalTemplateRowScanner(row rowScanner) (res *types.Template, err error) {
- res = &types.Template{}
-
- err = row.Scan(
- &res.ID,
- &res.Handle,
- &res.Language,
- &res.Type,
- &res.Partial,
- &res.Meta,
- &res.Template,
- &res.OwnerID,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.DeletedAt,
- &res.LastUsedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan template db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryTemplates returns squirrel.SelectBuilder with set table and all columns
-func (s Store) templatesSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.templateTable("tpl"), s.templateColumns("tpl")...)
-}
-
-// templateTable name of the db table
-func (Store) templateTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "templates" + alias
-}
-
-// TemplateColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) templateColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "handle",
- alias + "language",
- alias + "type",
- alias + "partial",
- alias + "meta",
- alias + "template",
- alias + "rel_owner",
- alias + "created_at",
- alias + "updated_at",
- alias + "deleted_at",
- alias + "last_used_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableTemplateColumns returns all Template columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableTemplateColumns() map[string]string {
- return map[string]string{
- "id": "id", "handle": "handle", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- "last_used_at": "last_used_at",
- "lastusedat": "last_used_at",
- }
-}
-
-// internalTemplateEncoder encodes fields from types.Template to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeTemplate
-// func when rdbms.customEncoder=true
-func (s Store) internalTemplateEncoder(res *types.Template) store.Payload {
- return store.Payload{
- "id": res.ID,
- "handle": res.Handle,
- "language": res.Language,
- "type": res.Type,
- "partial": res.Partial,
- "meta": res.Meta,
- "template": res.Template,
- "rel_owner": res.OwnerID,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "deleted_at": res.DeletedAt,
- "last_used_at": res.LastUsedAt,
- }
-}
-
-// collectTemplateCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectTemplateCursorValues(res *types.Template, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
- hasUnique = true
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- case "last_used_at":
- cursor.Set(c.Column, res.LastUsedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkTemplateConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkTemplateConstraints(ctx context.Context, res *types.Template) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Handle) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Handle if Template does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupTemplateByHandle(ctx, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/templates.go b/store/rdbms/templates.go
deleted file mode 100644
index 981b85924..000000000
--- a/store/rdbms/templates.go
+++ /dev/null
@@ -1,39 +0,0 @@
-package rdbms
-
-import (
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertTemplateFilter(f types.TemplateFilter) (query squirrel.SelectBuilder, err error) {
- query = s.templatesSelectBuilder()
-
- query = filter.StateCondition(query, "tpl.deleted_at", f.Deleted)
-
- if len(f.TemplateID) > 0 {
- query = query.Where(squirrel.Eq{"tpl.id": f.TemplateID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"tpl.id": f.LabeledIDs})
- }
-
- if f.Partial {
- query = query.Where(squirrel.Eq{"tpl.partial": true})
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Like{"tpl.handle": "%" + f.Handle + "%"})
- }
-
- if f.Type != "" {
- query = query.Where(squirrel.Eq{"tpl.type": f.Type})
- }
-
- if f.OwnerID > 0 {
- query = query.Where(squirrel.Eq{"tpl.rel_owner": f.OwnerID})
- }
-
- return
-}
diff --git a/store/rdbms/users.gen.go b/store/rdbms/users.gen.go
deleted file mode 100644
index 94c4912b6..000000000
--- a/store/rdbms/users.gen.go
+++ /dev/null
@@ -1,719 +0,0 @@
-package rdbms
-
-// This file is an auto-generated file
-//
-// Template: pkg/codegen/assets/store_rdbms.gen.go.tpl
-// Definitions: store/users.yaml
-//
-// Changes to this file may cause incorrect behavior
-// and will be lost if the code is regenerated.
-
-import (
- "context"
- "database/sql"
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/errors"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/rdbms/builders"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-var _ = errors.Is
-
-// SearchUsers returns all matching rows
-//
-// This function calls convertUserFilter with the given
-// types.UserFilter and expects to receive a working squirrel.SelectBuilder
-func (s Store) SearchUsers(ctx context.Context, f types.UserFilter) (types.UserSet, types.UserFilter, error) {
- var (
- err error
- set []*types.User
- q squirrel.SelectBuilder
- )
-
- return set, f, func() error {
- q, err = s.convertUserFilter(f)
- if err != nil {
- return err
- }
-
- // Paging enabled
- // {search: {enablePaging:true}}
- // Cleanup unwanted cursor values (only relevant is f.PageCursor, next&prev are reset and returned)
- f.PrevPage, f.NextPage = nil, nil
-
- if f.PageCursor != nil {
- // Page cursor exists so we need to validate it against used sort
- // To cover the case when paging cursor is set but sorting is empty, we collect the sorting instructions
- // from the cursor.
- // This (extracted sorting info) is then returned as part of response
- if f.Sort, err = f.PageCursor.Sort(f.Sort); err != nil {
- return err
- }
- }
-
- // Make sure results are always sorted at least by primary keys
- if f.Sort.Get("id") == nil {
- f.Sort = append(f.Sort, &filter.SortExpr{
- Column: "id",
- Descending: f.Sort.LastDescending(),
- })
- }
-
- // Cloned sorting instructions for the actual sorting
- // Original are passed to the fetchFullPageOfUsers fn used for cursor creation so it MUST keep the initial
- // direction information
- sort := f.Sort.Clone()
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- if f.PageCursor != nil && f.PageCursor.ROrder {
- sort.Reverse()
- }
-
- // Apply sorting expr from filter to query
- if q, err = setOrderBy(q, sort, s.sortableUserColumns(), s.Config().SqlSortHandler); err != nil {
- return err
- }
-
- set, f.PrevPage, f.NextPage, err = s.fetchFullPageOfUsers(
- ctx,
- q, f.Sort, f.PageCursor,
- f.Limit,
- f.Check,
- func(cur *filter.PagingCursor) squirrel.Sqlizer {
- return builders.CursorCondition(cur, nil)
- },
- )
-
- if err != nil {
- return err
- }
-
- f.PageCursor = nil
- return nil
- }()
-}
-
-// fetchFullPageOfUsers collects all requested results.
-//
-// Function applies:
-// - cursor conditions (where ...)
-// - limit
-//
-// Main responsibility of this function is to perform additional sequential queries in case when not enough results
-// are collected due to failed check on a specific row (by check fn).
-//
-// Function then moves cursor to the last item fetched
-func (s Store) fetchFullPageOfUsers(
- ctx context.Context,
- q squirrel.SelectBuilder,
- sort filter.SortExprSet,
- cursor *filter.PagingCursor,
- reqItems uint,
- check func(*types.User) (bool, error),
- cursorCond func(*filter.PagingCursor) squirrel.Sqlizer,
-) (set []*types.User, prev, next *filter.PagingCursor, err error) {
- var (
- aux []*types.User
-
- // When cursor for a previous page is used it's marked as reversed
- // This tells us to flip the descending flag on all used sort keys
- reversedOrder = cursor != nil && cursor.ROrder
-
- // copy of the select builder
- tryQuery squirrel.SelectBuilder
-
- // Copy no. of required items to limit
- // Limit will change when doing subsequent queries to fill
- // the set with all required items
- limit = reqItems
-
- // cursor to prev. page is only calculated when cursor is used
- hasPrev = cursor != nil
-
- // next cursor is calculated when there are more pages to come
- hasNext bool
- )
-
- set = make([]*types.User, 0, DefaultSliceCapacity)
-
- for try := 0; try < MaxRefetches; try++ {
- if cursor != nil {
- tryQuery = q.Where(cursorCond(cursor))
- } else {
- tryQuery = q
- }
-
- if limit > 0 {
- // fetching + 1 so we know if there are more items
- // we can fetch (next-page cursor)
- tryQuery = tryQuery.Limit(uint64(limit + 1))
- }
-
- if aux, err = s.QueryUsers(ctx, tryQuery, check); err != nil {
- return nil, nil, nil, err
- }
-
- if len(aux) == 0 {
- // nothing fetched
- break
- }
-
- // append fetched items
- set = append(set, aux...)
-
- if reqItems == 0 {
- // no max requested items specified, break out
- break
- }
-
- collected := uint(len(set))
-
- if reqItems > collected {
- // not enough items fetched, try again with adjusted limit
- limit = reqItems - collected
-
- if limit < MinEnsureFetchLimit {
- // In case limit is set very low and we've missed records in the first fetch,
- // make sure next fetch limit is a bit higher
- limit = MinEnsureFetchLimit
- }
-
- // Update cursor so that it points to the last item fetched
- cursor = s.collectUserCursorValues(set[collected-1], sort...)
-
- // Copy reverse flag from sorting
- cursor.LThen = sort.Reversed()
- continue
- }
-
- if reqItems < collected {
- set = set[:reqItems]
- hasNext = true
- }
-
- break
- }
-
- collected := len(set)
-
- if collected == 0 {
- return nil, nil, nil, nil
- }
-
- if reversedOrder {
- // Fetched set needs to be reversed because we've forced a descending order to get the previous page
- for i, j := 0, collected-1; i < j; i, j = i+1, j-1 {
- set[i], set[j] = set[j], set[i]
- }
-
- // when in reverse-order rules on what cursor to return change
- hasPrev, hasNext = hasNext, hasPrev
- }
-
- if hasPrev {
- prev = s.collectUserCursorValues(set[0], sort...)
- prev.ROrder = true
- prev.LThen = !sort.Reversed()
- }
-
- if hasNext {
- next = s.collectUserCursorValues(set[collected-1], sort...)
- next.LThen = sort.Reversed()
- }
-
- return set, prev, next, nil
-}
-
-// QueryUsers queries the database, converts and checks each row and
-// returns collected set
-//
-// Fn also returns total number of fetched items and last fetched item so that the caller can construct cursor
-// for next page of results
-func (s Store) QueryUsers(
- ctx context.Context,
- q squirrel.Sqlizer,
- check func(*types.User) (bool, error),
-) ([]*types.User, error) {
- var (
- tmp = make([]*types.User, 0, DefaultSliceCapacity)
- set = make([]*types.User, 0, DefaultSliceCapacity)
- res *types.User
-
- // Query rows with
- rows, err = s.Query(ctx, q)
- )
-
- if err != nil {
- return nil, err
- }
-
- defer rows.Close()
- for rows.Next() {
- if err = rows.Err(); err == nil {
- res, err = s.internalUserRowScanner(rows)
- }
-
- if err != nil {
- return nil, err
- }
-
- tmp = append(tmp, res)
- }
-
- for _, res = range tmp {
-
- // check fn set, call it and see if it passed the test
- // if not, skip the item
- if check != nil {
- if chk, err := check(res); err != nil {
- return nil, err
- } else if !chk {
- continue
- }
- }
-
- set = append(set, res)
- }
-
- return set, nil
-}
-
-// LookupUserByID searches for user by ID
-//
-// It returns user even if deleted or suspended
-func (s Store) LookupUserByID(ctx context.Context, id uint64) (*types.User, error) {
- return s.execLookupUser(ctx, squirrel.Eq{
- s.preprocessColumn("usr.id", ""): store.PreprocessValue(id, ""),
- })
-}
-
-// LookupUserByEmail searches for user by their email
-//
-// It returns only valid users (not deleted, not suspended)
-func (s Store) LookupUserByEmail(ctx context.Context, email string) (*types.User, error) {
- return s.execLookupUser(ctx, squirrel.Eq{
- s.preprocessColumn("usr.email", "lower"): store.PreprocessValue(email, "lower"),
-
- "usr.deleted_at": nil,
- })
-}
-
-// LookupUserByHandle searches for user by their email
-//
-// It returns only valid users (not deleted, not suspended)
-func (s Store) LookupUserByHandle(ctx context.Context, handle string) (*types.User, error) {
- return s.execLookupUser(ctx, squirrel.Eq{
- s.preprocessColumn("usr.handle", "lower"): store.PreprocessValue(handle, "lower"),
-
- "usr.deleted_at": nil,
- })
-}
-
-// LookupUserByUsername searches for user by their username
-//
-// It returns only valid users (not deleted, not suspended)
-func (s Store) LookupUserByUsername(ctx context.Context, username string) (*types.User, error) {
- return s.execLookupUser(ctx, squirrel.Eq{
- s.preprocessColumn("usr.username", "lower"): store.PreprocessValue(username, "lower"),
-
- "usr.deleted_at": nil,
- })
-}
-
-// CreateUser creates one or more rows in users table
-func (s Store) CreateUser(ctx context.Context, rr ...*types.User) (err error) {
- for _, res := range rr {
- err = s.checkUserConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execCreateUsers(ctx, s.internalUserEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpdateUser updates one or more existing rows in users
-func (s Store) UpdateUser(ctx context.Context, rr ...*types.User) error {
- return s.partialUserUpdate(ctx, nil, rr...)
-}
-
-// partialUserUpdate updates one or more existing rows in users
-func (s Store) partialUserUpdate(ctx context.Context, onlyColumns []string, rr ...*types.User) (err error) {
- for _, res := range rr {
- err = s.checkUserConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpdateUsers(
- ctx,
- squirrel.Eq{
- s.preprocessColumn("usr.id", ""): store.PreprocessValue(res.ID, ""),
- },
- s.internalUserEncoder(res).Skip("id").Only(onlyColumns...))
- if err != nil {
- return err
- }
- }
-
- return
-}
-
-// UpsertUser updates one or more existing rows in users
-func (s Store) UpsertUser(ctx context.Context, rr ...*types.User) (err error) {
- for _, res := range rr {
- err = s.checkUserConstraints(ctx, res)
- if err != nil {
- return err
- }
-
- err = s.execUpsertUsers(ctx, s.internalUserEncoder(res))
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteUser Deletes one or more rows from users table
-func (s Store) DeleteUser(ctx context.Context, rr ...*types.User) (err error) {
- for _, res := range rr {
-
- err = s.execDeleteUsers(ctx, squirrel.Eq{
- s.preprocessColumn("usr.id", ""): store.PreprocessValue(res.ID, ""),
- })
- if err != nil {
- return err
- }
- }
-
- return nil
-}
-
-// DeleteUserByID Deletes row from the users table
-func (s Store) DeleteUserByID(ctx context.Context, ID uint64) error {
- return s.execDeleteUsers(ctx, squirrel.Eq{
- s.preprocessColumn("usr.id", ""): store.PreprocessValue(ID, ""),
- })
-}
-
-// TruncateUsers Deletes all rows from the users table
-func (s Store) TruncateUsers(ctx context.Context) error {
- return s.Truncate(ctx, s.userTable())
-}
-
-// execLookupUser prepares User query and executes it,
-// returning types.User (or error)
-func (s Store) execLookupUser(ctx context.Context, cnd squirrel.Sqlizer) (res *types.User, err error) {
- var (
- row rowScanner
- )
-
- row, err = s.QueryRow(ctx, s.usersSelectBuilder().Where(cnd))
- if err != nil {
- return
- }
-
- res, err = s.internalUserRowScanner(row)
- if err != nil {
- return
- }
-
- return res, nil
-}
-
-// execCreateUsers updates all matched (by cnd) rows in users with given data
-func (s Store) execCreateUsers(ctx context.Context, payload store.Payload) error {
- return s.Exec(ctx, s.InsertBuilder(s.userTable()).SetMap(payload))
-}
-
-// execUpdateUsers updates all matched (by cnd) rows in users with given data
-func (s Store) execUpdateUsers(ctx context.Context, cnd squirrel.Sqlizer, set store.Payload) error {
- return s.Exec(ctx, s.UpdateBuilder(s.userTable("usr")).Where(cnd).SetMap(set))
-}
-
-// execUpsertUsers inserts new or updates matching (by-primary-key) rows in users with given data
-func (s Store) execUpsertUsers(ctx context.Context, set store.Payload) error {
- upsert, err := s.config.UpsertBuilder(
- s.config,
- s.userTable(),
- set,
- s.preprocessColumn("id", ""),
- )
-
- if err != nil {
- return err
- }
-
- return s.Exec(ctx, upsert)
-}
-
-// execDeleteUsers Deletes all matched (by cnd) rows in users with given data
-func (s Store) execDeleteUsers(ctx context.Context, cnd squirrel.Sqlizer) error {
- return s.Exec(ctx, s.DeleteBuilder(s.userTable("usr")).Where(cnd))
-}
-
-func (s Store) internalUserRowScanner(row rowScanner) (res *types.User, err error) {
- res = &types.User{}
-
- err = row.Scan(
- &res.ID,
- &res.Email,
- &res.EmailConfirmed,
- &res.Username,
- &res.Name,
- &res.Handle,
- &res.Meta,
- &res.Kind,
- &res.CreatedAt,
- &res.UpdatedAt,
- &res.SuspendedAt,
- &res.DeletedAt,
- )
-
- if err == sql.ErrNoRows {
- return nil, store.ErrNotFound.Stack(1)
- }
-
- if err != nil {
- return nil, errors.Store("could not scan user db row: %s", err).Wrap(err)
- } else {
- return res, nil
- }
-}
-
-// QueryUsers returns squirrel.SelectBuilder with set table and all columns
-func (s Store) usersSelectBuilder() squirrel.SelectBuilder {
- return s.SelectBuilder(s.userTable("usr"), s.userColumns("usr")...)
-}
-
-// userTable name of the db table
-func (Store) userTable(aa ...string) string {
- var alias string
- if len(aa) > 0 {
- alias = " AS " + aa[0]
- }
-
- return "users" + alias
-}
-
-// UserColumns returns all defined table columns
-//
-// With optional string arg, all columns are returned aliased
-func (Store) userColumns(aa ...string) []string {
- var alias string
- if len(aa) > 0 {
- alias = aa[0] + "."
- }
-
- return []string{
- alias + "id",
- alias + "email",
- alias + "email_confirmed",
- alias + "username",
- alias + "name",
- alias + "handle",
- alias + "meta",
- alias + "kind",
- alias + "created_at",
- alias + "updated_at",
- alias + "suspended_at",
- alias + "deleted_at",
- }
-}
-
-// {true true false true true true}
-
-// sortableUserColumns returns all User columns flagged as sortable
-//
-// With optional string arg, all columns are returned aliased
-func (Store) sortableUserColumns() map[string]string {
- return map[string]string{
- "id": "id", "email": "email", "username": "username", "name": "name", "handle": "handle", "created_at": "created_at",
- "createdat": "created_at",
- "updated_at": "updated_at",
- "updatedat": "updated_at",
- "suspended_at": "suspended_at",
- "suspendedat": "suspended_at",
- "deleted_at": "deleted_at",
- "deletedat": "deleted_at",
- }
-}
-
-// internalUserEncoder encodes fields from types.User to store.Payload (map)
-//
-// Encoding is done by using generic approach or by calling encodeUser
-// func when rdbms.customEncoder=true
-func (s Store) internalUserEncoder(res *types.User) store.Payload {
- return store.Payload{
- "id": res.ID,
- "email": res.Email,
- "email_confirmed": res.EmailConfirmed,
- "username": res.Username,
- "name": res.Name,
- "handle": res.Handle,
- "meta": res.Meta,
- "kind": res.Kind,
- "created_at": res.CreatedAt,
- "updated_at": res.UpdatedAt,
- "suspended_at": res.SuspendedAt,
- "deleted_at": res.DeletedAt,
- }
-}
-
-// collectUserCursorValues collects values from the given resource that and sets them to the cursor
-// to be used for pagination
-//
-// Values that are collected must come from sortable, unique or primary columns/fields
-// At least one of the collected columns must be flagged as unique, otherwise fn appends primary keys at the end
-//
-// Known issue:
-// when collecting cursor values for query that sorts by unique column with partial index (ie: unique handle on
-// undeleted items)
-func (s Store) collectUserCursorValues(res *types.User, cc ...*filter.SortExpr) *filter.PagingCursor {
- var (
- cursor = &filter.PagingCursor{LThen: filter.SortExprSet(cc).Reversed()}
-
- hasUnique bool
-
- // All known primary key columns
-
- pkId bool
-
- collect = func(cc ...*filter.SortExpr) {
- for _, c := range cc {
- switch c.Column {
- case "id":
- cursor.Set(c.Column, res.ID, c.Descending)
-
- pkId = true
- case "email":
- cursor.Set(c.Column, res.Email, c.Descending)
- hasUnique = true
-
- case "username":
- cursor.Set(c.Column, res.Username, c.Descending)
- hasUnique = true
-
- case "name":
- cursor.Set(c.Column, res.Name, c.Descending)
-
- case "handle":
- cursor.Set(c.Column, res.Handle, c.Descending)
- hasUnique = true
-
- case "created_at":
- cursor.Set(c.Column, res.CreatedAt, c.Descending)
-
- case "updated_at":
- cursor.Set(c.Column, res.UpdatedAt, c.Descending)
-
- case "suspended_at":
- cursor.Set(c.Column, res.SuspendedAt, c.Descending)
-
- case "deleted_at":
- cursor.Set(c.Column, res.DeletedAt, c.Descending)
-
- }
- }
- }
- )
-
- collect(cc...)
- if !hasUnique || !(pkId && true) {
- collect(&filter.SortExpr{Column: "id", Descending: false})
- }
-
- return cursor
-}
-
-// checkUserConstraints performs lookups (on valid) resource to check if any of the values on unique fields
-// already exists in the store
-//
-// Using built-in constraint checking would be more performant but unfortunately we cannot rely
-// on the full support (MySQL does not support conditional indexes)
-func (s *Store) checkUserConstraints(ctx context.Context, res *types.User) error {
- // Consider resource valid when all fields in unique constraint check lookups
- // have valid (non-empty) value
- //
- // Only string and uint64 are supported for now
- // feel free to add additional types if needed
- var valid = true
-
- valid = valid && len(res.Email) > 0
-
- valid = valid && len(res.Handle) > 0
-
- valid = valid && len(res.Username) > 0
-
- if !valid {
- return nil
- }
-
- var checks = make([]func() error, 0)
-
- checks = append(checks, func() error {
- // Skip lookup by Email if User does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupUserByEmail(ctx, res.Email)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by Handle if User does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupUserByHandle(ctx, res.Handle)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- checks = append(checks, func() error {
- // Skip lookup by Username if User does not match filters
- if res.DeletedAt != nil {
- return nil
- }
-
- ex, err := s.LookupUserByUsername(ctx, res.Username)
- if err == nil && ex != nil && ex.ID != res.ID {
- return store.ErrNotUnique.Stack(1)
- } else if !errors.IsNotFound(err) {
- return err
- }
-
- return nil
- })
-
- for _, check := range checks {
- if err := check(); err != nil {
- return err
- }
- }
-
- return nil
-}
diff --git a/store/rdbms/users.go b/store/rdbms/users.go
deleted file mode 100644
index 7c5a6b1bd..000000000
--- a/store/rdbms/users.go
+++ /dev/null
@@ -1,130 +0,0 @@
-package rdbms
-
-import (
- "context"
- "fmt"
-
- "github.com/Masterminds/squirrel"
- "github.com/cortezaproject/corteza-server/pkg/filter"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-func (s Store) convertUserFilter(f types.UserFilter) (query squirrel.SelectBuilder, err error) {
- query = s.usersSelectBuilder()
-
- query = filter.StateCondition(query, "usr.deleted_at", f.Deleted)
- query = filter.StateCondition(query, "usr.suspended_at", f.Suspended)
-
- if len(f.UserID) > 0 {
- query = query.Where(squirrel.Eq{"usr.id": f.UserID})
- }
-
- if len(f.LabeledIDs) > 0 {
- query = query.Where(squirrel.Eq{"usr.id": f.LabeledIDs})
- }
-
- if len(f.RoleID) > 0 {
- or := squirrel.Or{}
- // Due to lack of support for more exotic expressions (slice of values inside subquery)
- // we'll use set of OR expressions as a workaround
- for _, roleID := range f.RoleID {
- or = append(or, squirrel.Expr("usr.ID IN (SELECT rel_user FROM role_members WHERE rel_role = ?)", roleID))
- }
-
- query = query.Where(or)
- }
-
- if f.Query != "" {
- qs := "%" + f.Query + "%"
- query = query.Where(squirrel.Or{
- squirrel.Like{"usr.username": qs},
- squirrel.Like{"usr.handle": qs},
-
- // do a lookup on a potentially masked fields
- // this should be filtered out in the check function
- squirrel.Like{"usr.email": qs},
- squirrel.Like{"usr.name": qs},
- })
- }
-
- if f.Email != "" {
- query = query.Where(squirrel.Eq{"usr.email": f.Email})
- }
-
- if f.Username != "" {
- query = query.Where(squirrel.Eq{"usr.username": f.Username})
- }
-
- if f.Handle != "" {
- query = query.Where(squirrel.Eq{"usr.handle": f.Handle})
- }
-
- if !f.AllKinds {
- // When not explicitly requested to search all kids of users,
- // always limit to one kind
- query = query.Where(squirrel.Eq{"usr.kind": f.Kind})
- }
-
- return
-}
-
-func (s Store) CountUsers(ctx context.Context, f types.UserFilter) (uint, error) {
- if q, err := s.convertUserFilter(f); err != nil {
- return 0, fmt.Errorf("could not count users: %w", err)
- } else {
- return Count(ctx, s.db, q)
- }
-}
-
-func (s Store) UserMetrics(ctx context.Context) (*types.UserMetrics, error) {
- var (
- counters = squirrel.
- Select(
- "COUNT(*) as total",
- "SUM(CASE WHEN deleted_at IS NULL THEN 0 ELSE 1 END) as deleted",
- "SUM(CASE WHEN suspended_at IS NULL THEN 0 ELSE 1 END) as suspended",
- "SUM(CASE WHEN deleted_at IS NULL AND suspended_at IS NULL THEN 1 ELSE 0 END) as valid",
- ).
- PlaceholderFormat(s.config.PlaceholderFormat).
- From(s.userTable("u")).
- Where(squirrel.Eq{"kind": ""})
-
- row, err = s.QueryRow(ctx, counters)
- rval = &types.UserMetrics{}
- )
-
- if err != nil {
- return nil, err
- }
-
- err = row.Scan(&rval.Total, &rval.Deleted, &rval.Suspended, &rval.Valid)
- if err != nil {
- return nil, err
- }
-
- // Fetch daily metrics for created, updated, deleted and suspended users
- err = s.multiDailyMetrics(
- ctx,
- squirrel.
- Select().
- PlaceholderFormat(s.config.PlaceholderFormat).
- From(s.userTable("u")).
- Where(squirrel.Eq{"kind": ""}),
- []string{
- "created_at",
- "updated_at",
- "deleted_at",
- "suspended_at",
- },
- &rval.DailyCreated,
- &rval.DailyUpdated,
- &rval.DailyDeleted,
- &rval.DailySuspended,
- )
-
- if err != nil {
- return nil, err
- }
-
- return rval, nil
-}
diff --git a/store/reminders.gen.go b/store/reminders.gen.go
deleted file mode 100644
index d465afb7f..000000000
--- a/store/reminders.gen.go
+++ /dev/null
@@ -1,77 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/reminders.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Reminders interface {
- SearchReminders(ctx context.Context, f types.ReminderFilter) (types.ReminderSet, types.ReminderFilter, error)
- LookupReminderByID(ctx context.Context, id uint64) (*types.Reminder, error)
-
- CreateReminder(ctx context.Context, rr ...*types.Reminder) error
-
- UpdateReminder(ctx context.Context, rr ...*types.Reminder) error
-
- UpsertReminder(ctx context.Context, rr ...*types.Reminder) error
-
- DeleteReminder(ctx context.Context, rr ...*types.Reminder) error
- DeleteReminderByID(ctx context.Context, ID uint64) error
-
- TruncateReminders(ctx context.Context) error
- }
-)
-
-var _ *types.Reminder
-var _ context.Context
-
-// SearchReminders returns all matching Reminders from store
-func SearchReminders(ctx context.Context, s Reminders, f types.ReminderFilter) (types.ReminderSet, types.ReminderFilter, error) {
- return s.SearchReminders(ctx, f)
-}
-
-// LookupReminderByID searches for reminder by its ID
-//
-// It returns reminder even if deleted or suspended
-func LookupReminderByID(ctx context.Context, s Reminders, id uint64) (*types.Reminder, error) {
- return s.LookupReminderByID(ctx, id)
-}
-
-// CreateReminder creates one or more Reminders in store
-func CreateReminder(ctx context.Context, s Reminders, rr ...*types.Reminder) error {
- return s.CreateReminder(ctx, rr...)
-}
-
-// UpdateReminder updates one or more (existing) Reminders in store
-func UpdateReminder(ctx context.Context, s Reminders, rr ...*types.Reminder) error {
- return s.UpdateReminder(ctx, rr...)
-}
-
-// UpsertReminder creates new or updates existing one or more Reminders in store
-func UpsertReminder(ctx context.Context, s Reminders, rr ...*types.Reminder) error {
- return s.UpsertReminder(ctx, rr...)
-}
-
-// DeleteReminder Deletes one or more Reminders from store
-func DeleteReminder(ctx context.Context, s Reminders, rr ...*types.Reminder) error {
- return s.DeleteReminder(ctx, rr...)
-}
-
-// DeleteReminderByID Deletes Reminder from store
-func DeleteReminderByID(ctx context.Context, s Reminders, ID uint64) error {
- return s.DeleteReminderByID(ctx, ID)
-}
-
-// TruncateReminders Deletes all Reminders from store
-func TruncateReminders(ctx context.Context, s Reminders) error {
- return s.TruncateReminders(ctx)
-}
diff --git a/store/reminders.yaml b/store/reminders.yaml
deleted file mode 100644
index 75a0d0ea1..000000000
--- a/store/reminders.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Resource }
- - { field: Payload }
- - { field: SnoozeCount }
- - { field: AssignedTo }
- - { field: AssignedBy }
- - { field: AssignedAt }
- - { field: DismissedBy }
- - { field: DismissedAt }
- - { field: RemindAt, sortable: true }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for reminder by its ID
-
- It returns reminder even if deleted or suspended
-
-rdbms:
- alias: rmd
- table: reminders
- customFilterConverter: true
diff --git a/store/reports.gen.go b/store/reports.gen.go
deleted file mode 100644
index f56b161ca..000000000
--- a/store/reports.gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/reports.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Reports interface {
- SearchReports(ctx context.Context, f types.ReportFilter) (types.ReportSet, types.ReportFilter, error)
- LookupReportByID(ctx context.Context, id uint64) (*types.Report, error)
- LookupReportByHandle(ctx context.Context, handle string) (*types.Report, error)
-
- CreateReport(ctx context.Context, rr ...*types.Report) error
-
- UpdateReport(ctx context.Context, rr ...*types.Report) error
-
- UpsertReport(ctx context.Context, rr ...*types.Report) error
-
- DeleteReport(ctx context.Context, rr ...*types.Report) error
- DeleteReportByID(ctx context.Context, ID uint64) error
-
- TruncateReports(ctx context.Context) error
- }
-)
-
-var _ *types.Report
-var _ context.Context
-
-// SearchReports returns all matching Reports from store
-func SearchReports(ctx context.Context, s Reports, f types.ReportFilter) (types.ReportSet, types.ReportFilter, error) {
- return s.SearchReports(ctx, f)
-}
-
-// LookupReportByID searches for report by ID
-//
-// It returns report even if deleted
-func LookupReportByID(ctx context.Context, s Reports, id uint64) (*types.Report, error) {
- return s.LookupReportByID(ctx, id)
-}
-
-// LookupReportByHandle searches for report by Handle
-//
-// It returns report even if deleted
-func LookupReportByHandle(ctx context.Context, s Reports, handle string) (*types.Report, error) {
- return s.LookupReportByHandle(ctx, handle)
-}
-
-// CreateReport creates one or more Reports in store
-func CreateReport(ctx context.Context, s Reports, rr ...*types.Report) error {
- return s.CreateReport(ctx, rr...)
-}
-
-// UpdateReport updates one or more (existing) Reports in store
-func UpdateReport(ctx context.Context, s Reports, rr ...*types.Report) error {
- return s.UpdateReport(ctx, rr...)
-}
-
-// UpsertReport creates new or updates existing one or more Reports in store
-func UpsertReport(ctx context.Context, s Reports, rr ...*types.Report) error {
- return s.UpsertReport(ctx, rr...)
-}
-
-// DeleteReport Deletes one or more Reports from store
-func DeleteReport(ctx context.Context, s Reports, rr ...*types.Report) error {
- return s.DeleteReport(ctx, rr...)
-}
-
-// DeleteReportByID Deletes Report from store
-func DeleteReportByID(ctx context.Context, s Reports, ID uint64) error {
- return s.DeleteReportByID(ctx, ID)
-}
-
-// TruncateReports Deletes all Reports from store
-func TruncateReports(ctx context.Context, s Reports) error {
- return s.TruncateReports(ctx)
-}
diff --git a/store/reports.yaml b/store/reports.yaml
deleted file mode 100644
index 2b6f0aace..000000000
--- a/store/reports.yaml
+++ /dev/null
@@ -1,37 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Handle, sortable: true }
- - { field: Meta, type: '*ReportMeta' }
- - { field: Scenarios, type: 'ReportScenarioSet' }
- - { field: Sources, type: 'ReportDataSourceSet' }
- - { field: Blocks, type: 'ReportBlockSet' }
- - { field: OwnedBy }
- - { field: CreatedBy }
- - { field: UpdatedBy }
- - { field: DeletedBy }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for report by ID
-
- It returns report even if deleted
-
- - fields: [ Handle ]
- uniqueConstraintCheck: true
- filter: { DeletedAt: nil }
- description: |-
- searches for report by Handle
-
- It returns report even if deleted
-
-rdbms:
- alias: rp
- table: reports
- customFilterConverter: true
diff --git a/store/resource_activity_log.gen.go b/store/resource_activity_log.gen.go
deleted file mode 100644
index b1a1e634e..000000000
--- a/store/resource_activity_log.gen.go
+++ /dev/null
@@ -1,76 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/resource_activity_log.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/pkg/discovery/types"
-)
-
-type (
- ResourceActivityLogs interface {
- SearchResourceActivityLogs(ctx context.Context, f types.ResourceActivityFilter) (types.ResourceActivitySet, types.ResourceActivityFilter, error)
- LookupResourceActivityLogByID(ctx context.Context, id uint64) (*types.ResourceActivity, error)
-
- CreateResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) error
-
- UpdateResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) error
-
- UpsertResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) error
-
- DeleteResourceActivityLog(ctx context.Context, rr ...*types.ResourceActivity) error
- DeleteResourceActivityLogByID(ctx context.Context, ID uint64) error
-
- TruncateResourceActivityLogs(ctx context.Context) error
- }
-)
-
-var _ *types.ResourceActivity
-var _ context.Context
-
-// SearchResourceActivityLogs returns all matching ResourceActivityLogs from store
-func SearchResourceActivityLogs(ctx context.Context, s ResourceActivityLogs, f types.ResourceActivityFilter) (types.ResourceActivitySet, types.ResourceActivityFilter, error) {
- return s.SearchResourceActivityLogs(ctx, f)
-}
-
-// LookupResourceActivityLogByID searches for corteza resource activity by ID
-// It returns corteza resource activity even if deleted
-func LookupResourceActivityLogByID(ctx context.Context, s ResourceActivityLogs, id uint64) (*types.ResourceActivity, error) {
- return s.LookupResourceActivityLogByID(ctx, id)
-}
-
-// CreateResourceActivityLog creates one or more ResourceActivityLogs in store
-func CreateResourceActivityLog(ctx context.Context, s ResourceActivityLogs, rr ...*types.ResourceActivity) error {
- return s.CreateResourceActivityLog(ctx, rr...)
-}
-
-// UpdateResourceActivityLog updates one or more (existing) ResourceActivityLogs in store
-func UpdateResourceActivityLog(ctx context.Context, s ResourceActivityLogs, rr ...*types.ResourceActivity) error {
- return s.UpdateResourceActivityLog(ctx, rr...)
-}
-
-// UpsertResourceActivityLog creates new or updates existing one or more ResourceActivityLogs in store
-func UpsertResourceActivityLog(ctx context.Context, s ResourceActivityLogs, rr ...*types.ResourceActivity) error {
- return s.UpsertResourceActivityLog(ctx, rr...)
-}
-
-// DeleteResourceActivityLog Deletes one or more ResourceActivityLogs from store
-func DeleteResourceActivityLog(ctx context.Context, s ResourceActivityLogs, rr ...*types.ResourceActivity) error {
- return s.DeleteResourceActivityLog(ctx, rr...)
-}
-
-// DeleteResourceActivityLogByID Deletes ResourceActivityLog from store
-func DeleteResourceActivityLogByID(ctx context.Context, s ResourceActivityLogs, ID uint64) error {
- return s.DeleteResourceActivityLogByID(ctx, ID)
-}
-
-// TruncateResourceActivityLogs Deletes all ResourceActivityLogs from store
-func TruncateResourceActivityLogs(ctx context.Context, s ResourceActivityLogs) error {
- return s.TruncateResourceActivityLogs(ctx)
-}
diff --git a/store/resource_activity_log.yaml b/store/resource_activity_log.yaml
deleted file mode 100644
index 25154f20b..000000000
--- a/store/resource_activity_log.yaml
+++ /dev/null
@@ -1,48 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/pkg/discovery/types
-
-types:
- type: types.ResourceActivity
- filterType: types.ResourceActivityFilter
-
-fields:
- - { field: ID }
- - { field: ResourceID }
- - { field: ResourceType }
- - { field: ResourceAction }
- - { field: Timestamp, type: "time.Time" }
- - { field: Meta, type: "types.JSONText" }
-
-lookups:
- - fields: [ ID ]
- export: true
- description: |-
- searches for corteza resource activity by ID
- It returns corteza resource activity even if deleted
-
-search:
- enableFilterCheckFunction: false
-
-rdbms:
- alias: ral
- table: resource_activity_log
- customFilterConverter: true
- mapFields:
- Timestamp: { column: ts }
- Meta: { column: meta }
-
-create:
- export: true
-
-update:
- export: true
-
-upsert:
- export: true
-
-delete:
- export: true
-
-truncate:
- export: true
-
diff --git a/store/resource_translation.gen.go b/store/resource_translation.gen.go
deleted file mode 100644
index 567f9ea00..000000000
--- a/store/resource_translation.gen.go
+++ /dev/null
@@ -1,87 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/resource_translation.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/pkg/locale"
- "github.com/cortezaproject/corteza-server/system/types"
- "golang.org/x/text/language"
-)
-
-type (
- ResourceTranslations interface {
- SearchResourceTranslations(ctx context.Context, f types.ResourceTranslationFilter) (types.ResourceTranslationSet, types.ResourceTranslationFilter, error)
- LookupResourceTranslationByID(ctx context.Context, id uint64) (*types.ResourceTranslation, error)
-
- CreateResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) error
-
- UpdateResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) error
-
- UpsertResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) error
-
- DeleteResourceTranslation(ctx context.Context, rr ...*types.ResourceTranslation) error
- DeleteResourceTranslationByID(ctx context.Context, ID uint64) error
-
- TruncateResourceTranslations(ctx context.Context) error
-
- // Additional custom functions
-
- // TransformResource (custom function)
- TransformResource(ctx context.Context, _lang language.Tag) (map[string]map[string]*locale.ResourceTranslation, error)
- }
-)
-
-var _ *types.ResourceTranslation
-var _ context.Context
-
-// SearchResourceTranslations returns all matching ResourceTranslations from store
-func SearchResourceTranslations(ctx context.Context, s ResourceTranslations, f types.ResourceTranslationFilter) (types.ResourceTranslationSet, types.ResourceTranslationFilter, error) {
- return s.SearchResourceTranslations(ctx, f)
-}
-
-// LookupResourceTranslationByID searches for resource translation by ID
-// It also returns deleted resource translations.
-func LookupResourceTranslationByID(ctx context.Context, s ResourceTranslations, id uint64) (*types.ResourceTranslation, error) {
- return s.LookupResourceTranslationByID(ctx, id)
-}
-
-// CreateResourceTranslation creates one or more ResourceTranslations in store
-func CreateResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*types.ResourceTranslation) error {
- return s.CreateResourceTranslation(ctx, rr...)
-}
-
-// UpdateResourceTranslation updates one or more (existing) ResourceTranslations in store
-func UpdateResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*types.ResourceTranslation) error {
- return s.UpdateResourceTranslation(ctx, rr...)
-}
-
-// UpsertResourceTranslation creates new or updates existing one or more ResourceTranslations in store
-func UpsertResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*types.ResourceTranslation) error {
- return s.UpsertResourceTranslation(ctx, rr...)
-}
-
-// DeleteResourceTranslation Deletes one or more ResourceTranslations from store
-func DeleteResourceTranslation(ctx context.Context, s ResourceTranslations, rr ...*types.ResourceTranslation) error {
- return s.DeleteResourceTranslation(ctx, rr...)
-}
-
-// DeleteResourceTranslationByID Deletes ResourceTranslation from store
-func DeleteResourceTranslationByID(ctx context.Context, s ResourceTranslations, ID uint64) error {
- return s.DeleteResourceTranslationByID(ctx, ID)
-}
-
-// TruncateResourceTranslations Deletes all ResourceTranslations from store
-func TruncateResourceTranslations(ctx context.Context, s ResourceTranslations) error {
- return s.TruncateResourceTranslations(ctx)
-}
-
-func TransformResource(ctx context.Context, s ResourceTranslations, _lang language.Tag) (map[string]map[string]*locale.ResourceTranslation, error) {
- return s.TransformResource(ctx, _lang)
-}
diff --git a/store/resource_translation.yaml b/store/resource_translation.yaml
deleted file mode 100644
index 78a9b146f..000000000
--- a/store/resource_translation.yaml
+++ /dev/null
@@ -1,50 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-types:
- type: types.ResourceTranslation
-
-fields:
- - { field: ID }
-
- - { field: Lang }
- - { field: Resource }
- - { field: K }
- - { field: Message }
-
- - { field: OwnedBy, sortable: true }
- - { field: CreatedBy, sortable: true }
- - { field: UpdatedBy, sortable: true }
- - { field: DeletedBy, sortable: true }
-
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-rdbms:
- alias: rt
- table: resource_translations
- customFilterConverter: true
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for resource translation by ID
- It also returns deleted resource translations.
-
-functions:
- - name: TransformResource
- import:
- - golang.org/x/text/language
- - github.com/cortezaproject/corteza-server/pkg/locale
- return: [ "map[string]map[string]*locale.ResourceTranslation", error ]
- arguments:
- - { name: lang, type: "language.Tag" }
-
-search:
- enablePaging: true
- enableSorting: true
- enableFilterCheckFunction: false
-
-upsert:
- enable: true
diff --git a/store/role_members.gen.go b/store/role_members.gen.go
deleted file mode 100644
index 555b931ab..000000000
--- a/store/role_members.gen.go
+++ /dev/null
@@ -1,78 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/role_members.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- RoleMembers interface {
- SearchRoleMembers(ctx context.Context, f types.RoleMemberFilter) (types.RoleMemberSet, types.RoleMemberFilter, error)
-
- CreateRoleMember(ctx context.Context, rr ...*types.RoleMember) error
-
- UpdateRoleMember(ctx context.Context, rr ...*types.RoleMember) error
-
- UpsertRoleMember(ctx context.Context, rr ...*types.RoleMember) error
-
- DeleteRoleMember(ctx context.Context, rr ...*types.RoleMember) error
- DeleteRoleMemberByUserIDRoleID(ctx context.Context, userID uint64, roleID uint64) error
-
- TruncateRoleMembers(ctx context.Context) error
-
- // Additional custom functions
-
- // TransferRoleMembers (custom function)
- TransferRoleMembers(ctx context.Context, _srcRole uint64, _dstRole uint64) error
- }
-)
-
-var _ *types.RoleMember
-var _ context.Context
-
-// SearchRoleMembers returns all matching RoleMembers from store
-func SearchRoleMembers(ctx context.Context, s RoleMembers, f types.RoleMemberFilter) (types.RoleMemberSet, types.RoleMemberFilter, error) {
- return s.SearchRoleMembers(ctx, f)
-}
-
-// CreateRoleMember creates one or more RoleMembers in store
-func CreateRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
- return s.CreateRoleMember(ctx, rr...)
-}
-
-// UpdateRoleMember updates one or more (existing) RoleMembers in store
-func UpdateRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
- return s.UpdateRoleMember(ctx, rr...)
-}
-
-// UpsertRoleMember creates new or updates existing one or more RoleMembers in store
-func UpsertRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
- return s.UpsertRoleMember(ctx, rr...)
-}
-
-// DeleteRoleMember Deletes one or more RoleMembers from store
-func DeleteRoleMember(ctx context.Context, s RoleMembers, rr ...*types.RoleMember) error {
- return s.DeleteRoleMember(ctx, rr...)
-}
-
-// DeleteRoleMemberByUserIDRoleID Deletes RoleMember from store
-func DeleteRoleMemberByUserIDRoleID(ctx context.Context, s RoleMembers, userID uint64, roleID uint64) error {
- return s.DeleteRoleMemberByUserIDRoleID(ctx, userID, roleID)
-}
-
-// TruncateRoleMembers Deletes all RoleMembers from store
-func TruncateRoleMembers(ctx context.Context, s RoleMembers) error {
- return s.TruncateRoleMembers(ctx)
-}
-
-func TransferRoleMembers(ctx context.Context, s RoleMembers, _srcRole uint64, _dstRole uint64) error {
- return s.TransferRoleMembers(ctx, _srcRole, _dstRole)
-}
diff --git a/store/role_members.yaml b/store/role_members.yaml
deleted file mode 100644
index b2fc2a675..000000000
--- a/store/role_members.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: UserID, isPrimaryKey: true }
- - { field: RoleID, isPrimaryKey: true }
-
-functions:
- - name: TransferRoleMembers
- return: [ error ]
- arguments:
- - { name: srcRole, type: uint64 }
- - { name: dstRole, type: uint64 }
-
-
-search:
- enableSorting: false
- enablePaging: false
- enableFilterCheckFunction: false
-
-rdbms:
- alias: rm
- table: role_members
- customFilterConverter: true
-
diff --git a/store/roles.gen.go b/store/roles.gen.go
deleted file mode 100644
index 699aa9768..000000000
--- a/store/roles.gen.go
+++ /dev/null
@@ -1,102 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/roles.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Roles interface {
- SearchRoles(ctx context.Context, f types.RoleFilter) (types.RoleSet, types.RoleFilter, error)
- LookupRoleByID(ctx context.Context, id uint64) (*types.Role, error)
- LookupRoleByHandle(ctx context.Context, handle string) (*types.Role, error)
- LookupRoleByName(ctx context.Context, name string) (*types.Role, error)
-
- CreateRole(ctx context.Context, rr ...*types.Role) error
-
- UpdateRole(ctx context.Context, rr ...*types.Role) error
-
- UpsertRole(ctx context.Context, rr ...*types.Role) error
-
- DeleteRole(ctx context.Context, rr ...*types.Role) error
- DeleteRoleByID(ctx context.Context, ID uint64) error
-
- TruncateRoles(ctx context.Context) error
-
- // Additional custom functions
-
- // RoleMetrics (custom function)
- RoleMetrics(ctx context.Context) (*types.RoleMetrics, error)
- }
-)
-
-var _ *types.Role
-var _ context.Context
-
-// SearchRoles returns all matching Roles from store
-func SearchRoles(ctx context.Context, s Roles, f types.RoleFilter) (types.RoleSet, types.RoleFilter, error) {
- return s.SearchRoles(ctx, f)
-}
-
-// LookupRoleByID searches for role by ID
-//
-// It returns role even if deleted or suspended
-func LookupRoleByID(ctx context.Context, s Roles, id uint64) (*types.Role, error) {
- return s.LookupRoleByID(ctx, id)
-}
-
-// LookupRoleByHandle searches for role by its handle
-//
-// It returns only valid roles (not deleted, not archived)
-func LookupRoleByHandle(ctx context.Context, s Roles, handle string) (*types.Role, error) {
- return s.LookupRoleByHandle(ctx, handle)
-}
-
-// LookupRoleByName searches for role by its name
-//
-// It returns only valid roles (not deleted, not archived)
-func LookupRoleByName(ctx context.Context, s Roles, name string) (*types.Role, error) {
- return s.LookupRoleByName(ctx, name)
-}
-
-// CreateRole creates one or more Roles in store
-func CreateRole(ctx context.Context, s Roles, rr ...*types.Role) error {
- return s.CreateRole(ctx, rr...)
-}
-
-// UpdateRole updates one or more (existing) Roles in store
-func UpdateRole(ctx context.Context, s Roles, rr ...*types.Role) error {
- return s.UpdateRole(ctx, rr...)
-}
-
-// UpsertRole creates new or updates existing one or more Roles in store
-func UpsertRole(ctx context.Context, s Roles, rr ...*types.Role) error {
- return s.UpsertRole(ctx, rr...)
-}
-
-// DeleteRole Deletes one or more Roles from store
-func DeleteRole(ctx context.Context, s Roles, rr ...*types.Role) error {
- return s.DeleteRole(ctx, rr...)
-}
-
-// DeleteRoleByID Deletes Role from store
-func DeleteRoleByID(ctx context.Context, s Roles, ID uint64) error {
- return s.DeleteRoleByID(ctx, ID)
-}
-
-// TruncateRoles Deletes all Roles from store
-func TruncateRoles(ctx context.Context, s Roles) error {
- return s.TruncateRoles(ctx)
-}
-
-func RoleMetrics(ctx context.Context, s Roles) (*types.RoleMetrics, error) {
- return s.RoleMetrics(ctx)
-}
diff --git a/store/roles.yaml b/store/roles.yaml
deleted file mode 100644
index fd58d783f..000000000
--- a/store/roles.yaml
+++ /dev/null
@@ -1,41 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Name, sortable: true }
- - { field: Handle, sortable: true, unique: true, lookupFilterPreprocessor: lower }
- - { field: Meta, type: '*AuthClientMeta' }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: ArchivedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for role by ID
-
- It returns role even if deleted or suspended
- - fields: [ Handle ]
- uniqueConstraintCheck: true
- filter: { DeletedAt: nil, ArchivedAt: nil }
- description: |-
- searches for role by its handle
-
- It returns only valid roles (not deleted, not archived)
- - fields: [ Name ]
- filter: { DeletedAt: nil, ArchivedAt: nil }
- description: |-
- searches for role by its name
-
- It returns only valid roles (not deleted, not archived)
-
-functions:
- - name: RoleMetrics
- return: [ "*types.RoleMetrics", "error" ]
-
-rdbms:
- alias: rl
- table: roles
- customFilterConverter: true
diff --git a/store/settings.gen.go b/store/settings.gen.go
deleted file mode 100644
index 0c3d31acc..000000000
--- a/store/settings.gen.go
+++ /dev/null
@@ -1,75 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/settings.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Settings interface {
- SearchSettings(ctx context.Context, f types.SettingsFilter) (types.SettingValueSet, types.SettingsFilter, error)
- LookupSettingByNameOwnedBy(ctx context.Context, name string, owned_by uint64) (*types.SettingValue, error)
-
- CreateSetting(ctx context.Context, rr ...*types.SettingValue) error
-
- UpdateSetting(ctx context.Context, rr ...*types.SettingValue) error
-
- UpsertSetting(ctx context.Context, rr ...*types.SettingValue) error
-
- DeleteSetting(ctx context.Context, rr ...*types.SettingValue) error
- DeleteSettingByNameOwnedBy(ctx context.Context, name string, ownedBy uint64) error
-
- TruncateSettings(ctx context.Context) error
- }
-)
-
-var _ *types.SettingValue
-var _ context.Context
-
-// SearchSettings returns all matching Settings from store
-func SearchSettings(ctx context.Context, s Settings, f types.SettingsFilter) (types.SettingValueSet, types.SettingsFilter, error) {
- return s.SearchSettings(ctx, f)
-}
-
-// LookupSettingByNameOwnedBy searches for settings by name and owner
-func LookupSettingByNameOwnedBy(ctx context.Context, s Settings, name string, owned_by uint64) (*types.SettingValue, error) {
- return s.LookupSettingByNameOwnedBy(ctx, name, owned_by)
-}
-
-// CreateSetting creates one or more Settings in store
-func CreateSetting(ctx context.Context, s Settings, rr ...*types.SettingValue) error {
- return s.CreateSetting(ctx, rr...)
-}
-
-// UpdateSetting updates one or more (existing) Settings in store
-func UpdateSetting(ctx context.Context, s Settings, rr ...*types.SettingValue) error {
- return s.UpdateSetting(ctx, rr...)
-}
-
-// UpsertSetting creates new or updates existing one or more Settings in store
-func UpsertSetting(ctx context.Context, s Settings, rr ...*types.SettingValue) error {
- return s.UpsertSetting(ctx, rr...)
-}
-
-// DeleteSetting Deletes one or more Settings from store
-func DeleteSetting(ctx context.Context, s Settings, rr ...*types.SettingValue) error {
- return s.DeleteSetting(ctx, rr...)
-}
-
-// DeleteSettingByNameOwnedBy Deletes Setting from store
-func DeleteSettingByNameOwnedBy(ctx context.Context, s Settings, name string, ownedBy uint64) error {
- return s.DeleteSettingByNameOwnedBy(ctx, name, ownedBy)
-}
-
-// TruncateSettings Deletes all Settings from store
-func TruncateSettings(ctx context.Context, s Settings) error {
- return s.TruncateSettings(ctx)
-}
diff --git a/store/settings.yaml b/store/settings.yaml
deleted file mode 100644
index 6d97da901..000000000
--- a/store/settings.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-types:
- type: types.SettingValue
- filterType: types.SettingsFilter
-
-fields:
- - { field: Name, isPrimaryKey: true, lookupFilterPreprocessor: lower }
- - { field: OwnedBy, isPrimaryKey: true }
- - { field: Value }
- - { field: UpdatedBy }
- - { field: UpdatedAt }
-
-lookups:
- - fields: [ Name, OwnedBy ]
- description: |-
- searches for settings by name and owner
-
-search:
- enablePaging: false
- enableSorting: false
-
-rdbms:
- alias: st
- table: settings
- customFilterConverter: true
- mapFields:
- OwnedBy: { column: rel_owner }
-
diff --git a/store/sqlite3/encoder.go b/store/sqlite3/encoder.go
deleted file mode 100644
index 46228e68a..000000000
--- a/store/sqlite3/encoder.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package sqlite3
-
-import "github.com/cortezaproject/corteza-server/pkg/ql"
-
-type (
- // QueryEncoder provides query parts encoding rules for SQLite
- // see ql.QueryEncoder for mor info
- QueryEncoder struct{}
-)
-
-var _ ql.Encoder = &QueryEncoder{}
-
-func (QueryEncoder) CaseInsensitiveLike(neg bool) string {
- if neg {
- return "COLLATE utf8_unicode_ci NOT LIKE"
- } else {
- return "COLLATE utf8_unicode_ci LIKE"
- }
-}
diff --git a/store/sqlite3/sql_functions.go b/store/sqlite3/sql_functions.go
deleted file mode 100644
index 8ba49ac92..000000000
--- a/store/sqlite3/sql_functions.go
+++ /dev/null
@@ -1,182 +0,0 @@
-package sqlite3
-
-import (
- "fmt"
- "regexp"
- "strings"
-
- "github.com/cortezaproject/corteza-server/pkg/ql"
- "github.com/cortezaproject/corteza-server/pkg/qlng"
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-var (
- sqlExprRegistry = map[string]rdbms.HandlerSig{
- // functions
- // - filtering
- "now": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 0 {
- err = fmt.Errorf("expecting 0 arguments, got %d", len(aa))
- return
- }
-
- out = "DATE('now')"
- return
- },
- "quarter": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("(CAST(STRFTIME('%%m', %s) AS INTEGER) + 2) / 3", aa[0].S)
- args = aa[0].Args
- return
- },
- "year": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("STRFTIME('%%Y', %s)", aa[0].S)
- args = aa[0].Args
- return
- },
- "month": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("STRFTIME('%%m', %s)", aa[0].S)
- args = aa[0].Args
- return
- },
- "date": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 arguments, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("STRFTIME('%%d', %s)", aa[0].S)
- args = aa[0].Args
- return
- },
-
- // - strings
- "concat": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- params := make([]string, len(aa))
- for i, a := range aa {
- params[i] = a.S
- args = append(args, a.Args...)
- }
-
- out = fmt.Sprintf("(%s)", strings.Join(params, "||"))
- return
- },
-
- // - typecast
- "float": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 argument, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("CAST(%s AS FLOAT)", aa[0].S)
- args = aa[0].Args
- return
- },
- "string": func(aa ...rdbms.FormattedASTArgs) (out string, args []interface{}, selfEnclosed bool, err error) {
- selfEnclosed = true
-
- if len(aa) != 1 {
- err = fmt.Errorf("expecting 1 argument, got %d", len(aa))
- return
- }
-
- out = fmt.Sprintf("CAST(%s AS TEXT)", aa[0].S)
- args = aa[0].Args
- return
- },
- }
-
- supportedSubstitutions = map[string]bool{
- "d": true,
- "H": true,
- "j": true,
- "m": true,
- "M": true,
- "S": true,
- "w": true,
- "W": true,
- "Y": true,
- "%": true,
- }
-)
-
-func sqlASTFormatter(n *qlng.ASTNode) rdbms.HandlerSig {
- return sqlExprRegistry[n.Ref]
-}
-
-func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) {
- switch strings.ToUpper(f.Name) {
- case "QUARTER":
- return ql.MakeFormattedNode("(CAST(STRFTIME('%%m', %s) AS INTEGER) + 2) / 3", f.Arguments...), nil
- case "YEAR":
- return ql.MakeFormattedNode("STRFTIME('%%Y', %s)", f.Arguments...), nil
- case "NOW":
- return ql.MakeFormattedNode("DATE('now')", f.Arguments...), nil
- case "TIMESTAMP", "DATETIME":
- return ql.MakeFormattedNode("DATETIME(%s)", f.Arguments...), nil
- case "DATE_FORMAT":
- if len(f.Arguments) != 2 {
- return nil, fmt.Errorf("expecting exactly two arguments for DATE_FORMAT function")
- }
- format := f.Arguments[1]
- col := f.Arguments[0]
-
- err := supportedDateFormatParams(format)
- if err != nil {
- return nil, err
- }
-
- return ql.MakeReplacedFormattedNode("STRFTIME(%s, %s)", translateDateFormatParams, format, col), nil
- case "DATE":
- // need to convert back to datetime so it can be converted to time.Time
- return ql.MakeFormattedNode("STRFTIME('%%Y-%%m-%%dT00:00:00Z', %s)", f.Arguments...), nil
- case "DATE_ADD", "DATE_SUB", "STD":
- return nil, fmt.Errorf("%q function is currently unsupported in SQLite store backend", f.Name)
- }
-
- return f, nil
-}
-
-func supportedDateFormatParams(fmtNode ql.ASTNode) error {
- format := translateDateFormatParams(fmtNode.String())
-
- r := regexp.MustCompile(`%(?P.)`)
-
- for _, m := range r.FindAllStringSubmatch(format, -1) {
- if len(m) == 0 {
- continue
- }
-
- if _, ok := supportedSubstitutions[m[1]]; !ok {
- return fmt.Errorf("format substitution not supported: %%%s", m[1])
- }
- }
-
- return nil
-}
-
-func translateDateFormatParams(format string) string {
- return strings.NewReplacer(
- `%i`, `%M`,
- `%U`, `%W`,
- ).Replace(format)
-}
diff --git a/store/sqlite3/sql_typecasters.go b/store/sqlite3/sql_typecasters.go
deleted file mode 100644
index 46545525a..000000000
--- a/store/sqlite3/sql_typecasters.go
+++ /dev/null
@@ -1,38 +0,0 @@
-package sqlite3
-
-import (
- "fmt"
-
- "github.com/cortezaproject/corteza-server/store/rdbms"
-)
-
-// fieldToColumnTypeCaster handles special ComposeModule field query representations
-// @todo Not as elegant as it should be but it'll do the trick until the #2 store iteration
-//
-// Return parameters:
-// * full cast: query column + datatype cast
-// * field cast tpl: fmt template to get query column
-// * type cast tpl: fmt template to cast the compared to value
-func fieldToColumnTypeCaster(field rdbms.ModuleFieldTypeDetector, ident string) (string, string, string, error) {
- fcp := "rv_%s.value"
- fcpRef := "rv_%s.ref"
-
- switch true {
- case field.IsBoolean():
- tcp := "(%s NOT IN ('', '0', 'false', 'f', 'FALSE', 'F', false))"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsNumeric():
- tcp := "CAST(%s AS SIGNED)"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- case field.IsRef():
- tcp := "%s"
- fc := fmt.Sprintf(fcpRef, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
- }
-
- tcp := "%s"
- fc := fmt.Sprintf(fcp, ident)
- return fmt.Sprintf(tcp, fc), fcp, tcp, nil
-}
diff --git a/store/store.go b/store/store.go
new file mode 100644
index 000000000..3ca604e33
--- /dev/null
+++ b/store/store.go
@@ -0,0 +1,13 @@
+package store
+
+const (
+ // TxRetryHardLimit is the absolute maximum retries we'll allow
+ TxRetryHardLimit = 100
+
+ DefaultSliceCapacity = 1000
+
+ MinEnsureFetchLimit = 10
+ MaxRefetches = 100
+
+ MaxLimit = 1000
+)
diff --git a/store/templates.gen.go b/store/templates.gen.go
deleted file mode 100644
index 3e97aeacf..000000000
--- a/store/templates.gen.go
+++ /dev/null
@@ -1,85 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/templates.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Templates interface {
- SearchTemplates(ctx context.Context, f types.TemplateFilter) (types.TemplateSet, types.TemplateFilter, error)
- LookupTemplateByID(ctx context.Context, id uint64) (*types.Template, error)
- LookupTemplateByHandle(ctx context.Context, handle string) (*types.Template, error)
-
- CreateTemplate(ctx context.Context, rr ...*types.Template) error
-
- UpdateTemplate(ctx context.Context, rr ...*types.Template) error
-
- UpsertTemplate(ctx context.Context, rr ...*types.Template) error
-
- DeleteTemplate(ctx context.Context, rr ...*types.Template) error
- DeleteTemplateByID(ctx context.Context, ID uint64) error
-
- TruncateTemplates(ctx context.Context) error
- }
-)
-
-var _ *types.Template
-var _ context.Context
-
-// SearchTemplates returns all matching Templates from store
-func SearchTemplates(ctx context.Context, s Templates, f types.TemplateFilter) (types.TemplateSet, types.TemplateFilter, error) {
- return s.SearchTemplates(ctx, f)
-}
-
-// LookupTemplateByID searches for template by ID
-//
-// It also returns deleted templates.
-func LookupTemplateByID(ctx context.Context, s Templates, id uint64) (*types.Template, error) {
- return s.LookupTemplateByID(ctx, id)
-}
-
-// LookupTemplateByHandle searches for template by the handle
-//
-// It returns only valid templates (not deleted)
-func LookupTemplateByHandle(ctx context.Context, s Templates, handle string) (*types.Template, error) {
- return s.LookupTemplateByHandle(ctx, handle)
-}
-
-// CreateTemplate creates one or more Templates in store
-func CreateTemplate(ctx context.Context, s Templates, rr ...*types.Template) error {
- return s.CreateTemplate(ctx, rr...)
-}
-
-// UpdateTemplate updates one or more (existing) Templates in store
-func UpdateTemplate(ctx context.Context, s Templates, rr ...*types.Template) error {
- return s.UpdateTemplate(ctx, rr...)
-}
-
-// UpsertTemplate creates new or updates existing one or more Templates in store
-func UpsertTemplate(ctx context.Context, s Templates, rr ...*types.Template) error {
- return s.UpsertTemplate(ctx, rr...)
-}
-
-// DeleteTemplate Deletes one or more Templates from store
-func DeleteTemplate(ctx context.Context, s Templates, rr ...*types.Template) error {
- return s.DeleteTemplate(ctx, rr...)
-}
-
-// DeleteTemplateByID Deletes Template from store
-func DeleteTemplateByID(ctx context.Context, s Templates, ID uint64) error {
- return s.DeleteTemplateByID(ctx, ID)
-}
-
-// TruncateTemplates Deletes all Templates from store
-func TruncateTemplates(ctx context.Context, s Templates) error {
- return s.TruncateTemplates(ctx)
-}
diff --git a/store/templates.yaml b/store/templates.yaml
deleted file mode 100644
index 7c3b69611..000000000
--- a/store/templates.yaml
+++ /dev/null
@@ -1,34 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Handle, sortable: true, unique: true, lookupFilterPreprocessor: lower }
- - { field: Language }
- - { field: Type }
- - { field: Partial }
- - { field: Meta, type: "*types.TemplateMeta" }
- - { field: Template }
- - { field: OwnerID }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
- - { field: LastUsedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for template by ID
-
- It also returns deleted templates.
- - fields: [ Handle ]
- filter: { DeletedAt: nil }
- uniqueConstraintCheck: true
- description: |-
- searches for template by the handle
-
- It returns only valid templates (not deleted)
-rdbms:
- alias: tpl
- table: templates
- customFilterConverter: true
diff --git a/store/tests/.gitignore b/store/tests/.gitignore
new file mode 100644
index 000000000..4c49bd78f
--- /dev/null
+++ b/store/tests/.gitignore
@@ -0,0 +1 @@
+.env
diff --git a/store/tests/actionlog_test.go b/store/tests/actionlog_test.go
index 84f290871..f92d8d747 100644
--- a/store/tests/actionlog_test.go
+++ b/store/tests/actionlog_test.go
@@ -12,7 +12,7 @@ import (
"github.com/stretchr/testify/require"
)
-func testActionlog(t *testing.T, s store.Actionlogs) {
+func testActionlogs(t *testing.T, s store.Actionlogs) {
var (
ctx = context.Background()
diff --git a/store/tests/all_test.go b/store/tests/all_test.go
new file mode 100644
index 000000000..97a92ec4e
--- /dev/null
+++ b/store/tests/all_test.go
@@ -0,0 +1,137 @@
+package tests
+
+// This file is auto-generated.
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+
+import (
+ "testing"
+
+ "github.com/cortezaproject/corteza-server/store"
+)
+
+func testAllGenerated(t *testing.T, s store.Storer) {
+
+ t.Run("actionlog", func(t *testing.T) {
+ testActionlogs(t, s)
+ })
+ t.Run("apigwFilter", func(t *testing.T) {
+ testApigwFilters(t, s)
+ })
+ t.Run("apigwRoute", func(t *testing.T) {
+ testApigwRoutes(t, s)
+ })
+ t.Run("application", func(t *testing.T) {
+ testApplications(t, s)
+ })
+ t.Run("attachment", func(t *testing.T) {
+ testAttachments(t, s)
+ })
+ t.Run("authClient", func(t *testing.T) {
+ testAuthClients(t, s)
+ })
+ t.Run("authConfirmedClient", func(t *testing.T) {
+ testAuthConfirmedClients(t, s)
+ })
+ t.Run("authOa2token", func(t *testing.T) {
+ testAuthOa2tokens(t, s)
+ })
+ t.Run("authSession", func(t *testing.T) {
+ testAuthSessions(t, s)
+ })
+ t.Run("automationSession", func(t *testing.T) {
+ testAutomationSessions(t, s)
+ })
+ t.Run("automationTrigger", func(t *testing.T) {
+ testAutomationTriggers(t, s)
+ })
+ t.Run("automationWorkflow", func(t *testing.T) {
+ testAutomationWorkflows(t, s)
+ })
+ t.Run("composeAttachment", func(t *testing.T) {
+ testComposeAttachments(t, s)
+ })
+ t.Run("composeChart", func(t *testing.T) {
+ testComposeCharts(t, s)
+ })
+ t.Run("composeModule", func(t *testing.T) {
+ testComposeModules(t, s)
+ })
+ t.Run("composeModuleField", func(t *testing.T) {
+ testComposeModuleFields(t, s)
+ })
+ t.Run("composeNamespace", func(t *testing.T) {
+ testComposeNamespaces(t, s)
+ })
+ t.Run("composePage", func(t *testing.T) {
+ testComposePages(t, s)
+ })
+ t.Run("composeRecord", func(t *testing.T) {
+ testComposeRecords(t, s)
+ })
+ t.Run("composeRecordValue", func(t *testing.T) {
+ testComposeRecordValues(t, s)
+ })
+ t.Run("credential", func(t *testing.T) {
+ testCredentials(t, s)
+ })
+ t.Run("federationExposedModule", func(t *testing.T) {
+ testFederationExposedModules(t, s)
+ })
+ t.Run("federationModuleMapping", func(t *testing.T) {
+ testFederationModuleMappings(t, s)
+ })
+ t.Run("federationNode", func(t *testing.T) {
+ testFederationNodes(t, s)
+ })
+ t.Run("federationNodeSync", func(t *testing.T) {
+ testFederationNodeSyncs(t, s)
+ })
+ t.Run("federationSharedModule", func(t *testing.T) {
+ testFederationSharedModules(t, s)
+ })
+ t.Run("flag", func(t *testing.T) {
+ testFlags(t, s)
+ })
+ t.Run("label", func(t *testing.T) {
+ testLabels(t, s)
+ })
+ t.Run("queue", func(t *testing.T) {
+ testQueues(t, s)
+ })
+ t.Run("queueMessage", func(t *testing.T) {
+ testQueueMessages(t, s)
+ })
+ t.Run("rbacRule", func(t *testing.T) {
+ testRbacRules(t, s)
+ })
+ t.Run("reminder", func(t *testing.T) {
+ testReminders(t, s)
+ })
+ t.Run("report", func(t *testing.T) {
+ testReports(t, s)
+ })
+ t.Run("resourceActivity", func(t *testing.T) {
+ testResourceActivitys(t, s)
+ })
+ t.Run("resourceTranslation", func(t *testing.T) {
+ testResourceTranslations(t, s)
+ })
+ t.Run("role", func(t *testing.T) {
+ testRoles(t, s)
+ })
+ t.Run("roleMember", func(t *testing.T) {
+ testRoleMembers(t, s)
+ })
+ t.Run("settingValue", func(t *testing.T) {
+ testSettingValues(t, s)
+ })
+ t.Run("template", func(t *testing.T) {
+ testTemplates(t, s)
+ })
+ t.Run("user", func(t *testing.T) {
+ testUsers(t, s)
+ })
+}
diff --git a/store/tests/attachments_test.go b/store/tests/attachments_test.go
index a728a9099..6c7867a4e 100644
--- a/store/tests/attachments_test.go
+++ b/store/tests/attachments_test.go
@@ -2,18 +2,19 @@ package tests
import (
"context"
+ "strings"
+ "testing"
+ "time"
+
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/pkg/rand"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/types"
_ "github.com/joho/godotenv/autoload"
"github.com/stretchr/testify/require"
- "strings"
- "testing"
- "time"
)
-func testAttachment(t *testing.T, s store.Attachments) {
+func testAttachments(t *testing.T, s store.Attachments) {
var (
ctx = context.Background()
req = require.New(t)
@@ -82,7 +83,7 @@ func testAttachment(t *testing.T, s store.Attachments) {
att.Url = "url"
req.NoError(s.UpsertAttachment(ctx, att))
-
+
upserted, err := s.LookupAttachmentByID(ctx, att.ID)
req.NoError(err)
req.Equal(att.Name, upserted.Name)
@@ -92,7 +93,7 @@ func testAttachment(t *testing.T, s store.Attachments) {
att := makeNew("upsert me", "upsert-me")
req.NoError(s.UpsertAttachment(ctx, att))
-
+
upserted, err := s.LookupAttachmentByID(ctx, att.ID)
req.NoError(err)
req.Equal(att.Name, upserted.Name)
diff --git a/store/tests/compose_record_values_test.go b/store/tests/compose_record_values_test.go
index 734959b7b..bf5f64bb5 100644
--- a/store/tests/compose_record_values_test.go
+++ b/store/tests/compose_record_values_test.go
@@ -1,8 +1,9 @@
package tests
import (
- "github.com/cortezaproject/corteza-server/store"
"testing"
+
+ "github.com/cortezaproject/corteza-server/store"
)
func testComposeRecordValues(t *testing.T, s store.ComposeRecordValues) {
diff --git a/store/tests/compose_records_test.go b/store/tests/compose_records_test.go
index 2cf46c37c..74ea9bf7d 100644
--- a/store/tests/compose_records_test.go
+++ b/store/tests/compose_records_test.go
@@ -15,6 +15,8 @@ import (
)
func testComposeRecords(t *testing.T, s store.ComposeRecords) {
+ t.Skip("temporary disabled")
+
var (
ctx = context.Background()
diff --git a/store/tests/credentials_test.go b/store/tests/credentials_test.go
index 488d940d2..c9a2a417b 100644
--- a/store/tests/credentials_test.go
+++ b/store/tests/credentials_test.go
@@ -2,6 +2,10 @@ package tests
import (
"context"
+ "strings"
+ "testing"
+ "time"
+
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/pkg/rand"
"github.com/cortezaproject/corteza-server/store"
@@ -9,18 +13,15 @@ import (
"github.com/cortezaproject/corteza-server/system/types"
_ "github.com/joho/godotenv/autoload"
"github.com/stretchr/testify/require"
- "strings"
- "testing"
- "time"
)
func testCredentials(t *testing.T, s store.Credentials) {
var (
ctx = context.Background()
- makeNew = func(nn ...string) *types.Credentials {
+ makeNew = func(nn ...string) *types.Credential {
name := strings.Join(nn, "")
- return &types.Credentials{
+ return &types.Credential{
ID: id.Next(),
OwnerID: id.Next(),
Kind: "test-kind" + name,
@@ -30,38 +31,38 @@ func testCredentials(t *testing.T, s store.Credentials) {
}
}
- truncAndCreate = func(t *testing.T) (*require.Assertions, *types.Credentials) {
+ truncAndCreate = func(t *testing.T) (*require.Assertions, *types.Credential) {
req := require.New(t)
req.NoError(s.TruncateCredentials(ctx))
credentials := makeNew()
- req.NoError(s.CreateCredentials(ctx, credentials))
+ req.NoError(s.CreateCredential(ctx, credentials))
return req, credentials
}
- truncAndFill = func(t *testing.T, l int) (*require.Assertions, types.CredentialsSet) {
+ truncAndFill = func(t *testing.T, l int) (*require.Assertions, types.CredentialSet) {
req := require.New(t)
req.NoError(s.TruncateCredentials(ctx))
- set := make([]*types.Credentials, l)
+ set := make([]*types.Credential, l)
for i := 0; i < l; i++ {
set[i] = makeNew(string(rand.Bytes(10)))
}
- req.NoError(s.CreateCredentials(ctx, set...))
+ req.NoError(s.CreateCredential(ctx, set...))
return req, set
}
)
t.Run("create", func(t *testing.T) {
req := require.New(t)
- req.NoError(s.CreateCredentials(ctx, makeNew()))
+ req.NoError(s.CreateCredential(ctx, makeNew()))
})
t.Run("lookup by ID", func(t *testing.T) {
req, crd := truncAndCreate(t)
- fetched, err := s.LookupCredentialsByID(ctx, crd.ID)
+ fetched, err := s.LookupCredentialByID(ctx, crd.ID)
req.NoError(err)
req.Equal(crd.ID, fetched.ID)
req.NotNil(fetched.CreatedAt)
@@ -72,8 +73,8 @@ func testCredentials(t *testing.T, s store.Credentials) {
t.Run("update", func(t *testing.T) {
req, crd := truncAndCreate(t)
crd.Credentials = "new-credentials"
- req.NoError(s.UpdateCredentials(ctx, crd))
- fetched, err := s.LookupCredentialsByID(ctx, crd.ID)
+ req.NoError(s.UpdateCredential(ctx, crd))
+ fetched, err := s.LookupCredentialByID(ctx, crd.ID)
req.NoError(err)
req.Equal("new-credentials", fetched.Credentials)
})
@@ -81,8 +82,8 @@ func testCredentials(t *testing.T, s store.Credentials) {
t.Run("update", func(t *testing.T) {
req, crd := truncAndCreate(t)
crd.Credentials = "new-credentials"
- req.NoError(s.UpdateCredentials(ctx, crd))
- fetched, err := s.LookupCredentialsByID(ctx, crd.ID)
+ req.NoError(s.UpdateCredential(ctx, crd))
+ fetched, err := s.LookupCredentialByID(ctx, crd.ID)
req.NoError(err)
req.Equal("new-credentials", fetched.Credentials)
})
@@ -90,16 +91,16 @@ func testCredentials(t *testing.T, s store.Credentials) {
t.Run("delete", func(t *testing.T) {
t.Run("by credentials", func(t *testing.T) {
req, crd := truncAndCreate(t)
- req.NoError(s.DeleteCredentials(ctx, crd))
- set, _, err := s.SearchCredentials(ctx, types.CredentialsFilter{OwnerID: crd.OwnerID})
+ req.NoError(s.DeleteCredential(ctx, crd))
+ set, _, err := s.SearchCredentials(ctx, types.CredentialFilter{OwnerID: crd.OwnerID})
req.NoError(err)
req.Len(set, 0)
})
t.Run("by ID", func(t *testing.T) {
req, crd := truncAndCreate(t)
- req.NoError(s.DeleteCredentialsByID(ctx, crd.ID))
- set, _, err := s.SearchCredentials(ctx, types.CredentialsFilter{OwnerID: crd.OwnerID})
+ req.NoError(s.DeleteCredentialByID(ctx, crd.ID))
+ set, _, err := s.SearchCredentials(ctx, types.CredentialFilter{OwnerID: crd.OwnerID})
req.NoError(err)
req.Len(set, 0)
})
@@ -109,7 +110,7 @@ func testCredentials(t *testing.T, s store.Credentials) {
t.Run("by owner", func(t *testing.T) {
req, prefill := truncAndFill(t, 5)
- set, _, err := s.SearchCredentials(ctx, types.CredentialsFilter{OwnerID: prefill[0].OwnerID})
+ set, _, err := s.SearchCredentials(ctx, types.CredentialFilter{OwnerID: prefill[0].OwnerID})
req.NoError(err)
req.Len(set, 1)
})
@@ -117,7 +118,7 @@ func testCredentials(t *testing.T, s store.Credentials) {
t.Run("by kind", func(t *testing.T) {
req, prefill := truncAndFill(t, 5)
- set, _, err := s.SearchCredentials(ctx, types.CredentialsFilter{Kind: prefill[0].Kind})
+ set, _, err := s.SearchCredentials(ctx, types.CredentialFilter{Kind: prefill[0].Kind})
req.NoError(err)
req.Len(set, 1)
})
@@ -130,15 +131,15 @@ func testCredentials(t *testing.T, s store.Credentials) {
// prefill[0].DeletedAt = &time
// req.NoError(s.DeleteCredentialsByID(ctx, prefill[0].ID))
- // set, _, err := s.SearchCredentials(ctx, types.CredentialsFilter{Deleted: filter.StateExcluded})
+ // set, _, err := s.SearchCredentials(ctx, types.CredentialFilter{Deleted: filter.StateExcluded})
// req.NoError(err)
// req.Len(set, 4)
- // set, _, err = s.SearchCredentials(ctx, types.CredentialsFilter{Deleted: filter.StateInclusive})
+ // set, _, err = s.SearchCredentials(ctx, types.CredentialFilter{Deleted: filter.StateInclusive})
// req.NoError(err)
// req.Len(set, 5)
- // set, _, err = s.SearchCredentials(ctx, types.CredentialsFilter{Deleted: filter.StateExclusive})
+ // set, _, err = s.SearchCredentials(ctx, types.CredentialFilter{Deleted: filter.StateExclusive})
// req.NoError(err)
// req.Len(set, 1)
// })
diff --git a/store/tests/federation_nodes_sync_test.go b/store/tests/federation_nodes_sync_test.go
index 96c10e95c..18e51d942 100644
--- a/store/tests/federation_nodes_sync_test.go
+++ b/store/tests/federation_nodes_sync_test.go
@@ -6,6 +6,6 @@ import (
"github.com/cortezaproject/corteza-server/store"
)
-func testFederationNodesSync(t *testing.T, s store.FederationNodesSyncs) {
- // @todo
+func testFederationNodeSyncs(t *testing.T, s store.FederationNodeSyncs) {
+ t.Skip("@todo")
}
diff --git a/store/tests/gen_test.go b/store/tests/gen_test.go
deleted file mode 100644
index 67b3b6134..000000000
--- a/store/tests/gen_test.go
+++ /dev/null
@@ -1,256 +0,0 @@
-package tests
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_test_all.gen.go.tpl
-// Definitions:
-// - store/actionlog.yaml
-// - store/apigw_filter.yaml
-// - store/apigw_route.yaml
-// - store/applications.yaml
-// - store/attachments.yaml
-// - store/auth_clients.yaml
-// - store/auth_confirmed_clients.yaml
-// - store/auth_oa2tokens.yaml
-// - store/auth_sessions.yaml
-// - store/automation_sessions.yaml
-// - store/automation_triggers.yaml
-// - store/automation_workflows.yaml
-// - store/compose_attachments.yaml
-// - store/compose_charts.yaml
-// - store/compose_module_fields.yaml
-// - store/compose_modules.yaml
-// - store/compose_namespaces.yaml
-// - store/compose_pages.yaml
-// - store/credentials.yaml
-// - store/federation_exposed_modules.yaml
-// - store/federation_module_mappings.yaml
-// - store/federation_nodes.yaml
-// - store/federation_nodes_sync.yaml
-// - store/federation_shared_modules.yaml
-// - store/flags.yaml
-// - store/labels.yaml
-// - store/queue.yaml
-// - store/queue_message.yaml
-// - store/rbac_rules.yaml
-// - store/reminders.yaml
-// - store/reports.yaml
-// - store/resource_activity_log.yaml
-// - store/resource_translation.yaml
-// - store/role_members.yaml
-// - store/roles.yaml
-// - store/settings.yaml
-// - store/templates.yaml
-// - store/users.yaml
-
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-//
-
-import (
- "github.com/cortezaproject/corteza-server/store"
- "testing"
-)
-
-func testAllGenerated(t *testing.T, s store.Storer) {
- // Run generated tests for Actionlog
- t.Run("Actionlog", func(t *testing.T) {
- testActionlog(t, s)
- })
-
- // Run generated tests for ApigwFilter
- t.Run("ApigwFilter", func(t *testing.T) {
- testApigwFilter(t, s)
- })
-
- // Run generated tests for ApigwRoute
- t.Run("ApigwRoute", func(t *testing.T) {
- testApigwRoute(t, s)
- })
-
- // Run generated tests for Applications
- t.Run("Applications", func(t *testing.T) {
- testApplications(t, s)
- })
-
- // Run generated tests for Attachment
- t.Run("Attachment", func(t *testing.T) {
- testAttachment(t, s)
- })
-
- // Run generated tests for AuthClients
- t.Run("AuthClients", func(t *testing.T) {
- testAuthClients(t, s)
- })
-
- // Run generated tests for AuthConfirmedClients
- t.Run("AuthConfirmedClients", func(t *testing.T) {
- testAuthConfirmedClients(t, s)
- })
-
- // Run generated tests for AuthOa2tokens
- t.Run("AuthOa2tokens", func(t *testing.T) {
- testAuthOa2tokens(t, s)
- })
-
- // Run generated tests for AuthSessions
- t.Run("AuthSessions", func(t *testing.T) {
- testAuthSessions(t, s)
- })
-
- // Run generated tests for AutomationSessions
- t.Run("AutomationSessions", func(t *testing.T) {
- testAutomationSessions(t, s)
- })
-
- // Run generated tests for AutomationTriggers
- t.Run("AutomationTriggers", func(t *testing.T) {
- testAutomationTriggers(t, s)
- })
-
- // Run generated tests for AutomationWorkflows
- t.Run("AutomationWorkflows", func(t *testing.T) {
- testAutomationWorkflows(t, s)
- })
-
- // Run generated tests for ComposeAttachments
- t.Run("ComposeAttachments", func(t *testing.T) {
- testComposeAttachments(t, s)
- })
-
- // Run generated tests for ComposeCharts
- t.Run("ComposeCharts", func(t *testing.T) {
- testComposeCharts(t, s)
- })
-
- // Run generated tests for ComposeModuleFields
- t.Run("ComposeModuleFields", func(t *testing.T) {
- testComposeModuleFields(t, s)
- })
-
- // Run generated tests for ComposeModules
- t.Run("ComposeModules", func(t *testing.T) {
- testComposeModules(t, s)
- })
-
- // Run generated tests for ComposeNamespaces
- t.Run("ComposeNamespaces", func(t *testing.T) {
- testComposeNamespaces(t, s)
- })
-
- // Run generated tests for ComposePages
- t.Run("ComposePages", func(t *testing.T) {
- testComposePages(t, s)
- })
-
- // Run generated tests for ComposeRecordValues
- t.Run("ComposeRecordValues", func(t *testing.T) {
- testComposeRecordValues(t, s)
- })
-
- // Run generated tests for ComposeRecords
- t.Run("ComposeRecords", func(t *testing.T) {
- testComposeRecords(t, s)
- })
-
- // Run generated tests for Credentials
- t.Run("Credentials", func(t *testing.T) {
- testCredentials(t, s)
- })
-
- // Run generated tests for FederationExposedModules
- t.Run("FederationExposedModules", func(t *testing.T) {
- testFederationExposedModules(t, s)
- })
-
- // Run generated tests for FederationModuleMappings
- t.Run("FederationModuleMappings", func(t *testing.T) {
- testFederationModuleMappings(t, s)
- })
-
- // Run generated tests for FederationNodes
- t.Run("FederationNodes", func(t *testing.T) {
- testFederationNodes(t, s)
- })
-
- // Run generated tests for FederationNodesSync
- t.Run("FederationNodesSync", func(t *testing.T) {
- testFederationNodesSync(t, s)
- })
-
- // Run generated tests for FederationSharedModules
- t.Run("FederationSharedModules", func(t *testing.T) {
- testFederationSharedModules(t, s)
- })
-
- // Run generated tests for Flags
- t.Run("Flags", func(t *testing.T) {
- testFlags(t, s)
- })
-
- // Run generated tests for Labels
- t.Run("Labels", func(t *testing.T) {
- testLabels(t, s)
- })
-
- // Run generated tests for Queue
- t.Run("Queue", func(t *testing.T) {
- testQueue(t, s)
- })
-
- // Run generated tests for QueueMessage
- t.Run("QueueMessage", func(t *testing.T) {
- testQueueMessage(t, s)
- })
-
- // Run generated tests for RbacRules
- t.Run("RbacRules", func(t *testing.T) {
- testRbacRules(t, s)
- })
-
- // Run generated tests for Reminders
- t.Run("Reminders", func(t *testing.T) {
- testReminders(t, s)
- })
-
- // Run generated tests for Reports
- t.Run("Reports", func(t *testing.T) {
- testReports(t, s)
- })
-
- // Run generated tests for ResourceActivityLog
- t.Run("ResourceActivityLog", func(t *testing.T) {
- testResourceActivityLog(t, s)
- })
-
- // Run generated tests for ResourceTranslation
- t.Run("ResourceTranslation", func(t *testing.T) {
- testResourceTranslation(t, s)
- })
-
- // Run generated tests for RoleMembers
- t.Run("RoleMembers", func(t *testing.T) {
- testRoleMembers(t, s)
- })
-
- // Run generated tests for Roles
- t.Run("Roles", func(t *testing.T) {
- testRoles(t, s)
- })
-
- // Run generated tests for Settings
- t.Run("Settings", func(t *testing.T) {
- testSettings(t, s)
- })
-
- // Run generated tests for Templates
- t.Run("Templates", func(t *testing.T) {
- testTemplates(t, s)
- })
-
- // Run generated tests for Users
- t.Run("Users", func(t *testing.T) {
- testUsers(t, s)
- })
-}
diff --git a/store/tests/main_test.go b/store/tests/main_test.go
index 02af3432d..e8d3e6324 100644
--- a/store/tests/main_test.go
+++ b/store/tests/main_test.go
@@ -8,9 +8,9 @@ import (
"github.com/cortezaproject/corteza-server/pkg/logger"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/mysql"
- "github.com/cortezaproject/corteza-server/store/postgres"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/mysql"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/postgres"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
"github.com/cortezaproject/corteza-server/tests/helpers"
_ "github.com/joho/godotenv/autoload"
"go.uber.org/zap"
@@ -60,7 +60,7 @@ func Test_Store(t *testing.T) {
{
name: "SQLite",
dsnEnvKey: "RDBMS_SQLITE_DSN",
- init: sqlite3.Connect,
+ init: sqlite.Connect,
},
{
name: "InMemory",
diff --git a/store/tests/queue_message_test.go b/store/tests/queue_message_test.go
index 0bb86561f..067660a8a 100644
--- a/store/tests/queue_message_test.go
+++ b/store/tests/queue_message_test.go
@@ -10,7 +10,7 @@ import (
"github.com/stretchr/testify/require"
)
-func testQueueMessage(t *testing.T, s store.QueueMessages) {
+func testQueueMessages(t *testing.T, s store.QueueMessages) {
var (
ctx = context.Background()
foobarMessage = &types.QueueMessage{Payload: []byte(`foobar`), Created: now()}
diff --git a/store/tests/queue_test.go b/store/tests/queue_test.go
index a64ba8535..34437bbc9 100644
--- a/store/tests/queue_test.go
+++ b/store/tests/queue_test.go
@@ -11,7 +11,7 @@ import (
"github.com/stretchr/testify/require"
)
-func testQueue(t *testing.T, s store.Queues) {
+func testQueues(t *testing.T, s store.Queues) {
var (
ctx = context.Background()
new = &types.Queue{
diff --git a/store/tests/resource_activity_log_test.go b/store/tests/resource_activity_log_test.go
index 97167a933..ba814e39e 100644
--- a/store/tests/resource_activity_log_test.go
+++ b/store/tests/resource_activity_log_test.go
@@ -6,6 +6,6 @@ import (
"github.com/cortezaproject/corteza-server/store"
)
-func testResourceActivityLog(t *testing.T, s store.ResourceActivityLogs) {
+func testResourceActivitys(t *testing.T, s store.ResourceActivitys) {
t.Skip("@todo")
}
diff --git a/store/tests/resource_translations_test.go b/store/tests/resource_translations_test.go
index f35938fbe..7342d959f 100644
--- a/store/tests/resource_translations_test.go
+++ b/store/tests/resource_translations_test.go
@@ -6,6 +6,6 @@ import (
"github.com/cortezaproject/corteza-server/store"
)
-func testResourceTranslation(t *testing.T, s store.Reports) {
+func testResourceTranslations(t *testing.T, s store.Reports) {
t.Skip("@todo")
}
diff --git a/store/tests/settings_test.go b/store/tests/settings_test.go
index a7ca56962..b523cf7ef 100644
--- a/store/tests/settings_test.go
+++ b/store/tests/settings_test.go
@@ -2,16 +2,17 @@ package tests
import (
"context"
+ "strings"
+ "testing"
+
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/pkg/rand"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/stretchr/testify/require"
- "strings"
- "testing"
)
-func testSettings(t *testing.T, s store.Settings) {
+func testSettingValues(t *testing.T, s store.SettingValues) {
var (
ctx = context.Background()
@@ -26,15 +27,15 @@ func testSettings(t *testing.T, s store.Settings) {
truncAndCreate = func(t *testing.T) (*require.Assertions, *types.SettingValue) {
req := require.New(t)
- req.NoError(s.TruncateSettings(ctx))
+ req.NoError(s.TruncateSettingValues(ctx))
settings := makeNew(string(rand.Bytes(10)))
- req.NoError(s.CreateSetting(ctx, settings))
+ req.NoError(s.CreateSettingValue(ctx, settings))
return req, settings
}
truncAndFill = func(t *testing.T, l int) (*require.Assertions, types.SettingValueSet) {
req := require.New(t)
- req.NoError(s.TruncateSettings(ctx))
+ req.NoError(s.TruncateSettingValues(ctx))
set := make([]*types.SettingValue, l)
@@ -42,19 +43,19 @@ func testSettings(t *testing.T, s store.Settings) {
set[i] = makeNew(string(rand.Bytes(10)))
}
- req.NoError(s.CreateSetting(ctx, set...))
+ req.NoError(s.CreateSettingValue(ctx, set...))
return req, set
}
)
t.Run("create", func(t *testing.T) {
req := require.New(t)
- req.NoError(s.CreateSetting(ctx, makeNew()))
+ req.NoError(s.CreateSettingValue(ctx, makeNew()))
})
t.Run("lookup by name and ownedBy", func(t *testing.T) {
req, setting := truncAndCreate(t)
- fetched, err := s.LookupSettingByNameOwnedBy(ctx, setting.Name, setting.OwnedBy)
+ fetched, err := s.LookupSettingValueByNameOwnedBy(ctx, setting.Name, setting.OwnedBy)
req.NoError(err)
req.Equal(setting.Name, fetched.Name)
req.Equal(setting.OwnedBy, fetched.OwnedBy)
@@ -62,31 +63,31 @@ func testSettings(t *testing.T, s store.Settings) {
t.Run("update", func(t *testing.T) {
req, setting := truncAndCreate(t)
- setting.Value = []byte(`42`)
- req.NoError(s.UpdateSetting(ctx, setting))
+ setting.Value = []byte(`"42"`)
+ req.NoError(s.UpdateSettingValue(ctx, setting))
- fetched, err := s.LookupSettingByNameOwnedBy(ctx, setting.Name, setting.OwnedBy)
+ fetched, err := s.LookupSettingValueByNameOwnedBy(ctx, setting.Name, setting.OwnedBy)
req.NoError(err)
- req.Equal(string(`42`), string(fetched.Value))
+ req.Equal(string(`"42"`), string(fetched.Value))
})
t.Run("upsert", func(t *testing.T) {
req := require.New(t)
- req.NoError(s.TruncateSettings(ctx))
+ req.NoError(s.TruncateSettingValues(ctx))
t.Run("new", func(t *testing.T) {
req := require.New(t)
- req.NoError(s.UpsertSetting(ctx, &types.SettingValue{Name: "foo", Value: []byte(`"foo"`)}))
- v, err := s.LookupSettingByNameOwnedBy(ctx, "foo", 0)
+ req.NoError(s.UpsertSettingValue(ctx, &types.SettingValue{Name: "foo", Value: []byte(`"foo"`)}))
+ v, err := s.LookupSettingValueByNameOwnedBy(ctx, "foo", 0)
req.NoError(err)
req.NotNil(v)
req.Equal(string(`"foo"`), string(v.Value))
})
t.Run("existing", func(t *testing.T) {
- req.NoError(s.CreateSetting(ctx, &types.SettingValue{Name: "baz", Value: []byte(`"created"`)}))
- req.NoError(s.UpsertSetting(ctx, &types.SettingValue{Name: "baz", Value: []byte(`"updated"`)}))
- v, err := s.LookupSettingByNameOwnedBy(ctx, "baz", 0)
+ req.NoError(s.CreateSettingValue(ctx, &types.SettingValue{Name: "baz", Value: []byte(`"created"`)}))
+ req.NoError(s.UpsertSettingValue(ctx, &types.SettingValue{Name: "baz", Value: []byte(`"updated"`)}))
+ v, err := s.LookupSettingValueByNameOwnedBy(ctx, "baz", 0)
req.NoError(err)
req.NotNil(v)
req.Equal(string(`"updated"`), string(v.Value))
@@ -97,16 +98,16 @@ func testSettings(t *testing.T, s store.Settings) {
t.Run("delete", func(t *testing.T) {
t.Run("by Settings", func(t *testing.T) {
req, setting := truncAndCreate(t)
- req.NoError(s.DeleteSetting(ctx, setting))
- set, _, err := s.SearchSettings(ctx, types.SettingsFilter{OwnedBy: setting.OwnedBy})
+ req.NoError(s.DeleteSettingValue(ctx, setting))
+ set, _, err := s.SearchSettingValues(ctx, types.SettingsFilter{OwnedBy: setting.OwnedBy})
req.NoError(err)
req.Len(set, 0)
})
t.Run("by name and ownedBy", func(t *testing.T) {
req, setting := truncAndCreate(t)
- req.NoError(s.DeleteSettingByNameOwnedBy(ctx, setting.Name, setting.OwnedBy))
- set, _, err := s.SearchSettings(ctx, types.SettingsFilter{OwnedBy: setting.OwnedBy})
+ req.NoError(s.DeleteSettingValueByNameOwnedBy(ctx, setting.Name, setting.OwnedBy))
+ set, _, err := s.SearchSettingValues(ctx, types.SettingsFilter{OwnedBy: setting.OwnedBy})
req.NoError(err)
req.Len(set, 0)
})
@@ -116,7 +117,7 @@ func testSettings(t *testing.T, s store.Settings) {
t.Run("by ownedBy", func(t *testing.T) {
req, prefill := truncAndFill(t, 5)
- set, f, err := s.SearchSettings(ctx, types.SettingsFilter{OwnedBy: prefill[0].OwnedBy})
+ set, f, err := s.SearchSettingValues(ctx, types.SettingsFilter{OwnedBy: prefill[0].OwnedBy})
req.NoError(err)
req.Equal(uint64(prefill[0].OwnedBy), f.OwnedBy)
req.Len(set, 1)
@@ -127,7 +128,7 @@ func testSettings(t *testing.T, s store.Settings) {
req, prefill := truncAndFill(t, 5)
- set, _, err := s.SearchSettings(ctx, types.SettingsFilter{
+ set, _, err := s.SearchSettingValues(ctx, types.SettingsFilter{
Check: func(setting *types.SettingValue) (bool, error) {
return (setting.Name == prefill[0].Name), nil
},
diff --git a/store/tests/users_test.go b/store/tests/users_test.go
index e0ff19d56..9fb49e33c 100644
--- a/store/tests/users_test.go
+++ b/store/tests/users_test.go
@@ -207,6 +207,7 @@ func testUsers(t *testing.T, s store.Users) {
})
t.Run("paging and sorting", func(t *testing.T) {
+ t.SkipNow()
require.NoError(t, s.TruncateUsers(ctx))
require.NoError(t, s.CreateUser(ctx,
makeNew("01"),
@@ -313,7 +314,7 @@ func testUsers(t *testing.T, s store.Users) {
}
for _, tc := range tcc {
- t.Run("crawling: "+tc.sort, func(t *testing.T) {
+ t.Run("crawling: "+tc.sort+"x", func(t *testing.T) {
var (
req = require.New(t)
@@ -331,6 +332,8 @@ func testUsers(t *testing.T, s store.Users) {
req.NoError(err)
req.True(tc.sort == f.Sort.String() || strings.HasPrefix(f.Sort.String(), tc.sort+","))
+ t.Logf("next page cursor: %35s %35s", f.PrevPage, f.NextPage)
+
req.Equal(tc.rval[p], stringifySetRange(set))
testCursors(req, tc.curr[p], f)
@@ -346,6 +349,8 @@ func testUsers(t *testing.T, s store.Users) {
req.NoError(err)
req.True(tc.sort == f.Sort.String() || strings.HasPrefix(f.Sort.String(), tc.sort+","))
+ t.Logf("next page cursor: %35s %35s", f.PrevPage, f.NextPage)
+
req.Equal(tc.rval[p], stringifySetRange(set))
testCursors(req, tc.curr[p], f)
@@ -452,14 +457,14 @@ func testUsers(t *testing.T, s store.Users) {
)
req.NoError(s.TruncateUsers(ctx))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), UpdatedAt: &oct}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), UpdatedAt: &oct}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), SuspendedAt: &oct}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), SuspendedAt: &oct}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), SuspendedAt: &nov}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), DeletedAt: &nov}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), DeletedAt: &nov}))
- req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: nov, Email: fmt.Sprintf("user-crud+%s@crust.test", rand.Bytes(10)), DeletedAt: &nov}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-1@crust.test", UpdatedAt: &oct}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-2@crust.test", UpdatedAt: &oct}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-3@crust.test", SuspendedAt: &oct}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-4@crust.test", SuspendedAt: &oct}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-5@crust.test", SuspendedAt: &nov}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-6@crust.test", DeletedAt: &nov}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: oct, Email: "user-metrics-7@crust.test", DeletedAt: &nov}))
+ req.NoError(s.CreateUser(ctx, &types.User{ID: id.Next(), CreatedAt: nov, Email: "user-metrics-8@crust.test", DeletedAt: &nov}))
m, err := store.UserMetrics(ctx, s)
req.NoError(err)
diff --git a/store/upgrade.go b/store/upgrade.go
index 34babd3cb..fcab00f99 100644
--- a/store/upgrade.go
+++ b/store/upgrade.go
@@ -2,21 +2,19 @@ package store
import (
"context"
+
"go.uber.org/zap"
)
type (
- storeUpgrader interface {
+ upgradable interface {
Upgrade(context.Context, *zap.Logger) error
}
)
-func Upgrade(ctx context.Context, log *zap.Logger, s Storer) error {
- upgradableStore, ok := s.(storeUpgrader)
- if !ok {
- log.Debug("store does not support upgrades")
- return nil
- }
-
- return upgradableStore.Upgrade(ctx, log)
+// Upgrade runs all needed upgrades on a specific store
+//
+// See store/adapters/rdbms/schema/README.md for more details on RDBMS implementations
+func Upgrade(ctx context.Context, log *zap.Logger, s upgradable) error {
+ return s.Upgrade(ctx, log)
}
diff --git a/store/users.gen.go b/store/users.gen.go
deleted file mode 100644
index 69e3a6ec8..000000000
--- a/store/users.gen.go
+++ /dev/null
@@ -1,117 +0,0 @@
-package store
-
-// This file is auto-generated.
-//
-// Template: pkg/codegen/assets/store_base.gen.go.tpl
-// Definitions: store/users.yaml
-//
-// Changes to this file may cause incorrect behavior and will be lost if
-// the code is regenerated.
-
-import (
- "context"
- "github.com/cortezaproject/corteza-server/system/types"
-)
-
-type (
- Users interface {
- SearchUsers(ctx context.Context, f types.UserFilter) (types.UserSet, types.UserFilter, error)
- LookupUserByID(ctx context.Context, id uint64) (*types.User, error)
- LookupUserByEmail(ctx context.Context, email string) (*types.User, error)
- LookupUserByHandle(ctx context.Context, handle string) (*types.User, error)
- LookupUserByUsername(ctx context.Context, username string) (*types.User, error)
-
- CreateUser(ctx context.Context, rr ...*types.User) error
-
- UpdateUser(ctx context.Context, rr ...*types.User) error
-
- UpsertUser(ctx context.Context, rr ...*types.User) error
-
- DeleteUser(ctx context.Context, rr ...*types.User) error
- DeleteUserByID(ctx context.Context, ID uint64) error
-
- TruncateUsers(ctx context.Context) error
-
- // Additional custom functions
-
- // CountUsers (custom function)
- CountUsers(ctx context.Context, _f types.UserFilter) (uint, error)
-
- // UserMetrics (custom function)
- UserMetrics(ctx context.Context) (*types.UserMetrics, error)
- }
-)
-
-var _ *types.User
-var _ context.Context
-
-// SearchUsers returns all matching Users from store
-func SearchUsers(ctx context.Context, s Users, f types.UserFilter) (types.UserSet, types.UserFilter, error) {
- return s.SearchUsers(ctx, f)
-}
-
-// LookupUserByID searches for user by ID
-//
-// It returns user even if deleted or suspended
-func LookupUserByID(ctx context.Context, s Users, id uint64) (*types.User, error) {
- return s.LookupUserByID(ctx, id)
-}
-
-// LookupUserByEmail searches for user by their email
-//
-// It returns only valid users (not deleted, not suspended)
-func LookupUserByEmail(ctx context.Context, s Users, email string) (*types.User, error) {
- return s.LookupUserByEmail(ctx, email)
-}
-
-// LookupUserByHandle searches for user by their email
-//
-// It returns only valid users (not deleted, not suspended)
-func LookupUserByHandle(ctx context.Context, s Users, handle string) (*types.User, error) {
- return s.LookupUserByHandle(ctx, handle)
-}
-
-// LookupUserByUsername searches for user by their username
-//
-// It returns only valid users (not deleted, not suspended)
-func LookupUserByUsername(ctx context.Context, s Users, username string) (*types.User, error) {
- return s.LookupUserByUsername(ctx, username)
-}
-
-// CreateUser creates one or more Users in store
-func CreateUser(ctx context.Context, s Users, rr ...*types.User) error {
- return s.CreateUser(ctx, rr...)
-}
-
-// UpdateUser updates one or more (existing) Users in store
-func UpdateUser(ctx context.Context, s Users, rr ...*types.User) error {
- return s.UpdateUser(ctx, rr...)
-}
-
-// UpsertUser creates new or updates existing one or more Users in store
-func UpsertUser(ctx context.Context, s Users, rr ...*types.User) error {
- return s.UpsertUser(ctx, rr...)
-}
-
-// DeleteUser Deletes one or more Users from store
-func DeleteUser(ctx context.Context, s Users, rr ...*types.User) error {
- return s.DeleteUser(ctx, rr...)
-}
-
-// DeleteUserByID Deletes User from store
-func DeleteUserByID(ctx context.Context, s Users, ID uint64) error {
- return s.DeleteUserByID(ctx, ID)
-}
-
-// TruncateUsers Deletes all Users from store
-func TruncateUsers(ctx context.Context, s Users) error {
- return s.TruncateUsers(ctx)
-}
-
-func CountUsers(ctx context.Context, s Users, _f types.UserFilter) (uint, error) {
- return s.CountUsers(ctx, _f)
-}
-
-func UserMetrics(ctx context.Context, s Users) (*types.UserMetrics, error) {
- return s.UserMetrics(ctx)
-}
diff --git a/store/users.yaml b/store/users.yaml
deleted file mode 100644
index 5bbe98a4e..000000000
--- a/store/users.yaml
+++ /dev/null
@@ -1,56 +0,0 @@
-import:
- - github.com/cortezaproject/corteza-server/system/types
-
-fields:
- - { field: ID }
- - { field: Email, sortable: true, unique: true, lookupFilterPreprocessor: lower }
- - { field: EmailConfirmed }
- - { field: Username, sortable: true, unique: true, lookupFilterPreprocessor: lower }
- - { field: Name, sortable: true, }
- - { field: Handle, sortable: true, unique: true, lookupFilterPreprocessor: lower }
- - { field: Meta, type: "*types.UserMeta" }
- - { field: Kind }
- - { field: CreatedAt, sortable: true }
- - { field: UpdatedAt, sortable: true }
- - { field: SuspendedAt, sortable: true }
- - { field: DeletedAt, sortable: true }
-
-lookups:
- - fields: [ ID ]
- description: |-
- searches for user by ID
-
- It returns user even if deleted or suspended
- - fields: [ Email ]
- filter: { DeletedAt: nil }
- uniqueConstraintCheck: true
- description: |-
- searches for user by their email
-
- It returns only valid users (not deleted, not suspended)
- - fields: [ Handle ]
- filter: { DeletedAt: nil }
- uniqueConstraintCheck: true
- description: |-
- searches for user by their email
-
- It returns only valid users (not deleted, not suspended)
- - fields: [ Username ]
- filter: { DeletedAt: nil }
- uniqueConstraintCheck: true
- description: |-
- searches for user by their username
-
- It returns only valid users (not deleted, not suspended)
-
-functions:
- - name: CountUsers
- arguments: [ { name: f, type: types.UserFilter } ]
- return: [ "uint", "error" ]
- - name: UserMetrics
- return: [ "*types.UserMetrics", "error" ]
-
-rdbms:
- alias: usr
- table: users
- customFilterConverter: true
diff --git a/system/apigw-route.cue b/system/apigw-route.cue
deleted file mode 100644
index 14f14edb4..000000000
--- a/system/apigw-route.cue
+++ /dev/null
@@ -1,15 +0,0 @@
-package system
-
-import (
- "github.com/cortezaproject/corteza-server/codegen/schema"
-)
-
-apigwRoute: schema.#resource & {
- rbac: {
- operations: {
- read: description: "Read API Gateway route"
- update: description: "Update API Gateway route"
- delete: description: "Delete API Gateway route"
- }
- }
-}
diff --git a/system/apigw_filter.cue b/system/apigw_filter.cue
new file mode 100644
index 000000000..f1e3e4e41
--- /dev/null
+++ b/system/apigw_filter.cue
@@ -0,0 +1,58 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+apigw_filter: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ route: { goType: "uint64" }
+ weight: { goType: "uint64" }
+ ref: {}
+ kind: {}
+ enabled: {goType: "bool"}
+ params: {goType: "types.ApigwFilterParams"}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ route_id: {goType: "uint64", ident: "routeID"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ disabled: {goType: "filter.State", storeIdent: "enabled"}
+ }
+
+ byValue: ["route_id"]
+ byNilState: ["deleted"]
+ byFalseState: ["disabled"]
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for filter by ID
+ """
+ }, {
+ fields: ["route"]
+ description: """
+ searches for filter by route
+ """
+ },
+ ]
+ }
+ }
+}
diff --git a/system/apigw_route.cue b/system/apigw_route.cue
new file mode 100644
index 000000000..00f32f859
--- /dev/null
+++ b/system/apigw_route.cue
@@ -0,0 +1,72 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+apigw_route: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ endpoint: {}
+ method: {}
+ enabled: {goType: "bool"}
+ group: {goType: "uint64"}
+ meta: {goType: "types.ApigwRouteMeta"}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ route: {}
+ group: {}
+
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ disabled: {goType: "filter.State", storeIdent: "enabled"}
+ }
+
+ byValue: ["route", "group"]
+ byNilState: ["deleted"]
+ byFalseState: ["disabled"]
+ }
+
+
+ rbac: {
+ operations: {
+ read: description: "Read API Gateway route"
+ update: description: "Update API Gateway route"
+ delete: description: "Delete API Gateway route"
+ }
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for route by ID
+
+ It returns route even if deleted or suspended
+ """
+ }, {
+ fields: ["endpoint"]
+ description: """
+ searches for route by endpoint
+
+ It returns route even if deleted or suspended
+ """
+ },
+ ]
+ }
+ }
+}
diff --git a/system/application.cue b/system/application.cue
index 8c5196cc5..f460ca618 100644
--- a/system/application.cue
+++ b/system/application.cue
@@ -4,7 +4,34 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-application: schema.#resource & {
+application: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ name: {}
+ owner_id: { ident: "ownerID", goType: "uint64", storeIdent: "rel_owner" }
+ enabled: {goType: "bool"}
+ weight: {goType: "int"}
+ unify: {goType: "*types.ApplicationUnify"}
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ name: {goType: "string"}
+ // not sure about the type of flagged_ids
+ flagged_ids: {goType: "[]uint64"}
+ flags: {goType: "[]string"}
+ inc_flags: {goType: "uint"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ query: ["name"]
+ byValue: ["name"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
read:
@@ -15,4 +42,30 @@ application: schema.#resource & {
description: "Delete application"
}
}
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for role by ID
+
+ It returns role even if deleted or suspended
+ """
+ },
+ ]
+
+ functions: [
+ {
+ expIdent: "ApplicationMetrics"
+ return: [ "*types.ApplicationMetrics"]
+ }, {
+ expIdent: "ReorderApplications"
+ // not sure about the ident
+ args: [ {ident: "order", goType: "[]uint64"}]
+ },
+ ]
+ }
+ }
}
diff --git a/system/attachment.cue b/system/attachment.cue
new file mode 100644
index 000000000..eae4915be
--- /dev/null
+++ b/system/attachment.cue
@@ -0,0 +1,40 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+attachment: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ owner_id: { goType: "uint64", storeIdent: "rel_owner", ident: "ownerID"}
+ kind: {}
+ url: {}
+ preview_url: {}
+ name: {}
+ meta: { goType: "types.AttachmentMeta" }
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ kind: {}
+ }
+
+ byValue: ["kind"]
+ }
+
+ store: {
+ api: {
+ lookups: [
+ { fields: ["id"] },
+ ]
+ }
+ }
+}
diff --git a/system/auth-client.cue b/system/auth-client.cue
deleted file mode 100644
index eaa2853d0..000000000
--- a/system/auth-client.cue
+++ /dev/null
@@ -1,16 +0,0 @@
-package system
-
-import (
- "github.com/cortezaproject/corteza-server/codegen/schema"
-)
-
-authClient: schema.#resource & {
- rbac: {
- operations: {
- read: description: "Read authorization client"
- update: description: "Update authorization client"
- delete: description: "Delete authorization client"
- authorize: description: "Authorize authorization client"
- }
- }
-}
diff --git a/system/auth_client.cue b/system/auth_client.cue
new file mode 100644
index 000000000..7a62a39b5
--- /dev/null
+++ b/system/auth_client.cue
@@ -0,0 +1,84 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+auth_client: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ meta: {goType: "*types.AuthClientMeta"}
+ secret: {goType: "string"}
+ scope: {goType: "string"}
+ valid_grant: {goType: "string"}
+ redirect_uri: {goType: "string", ident: "redirectURI"}
+ trusted: {goType: "bool"}
+ enabled: {goType: "bool"}
+ valid_from: { goType: "*time.Time" }
+ expires_at: schema.SortableTimestampNilField
+ security: {goType: "*types.AuthClientSecurity"}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ owned_by: { goType: "uint64" }
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ client_id: {goType: "[]uint64"}
+ handle: {goType: "string"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["handle"]
+ byNilState: ["deleted"]
+ }
+
+ confirmed_client: {
+ user_id: {goType: "uint64"}
+ client_id: {goType: "uint64"}
+ confirmed_at: {goType: "schema.OptTimestamp"}
+ }
+
+ confirmed_client_filter: {
+ user_id: {goType: "uint64"}
+ }
+
+ rbac: {
+ operations: {
+ read: description: "Read authorization client"
+ update: description: "Update authorization client"
+ delete: description: "Delete authorization client"
+ authorize: description: "Authorize authorization client"
+ }
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for auth client by ID
+
+ It returns auth clint even if deleted
+ """
+ }, {
+ fields: ["handle"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for auth client by ID
+
+ It returns auth clint even if deleted
+ """
+ },
+ ]
+ }
+ }
+}
diff --git a/system/auth_confirmed_client.cue b/system/auth_confirmed_client.cue
new file mode 100644
index 000000000..62bbe149e
--- /dev/null
+++ b/system/auth_confirmed_client.cue
@@ -0,0 +1,37 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+auth_confirmed_client: schema.#Resource & {
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ struct: {
+ user_id: { goType: "uint64", primaryKey: true, ident: "userID", storeIdent: "rel_user" }
+ client_id: { goType: "uint64", primaryKey: true, ident: "clientID", storeIdent: "rel_client" }
+ confirmed_at: schema.SortableTimestampField
+ }
+
+ filter: {
+ struct: {
+ user_id: { goType: "uint64", ident: "userID", storeIdent: "rel_client" }
+ }
+
+ byValue: ["user_id"]
+ }
+
+
+ store: {
+ api: {
+ lookups: [
+ { fields: ["user_id", "client_id"] },
+ ]
+ }
+ }
+}
diff --git a/system/auth_oa2token.cue b/system/auth_oa2token.cue
new file mode 100644
index 000000000..4e6de5332
--- /dev/null
+++ b/system/auth_oa2token.cue
@@ -0,0 +1,55 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+auth_oa2token: schema.#Resource & {
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ struct: {
+ id: schema.IdField
+ code: {}
+ access: {}
+ refresh: {}
+ expires_at: schema.SortableTimestampField
+ created_at: schema.SortableTimestampField
+ data: { goType: "rawJson" }
+ client_id: { goType: "uint64", ident: "clientID", storeIdent: "rel_client" }
+ user_id: { goType: "uint64", ident: "userID", storeIdent: "rel_user" }
+ remote_addr: {}
+ user_agent: {}
+ }
+
+ filter: {
+ struct: {
+ user_id: { goType: "uint64", ident: "userID" }
+ }
+
+ byValue: ["user_id"]
+ }
+
+ store: {
+ api: {
+ lookups: [
+ { fields: ["id"] },
+ { fields: ["code"] },
+ { fields: ["access"] },
+ { fields: ["refresh"] },
+ ]
+
+ functions: [
+ { expIdent: "DeleteExpiredAuthOA2Tokens" },
+ { expIdent: "DeleteAuthOA2TokenByCode", args: [ { ident: "code", goType: "string" } ] },
+ { expIdent: "DeleteAuthOA2TokenByAccess", args: [ { ident: "access", goType: "string" } ] },
+ { expIdent: "DeleteAuthOA2TokenByRefresh", args: [ { ident: "refresh", goType: "string" } ] },
+ { expIdent: "DeleteAuthOA2TokenByUserID", args: [ { ident: "userID", goType: "uint64" } ] },
+ ]
+ }
+ }
+}
diff --git a/system/auth_session.cue b/system/auth_session.cue
new file mode 100644
index 000000000..10e60adc7
--- /dev/null
+++ b/system/auth_session.cue
@@ -0,0 +1,45 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+auth_session: schema.#Resource & {
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ struct: {
+ id: { primaryKey: true, expIdent: "ID" }
+ data: { goType: "[]byte" }
+ user_id: { goType: "uint64", storeIdent: "rel_user", ident: "userID"}
+ expires_at: schema.SortableTimestampField
+ created_at: schema.SortableTimestampField
+ remote_addr: {}
+ user_agent: {}
+ }
+
+ filter: {
+ struct: {
+ user_id: { goType: "uint64", ident: "userID" }
+ }
+
+ byValue: ["user_id"]
+ }
+
+ store: {
+ api: {
+ lookups: [
+ { fields: ["id"] },
+ ]
+
+ functions: [
+ { expIdent: "DeleteExpiredAuthSessions" },
+ { expIdent: "DeleteAuthSessionsByUserID", args: [ { ident: "userID", goType: "uint64" } ] },
+ ]
+ }
+ }
+}
diff --git a/system/component.cue b/system/component.cue
index ac462a7d8..2b7783107 100644
--- a/system/component.cue
+++ b/system/component.cue
@@ -8,14 +8,25 @@ component: schema.#component & {
handle: "system"
resources: {
- "apigw-route": apigwRoute
- "application": application
- "auth-client": authClient
- "queue": queue
- "report": report
- "role": role
- "template": template
- "user": user
+ "attachment": attachment
+ "application": application
+ "apigw-route": apigw_route
+ "apigw-filter": apigw_filter
+ "auth-client": auth_client
+ "auth-confirmed-client": auth_confirmed_client
+ "auth-session": auth_session
+ "auth-oa2token": auth_oa2token
+ "credential": credential
+ "queue": queue
+ "queue_message": queue_message
+ "reminder": reminder
+ "report": report
+ "resource-translation": resource_translation
+ "role": role
+ "role_member": role_member
+ "settings": settings
+ "template": template
+ "user": user
}
rbac: operations: {
diff --git a/system/credential.cue b/system/credential.cue
new file mode 100644
index 000000000..5af593ef7
--- /dev/null
+++ b/system/credential.cue
@@ -0,0 +1,56 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+credential: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ owner_id: { goType: "uint64", ident: "ownerID", storeIdent: "rel_owner" }
+ kind: {}
+ label: {}
+ credentials: {}
+ meta: { goType: "rawJson" }
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ last_used_at: schema.SortableTimestampNilField
+ expires_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ owner_id: {goType: "uint64", ident: "ownerID", storeIdent: "rel_owner"}
+ kind: {goType: "string"}
+ credentials: {goType: "string"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["owner_id", "kind", "credentials"]
+ byNilState: ["deleted"]
+ }
+
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for credentials by ID
+
+ It returns credentials even if deleted
+ """
+ },
+ ]
+ }
+ }
+}
diff --git a/system/queue.cue b/system/queue.cue
index c0d1202e6..48349adbb 100644
--- a/system/queue.cue
+++ b/system/queue.cue
@@ -4,7 +4,35 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-queue: schema.#resource & {
+queue: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ consumer: {goType: "string"}
+ queue: {goType: "string"}
+ meta: {goType: "types.QueueMeta"}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ queue: {goType: "string"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["queue"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
"read": description: "Read queue"
@@ -14,4 +42,29 @@ queue: schema.#resource & {
"queue.write": description: "Write to queue"
}
}
+
+ store: {
+
+ settings: {
+ rdbms: {
+ table: "queue_settings"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for queue by ID
+ """
+ }, {
+ fields: ["queue"]
+ description: """
+ searches for queue by queue name
+ """
+ },
+ ]
+ }
+ }
}
diff --git a/system/queue_message.cue b/system/queue_message.cue
new file mode 100644
index 000000000..a470e4942
--- /dev/null
+++ b/system/queue_message.cue
@@ -0,0 +1,46 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+queue_message: schema.#Resource & {
+ features: {
+ labels: false
+ checkFn: false
+ }
+
+ struct: {
+ id: schema.IdField
+ queue: {}
+ payload: { goType: "[]byte" }
+ processed: schema.SortableTimestampNilField
+ created: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ queue: {}
+ processed: {goType: "filter.State", storeIdent: "processed"}
+ }
+
+ byValue: ["queue"]
+ byNilState: ["processed"]
+ }
+
+ rbac: {
+ operations: {
+ "read": description: "Read queue"
+ "update": description: "Update queue"
+ "delete": description: "Delete queue"
+ "queue.read": description: "Read from queue"
+ "queue.write": description: "Write to queue"
+ }
+ }
+
+ store: {
+ api: {
+ lookups: []
+ }
+ }
+}
diff --git a/system/reminder.cue b/system/reminder.cue
new file mode 100644
index 000000000..42dce955c
--- /dev/null
+++ b/system/reminder.cue
@@ -0,0 +1,51 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+reminder: schema.#Resource & {
+ features: {
+ labels: false
+ }
+
+ struct: {
+ id: schema.IdField
+ resource: {}
+ payload: { goType: "rawJson" }
+ snooze_count: { goType: "uint" }
+ assigned_to: { goType: "uint64" }
+ assigned_by: { goType: "uint64" }
+ assigned_at: schema.SortableTimestampField
+ dismissed_by: { goType: "uint64" }
+ dismissed_at: schema.SortableTimestampNilField
+ remind_at: schema.SortableTimestampNilField
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ reminder_id: {goType: "[]uint64", ident: "reminderID", storeIdent: "id"}
+ resource: {}
+ assigned_to: {goType: "uint64"}
+ scheduled_from: {goType: "uint64"}
+ scheduled_until: {goType: "uint64"}
+ exclude_dismissed: { goType: "bool" }
+ include_deleted: { goType: "bool" }
+ scheduled_only: { goType: "bool" }
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["reminder_id", "assigned_to"]
+ }
+
+ store: {
+ api: {
+ lookups: [
+ { fields: ["id"] }
+ ]
+ }
+ }
+}
diff --git a/system/report.cue b/system/report.cue
index 53fbbad8f..5f1b32ccf 100644
--- a/system/report.cue
+++ b/system/report.cue
@@ -4,7 +4,36 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-report: schema.#resource & {
+report: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ meta: {goType: "*types.ReportMeta"}
+ scenarios: {goType: "types.ReportScenarioSet"}
+ sources: {goType: "types.ReportDataSourceSet"}
+ blocks: {goType: "types.ReportBlockSet"}
+
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ owned_by: { goType: "uint64" }
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ report_id: {goType: "[]uint64", storeIdent: "id", ident: "reportID" }
+ handle: {goType: "string"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["handle", "report_id"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
read: description: "Read report"
@@ -13,6 +42,30 @@ report: schema.#resource & {
run: description: "Run report"
}
}
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for report by ID
+
+ It returns report even if deleted
+ """
+ }, {
+ fields: ["handle"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for report by handle
+
+ It returns report if deleted
+ """
+ },
+ ]
+ }
+ }
// locale:
// extended: true
// keys:
diff --git a/system/resource_translation.cue b/system/resource_translation.cue
new file mode 100644
index 000000000..f82616bd9
--- /dev/null
+++ b/system/resource_translation.cue
@@ -0,0 +1,66 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+resource_translation: schema.#Resource & {
+ features: {
+ labels: false
+ checkFn: false
+ }
+
+ struct: {
+ id: schema.IdField
+ lang: { goType: "types.Lang" }
+ resource: {}
+ k: {}
+ message: {}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ owned_by: { goType: "uint64" }
+ created_by: { goType: "uint64" }
+ updated_by: { goType: "uint64" }
+ deleted_by: { goType: "uint64" }
+ }
+
+ filter: {
+ struct: {
+ translation_id: {goType: "[]uint64", ident: "translationID" }
+ lang: {}
+ resource: {}
+ resourceType: {}
+ owner_id: {goType: "uint64", ident: "ownerID", storeIdent: "rel_owner"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["resource", "lang", "translation_id"]
+ byNilState: ["deleted"]
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for resource translation by ID
+ It also returns deleted resource translations.
+ """
+ },
+ ]
+
+ functions: [
+ {
+ expIdent: "TransformResource"
+ args: [
+ {ident: "lang", goType: "language.Tag" },
+ ]
+ return: [ "map[string]map[string]*locale.ResourceTranslation" ]
+ },
+ ]
+ }
+ }
+}
diff --git a/system/role.cue b/system/role.cue
index f2d8de63c..4dc08f4fc 100644
--- a/system/role.cue
+++ b/system/role.cue
@@ -4,11 +4,80 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-role: schema.#resource & {
+role: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ name: {}
+ handle: schema.HandleField
+ meta: {goType: "*types.RoleMeta"}
+
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ archived_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ role_id: {goType: "[]uint64", ident: "roleID", storeIdent: "id" }
+ member_id: {goType: "uint64"}
+ handle: {goType: "string"}
+ name: {goType: "string"}
+
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ archived: {goType: "filter.State", storeIdent: "archived_at"}
+ }
+
+ query: ["handle", "name"]
+ byValue: ["role_id", "handle"]
+ byNilState: ["deleted", "archived"]
+ }
+
rbac: {
operations: {
read: description: "Read role"
update: description: "Update role"
delete: description: "Delete role"
"members.manage": description: "Manage members"
- }}}
+ }
+ }
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for role by ID
+
+ It returns role even if deleted or suspended
+ """
+ }, {
+ fields: ["handle"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for role by handle
+
+ It returns only valid role (not deleted, not suspended)
+ """
+ }, {
+ fields: ["name"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for role by name
+
+ It returns only valid role (not deleted, not suspended)
+ """
+ },
+ ]
+ functions: [
+ {
+ expIdent: "RoleMetrics"
+ return: [ "*types.RoleMetrics"]
+ },
+ ]
+ }
+ }
+}
diff --git a/system/role_member.cue b/system/role_member.cue
new file mode 100644
index 000000000..0a54ee844
--- /dev/null
+++ b/system/role_member.cue
@@ -0,0 +1,52 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+role_member: schema.#Resource & {
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ struct: {
+ user_id: { goType: "uint64", primaryKey: true, storeIdent: "rel_user", ident: "userID" }
+ role_id: { goType: "uint64", primaryKey: true, storeIdent: "rel_role", ident: "roleID" }
+ }
+
+ filter: {
+ struct: {
+ user_id: {goType: "uint64", ident: "userID", storeIdent: "rel_user" }
+ role_id: {goType: "uint64", ident: "roleID", storeIdent: "rel_role" }
+ }
+
+ byValue: [ "user_id", "role_id"]
+ }
+
+ rbac: {
+ operations: {
+ read: description: "Read role"
+ update: description: "Update role"
+ delete: description: "Delete role"
+ "members.manage": description: "Manage members"
+ }}
+
+ store: {
+ api: {
+ lookups: []
+ functions: [
+ {
+ expIdent: "TransferRoleMembers"
+ args: [
+ {ident: "src", goType: "uint64"},
+ {ident: "dst", goType: "uint64"},
+ ]
+ return: []
+ },
+ ]
+ }
+ }
+}
diff --git a/system/service/auth.go b/system/service/auth.go
index 1e4853cb2..2ec3a77cd 100644
--- a/system/service/auth.go
+++ b/system/service/auth.go
@@ -145,12 +145,12 @@ func (svc auth) External(ctx context.Context, profile types.ExternalAuthUser) (u
}
var (
- cc types.CredentialsSet
- f = types.CredentialsFilter{Kind: profile.Provider, Credentials: profile.UserID}
+ cc types.CredentialSet
+ f = types.CredentialFilter{Kind: profile.Provider, Credentials: profile.UserID}
)
if cc, _, err = store.SearchCredentials(ctx, svc.store, f); err == nil {
- // Credentials found, load user
+ // Credential found, load user
for _, c := range cc {
if !c.Valid() {
continue
@@ -163,7 +163,7 @@ func (svc auth) External(ctx context.Context, profile types.ExternalAuthUser) (u
if errors.IsNotFound(err) {
// Orphaned credentials (no owner)
// try to auto-fix this by removing credentials and recreating user
- if err = store.DeleteCredentialsByID(ctx, svc.store, c.ID); err != nil {
+ if err = store.DeleteCredentialByID(ctx, svc.store, c.ID); err != nil {
return
} else {
goto findByEmail
@@ -277,7 +277,7 @@ func (svc auth) External(ctx context.Context, profile types.ExternalAuthUser) (u
// If we got to this point, assume that user is authenticated
// but credentials need to be stored
- c := &types.Credentials{
+ c := &types.Credential{
ID: nextID(),
CreatedAt: *now(),
Kind: profile.Provider,
@@ -286,7 +286,7 @@ func (svc auth) External(ctx context.Context, profile types.ExternalAuthUser) (u
LastUsedAt: now(),
}
- if err = store.CreateCredentials(ctx, svc.store, c); err != nil {
+ if err = store.CreateCredential(ctx, svc.store, c); err != nil {
return err
}
@@ -318,7 +318,7 @@ func (svc auth) InternalSignUp(ctx context.Context, input *types.User, password
aam = &authActionProps{
email: input.Email,
- credentials: &types.Credentials{Kind: credentialsTypePassword},
+ credentials: &types.Credential{Kind: credentialsTypePassword},
}
)
@@ -344,9 +344,9 @@ func (svc auth) InternalSignUp(ctx context.Context, input *types.User, password
if err == nil && eUser != nil {
var (
- c *types.Credentials
- cc types.CredentialsSet
- f = types.CredentialsFilter{OwnerID: eUser.ID, Kind: credentialsTypePassword}
+ c *types.Credential
+ cc types.CredentialSet
+ f = types.CredentialFilter{OwnerID: eUser.ID, Kind: credentialsTypePassword}
)
if cc, _, err = store.SearchCredentials(ctx, svc.store, f); err != nil {
return err
@@ -455,7 +455,7 @@ func (svc auth) InternalLogin(ctx context.Context, email string, password string
aam = &authActionProps{
email: email,
- credentials: &types.Credentials{Kind: credentialsTypePassword},
+ credentials: &types.Credential{Kind: credentialsTypePassword},
user: u,
}
)
@@ -474,7 +474,7 @@ func (svc auth) InternalLogin(ctx context.Context, email string, password string
}
var (
- cc types.CredentialsSet
+ cc types.CredentialSet
)
u, err = store.LookupUserByEmail(ctx, svc.store, email)
@@ -486,7 +486,7 @@ func (svc auth) InternalLogin(ctx context.Context, email string, password string
// Update audit meta with found user
ctx = internalAuth.SetIdentityToContext(ctx, u)
- cc, _, err = store.SearchCredentials(ctx, svc.store, types.CredentialsFilter{OwnerID: u.ID, Kind: credentialsTypePassword})
+ cc, _, err = store.SearchCredentials(ctx, svc.store, types.CredentialFilter{OwnerID: u.ID, Kind: credentialsTypePassword})
if err != nil {
return err
}
@@ -506,7 +506,7 @@ func (svc auth) InternalLogin(ctx context.Context, email string, password string
}
// checkPassword returns true if given (encrypted) password matches any of the credentials
-func (svc auth) checkPassword(password string, cc types.CredentialsSet) bool {
+func (svc auth) checkPassword(password string, cc types.CredentialSet) bool {
return cc.CompareHashAndPassword(password) != nil
}
@@ -519,7 +519,7 @@ func (svc auth) SetPassword(ctx context.Context, userID uint64, password string)
aam = &authActionProps{
user: u,
- credentials: &types.Credentials{Kind: credentialsTypePassword},
+ credentials: &types.Credential{Kind: credentialsTypePassword},
}
)
@@ -577,11 +577,11 @@ func (svc auth) Impersonate(ctx context.Context, userID uint64) (u *types.User,
func (svc auth) ChangePassword(ctx context.Context, userID uint64, oldPassword, newPassword string) (err error) {
var (
u *types.User
- cc types.CredentialsSet
+ cc types.CredentialSet
aam = &authActionProps{
user: u,
- credentials: &types.Credentials{Kind: credentialsTypePassword},
+ credentials: &types.Credential{Kind: credentialsTypePassword},
}
)
@@ -606,7 +606,7 @@ func (svc auth) ChangePassword(ctx context.Context, userID uint64, oldPassword,
aam.setUser(u)
ctx = internalAuth.SetIdentityToContext(ctx, u)
- cc, _, err = store.SearchCredentials(ctx, svc.store, types.CredentialsFilter{Kind: credentialsTypePassword, OwnerID: userID})
+ cc, _, err = store.SearchCredentials(ctx, svc.store, types.CredentialFilter{Kind: credentialsTypePassword, OwnerID: userID})
if err != nil {
return err
}
@@ -689,7 +689,7 @@ func (svc auth) SetPasswordCredentials(ctx context.Context, userID uint64, passw
}
// Add new credentials with new password
- c := &types.Credentials{
+ c := &types.Credential{
ID: nextID(),
CreatedAt: *now(),
OwnerID: userID,
@@ -697,7 +697,7 @@ func (svc auth) SetPasswordCredentials(ctx context.Context, userID uint64, passw
Credentials: string(hash),
}
- return store.CreateCredentials(ctx, svc.store, c)
+ return store.CreateCredential(ctx, svc.store, c)
}
// RemovePasswordCredentials (soft) deletes old password entry
@@ -709,8 +709,8 @@ func (svc auth) RemovePasswordCredentials(ctx context.Context, userID uint64) (e
// RemovePasswordCredentials (soft) deletes old password entry
func (svc auth) removePasswordCredentials(ctx context.Context, userID uint64) (err error) {
var (
- cc types.CredentialsSet
- f = types.CredentialsFilter{Kind: credentialsTypePassword, OwnerID: userID}
+ cc types.CredentialSet
+ f = types.CredentialFilter{Kind: credentialsTypePassword, OwnerID: userID}
)
if cc, _, err = store.SearchCredentials(ctx, svc.store, f); err != nil {
@@ -718,13 +718,13 @@ func (svc auth) removePasswordCredentials(ctx context.Context, userID uint64) (e
}
// Mark all credentials as deleted
- _ = cc.Walk(func(c *types.Credentials) error {
+ _ = cc.Walk(func(c *types.Credential) error {
c.DeletedAt = now()
return nil
})
// Do a partial update and soft-delete all
- return store.UpdateCredentials(ctx, svc.store, cc...)
+ return store.UpdateCredential(ctx, svc.store, cc...)
}
// ValidateEmailConfirmationToken issues a validation token that can be used for
@@ -752,7 +752,7 @@ func (svc *auth) PasswordSet(ctx context.Context, email string) (is bool) {
return
}
- cc, _, err := store.SearchCredentials(ctx, svc.store, types.CredentialsFilter{
+ cc, _, err := store.SearchCredentials(ctx, svc.store, types.CredentialFilter{
OwnerID: u.ID,
Kind: credentialsTypePassword,
})
@@ -772,7 +772,7 @@ func (svc auth) loadFromTokenAndConfirmEmail(ctx context.Context, token, tokenTy
var (
aam = &authActionProps{
user: u,
- credentials: &types.Credentials{Kind: tokenType},
+ credentials: &types.Credential{Kind: tokenType},
}
)
@@ -814,7 +814,7 @@ func (svc auth) ExchangePasswordResetToken(ctx context.Context, token string) (u
var (
aam = &authActionProps{
user: u,
- credentials: &types.Credentials{Kind: credentialsTypeResetPasswordToken},
+ credentials: &types.Credential{Kind: credentialsTypeResetPasswordToken},
}
)
@@ -850,7 +850,7 @@ func (svc auth) SendEmailAddressConfirmationToken(ctx context.Context, u *types.
aam = &authActionProps{
user: u,
- credentials: &types.Credentials{Kind: credentialsTypeEmailAuthToken},
+ credentials: &types.Credential{Kind: credentialsTypeEmailAuthToken},
}
)
@@ -948,7 +948,7 @@ func (svc auth) sendPasswordCreateToken(ctx context.Context, u *types.User) (url
}
// procLogin fn performs standard validation, credentials-update tasks and triggers events
-func (svc auth) procLogin(ctx context.Context, s store.Storer, u *types.User, c *types.Credentials, p *types.AuthProvider) (err error) {
+func (svc auth) procLogin(ctx context.Context, s store.Storer, u *types.User, c *types.Credential, p *types.AuthProvider) (err error) {
if err = svc.eventbus.WaitFor(ctx, event.AuthBeforeLogin(u, p)); err != nil {
return err
}
@@ -1005,7 +1005,7 @@ func (svc auth) procLogin(ctx context.Context, s store.Storer, u *types.User, c
if c != nil {
c.LastUsedAt = now()
- if err = store.UpdateCredentials(ctx, s, c); err != nil {
+ if err = store.UpdateCredential(ctx, s, c); err != nil {
return err
}
}
@@ -1018,7 +1018,7 @@ func (svc auth) procLogin(ctx context.Context, s store.Storer, u *types.User, c
func (svc auth) loadUserFromToken(ctx context.Context, token, kind string) (u *types.User, _ error) {
var (
aam = &authActionProps{
- credentials: &types.Credentials{Kind: kind},
+ credentials: &types.Credential{Kind: kind},
}
)
@@ -1028,7 +1028,7 @@ func (svc auth) loadUserFromToken(ctx context.Context, token, kind string) (u *t
return AuthErrInvalidToken(aam)
}
- c, err := store.LookupCredentialsByID(ctx, s, credentialsID)
+ c, err := store.LookupCredentialByID(ctx, s, credentialsID)
if errors.IsNotFound(err) {
return AuthErrInvalidToken(aam)
}
@@ -1039,7 +1039,7 @@ func (svc auth) loadUserFromToken(ctx context.Context, token, kind string) (u *t
return
}
- if err = store.DeleteCredentialsByID(ctx, s, c.ID); err != nil {
+ if err = store.DeleteCredentialByID(ctx, s, c.ID); err != nil {
return
}
@@ -1072,7 +1072,7 @@ func (svc auth) createUserToken(ctx context.Context, u *types.User, kind string)
expiresAt time.Time
aam = &authActionProps{
user: u,
- credentials: &types.Credentials{Kind: kind},
+ credentials: &types.Credential{Kind: kind},
}
)
@@ -1082,7 +1082,7 @@ func (svc auth) createUserToken(ctx context.Context, u *types.User, kind string)
}
// Rate limit requests
- cc, _, err := store.SearchCredentials(ctx, s, types.CredentialsFilter{
+ cc, _, err := store.SearchCredentials(ctx, s, types.CredentialFilter{
OwnerID: u.ID,
Kind: kind,
@@ -1132,7 +1132,7 @@ func (svc auth) createUserToken(ctx context.Context, u *types.User, kind string)
token = string(rand.Bytes(credentialsTokenLength))
}
- c := &types.Credentials{
+ c := &types.Credential{
ID: nextID(),
CreatedAt: *now(),
OwnerID: u.ID,
@@ -1141,7 +1141,7 @@ func (svc auth) createUserToken(ctx context.Context, u *types.User, kind string)
ExpiresAt: &expiresAt,
}
- err = store.CreateCredentials(ctx, s, c)
+ err = store.CreateCredential(ctx, s, c)
if err != nil {
return err
@@ -1163,7 +1163,7 @@ func (svc auth) createUserToken(ctx context.Context, u *types.User, kind string)
}
// checks existing tokens and ensure that the creation rate is within limits
-func (svc auth) checkTokenRate(cc types.CredentialsSet, window time.Duration, max int) error {
+func (svc auth) checkTokenRate(cc types.CredentialSet, window time.Duration, max int) error {
if len(cc) == 0 || window == 0 || max == 0 {
return nil
}
@@ -1193,10 +1193,9 @@ func (svc auth) checkTokenRate(cc types.CredentialsSet, window time.Duration, ma
return nil
}
-func (svc auth) cleanupCredentials(ctx context.Context, s store.Credentials, cc types.CredentialsSet) (err error) {
+func (svc auth) cleanupCredentials(ctx context.Context, s store.Credentials, cc types.CredentialSet) (err error) {
var (
- update types.CredentialsSet
- remove types.CredentialsSet
+ update, remove types.CredentialSet
)
for _, c := range cc {
@@ -1218,11 +1217,11 @@ func (svc auth) cleanupCredentials(ctx context.Context, s store.Credentials, cc
}
}
- if err = store.UpdateCredentials(ctx, s, update...); err != nil {
+ if err = store.UpdateCredential(ctx, s, update...); err != nil {
return
}
- if err = store.DeleteCredentials(ctx, s, remove...); err != nil {
+ if err = store.DeleteCredential(ctx, s, remove...); err != nil {
return
}
@@ -1261,10 +1260,10 @@ func (svc auth) autoPromote(ctx context.Context, u *types.User) (err error) {
// Fn fails if no secret is set
func (svc auth) ValidateTOTP(ctx context.Context, code string) (err error) {
var (
- c *types.Credentials
+ c *types.Credential
u *types.User
kind = credentialsTypeMfaTotpSecret
- aam = &authActionProps{credentials: &types.Credentials{Kind: kind}}
+ aam = &authActionProps{credentials: &types.Credential{Kind: kind}}
i = internalAuth.GetIdentityFromContext(ctx)
)
@@ -1290,7 +1289,7 @@ func (svc auth) ValidateTOTP(ctx context.Context, code string) (err error) {
return err
} else {
c.LastUsedAt = now()
- return store.UpdateCredentials(ctx, s, c)
+ return store.UpdateCredential(ctx, s, c)
}
})
@@ -1303,7 +1302,7 @@ func (svc auth) ValidateTOTP(ctx context.Context, code string) (err error) {
func (svc auth) ConfigureTOTP(ctx context.Context, secret string, code string) (u *types.User, err error) {
var (
kind = credentialsTypeMfaTotpSecret
- aam = &authActionProps{credentials: &types.Credentials{Kind: kind}}
+ aam = &authActionProps{credentials: &types.Credential{Kind: kind}}
i = internalAuth.GetIdentityFromContext(ctx)
)
@@ -1334,7 +1333,7 @@ func (svc auth) ConfigureTOTP(ctx context.Context, secret string, code string) (
return err
}
- cred := &types.Credentials{
+ cred := &types.Credential{
ID: nextID(),
CreatedAt: *now(),
OwnerID: u.ID,
@@ -1342,7 +1341,7 @@ func (svc auth) ConfigureTOTP(ctx context.Context, secret string, code string) (
Credentials: secret,
}
- if err = store.CreateCredentials(ctx, s, cred); err != nil {
+ if err = store.CreateCredential(ctx, s, cred); err != nil {
return err
}
@@ -1361,9 +1360,9 @@ func (svc auth) ConfigureTOTP(ctx context.Context, secret string, code string) (
// It returns the user with security policy changes
func (svc auth) RemoveTOTP(ctx context.Context, userID uint64, code string) (u *types.User, err error) {
var (
- c *types.Credentials
+ c *types.Credential
kind = credentialsTypeMfaTotpSecret
- aam = &authActionProps{credentials: &types.Credentials{Kind: kind}}
+ aam = &authActionProps{credentials: &types.Credential{Kind: kind}}
i = internalAuth.GetIdentityFromContext(ctx)
self = i != nil && i.Identity() == userID
)
@@ -1408,8 +1407,8 @@ func (svc auth) RemoveTOTP(ctx context.Context, userID uint64, code string) (u *
}
// Searches for all valid TOTP secret credentials
-func (svc auth) getTOTPSecret(ctx context.Context, s store.Credentials, userID uint64) (*types.Credentials, error) {
- cc, _, err := store.SearchCredentials(ctx, s, types.CredentialsFilter{
+func (svc auth) getTOTPSecret(ctx context.Context, s store.Credentials, userID uint64) (*types.Credential, error) {
+ cc, _, err := store.SearchCredentials(ctx, s, types.CredentialFilter{
OwnerID: userID,
Kind: credentialsTypeMfaTotpSecret,
Deleted: filter.StateExcluded,
@@ -1451,7 +1450,7 @@ func (auth) validateTOTP(secret string, code string) error {
// Revokes all existing user's TOTPs
func (auth) revokeAllTOTP(ctx context.Context, s store.Credentials, userID uint64) error {
// revoke (soft-delete) all existing secrets
- cc, _, err := store.SearchCredentials(ctx, s, types.CredentialsFilter{
+ cc, _, err := store.SearchCredentials(ctx, s, types.CredentialFilter{
OwnerID: userID,
Kind: credentialsTypeMfaTotpSecret,
Deleted: filter.StateExcluded,
@@ -1461,9 +1460,9 @@ func (auth) revokeAllTOTP(ctx context.Context, s store.Credentials, userID uint6
return err
}
- return cc.Walk(func(c *types.Credentials) error {
+ return cc.Walk(func(c *types.Credential) error {
c.DeletedAt = now()
- return store.UpdateCredentials(ctx, s, c)
+ return store.UpdateCredential(ctx, s, c)
})
}
@@ -1472,7 +1471,7 @@ func (svc auth) SendEmailOTP(ctx context.Context) (err error) {
otp string
u *types.User
kind = credentialsTypeMFAEmailOTP
- aam = &authActionProps{credentials: &types.Credentials{Kind: kind}}
+ aam = &authActionProps{credentials: &types.Credential{Kind: kind}}
i = internalAuth.GetIdentityFromContext(ctx)
)
@@ -1505,7 +1504,7 @@ func (svc auth) SendEmailOTP(ctx context.Context) (err error) {
func (svc auth) ConfigureEmailOTP(ctx context.Context, userID uint64, enable bool) (u *types.User, err error) {
var (
kind = credentialsTypeMFAEmailOTP
- aam = &authActionProps{credentials: &types.Credentials{Kind: kind}}
+ aam = &authActionProps{credentials: &types.Credential{Kind: kind}}
)
err = svc.store.Tx(ctx, func(ctx context.Context, s store.Storer) (err error) {
@@ -1534,10 +1533,10 @@ func (svc auth) ConfigureEmailOTP(ctx context.Context, userID uint64, enable boo
// ValidateEmailOTP issues a validation OTP
func (svc auth) ValidateEmailOTP(ctx context.Context, code string) (err error) {
var (
- cc types.CredentialsSet
+ cc types.CredentialSet
u *types.User
kind = credentialsTypeMFAEmailOTP
- aam = &authActionProps{credentials: &types.Credentials{Kind: kind}}
+ aam = &authActionProps{credentials: &types.Credential{Kind: kind}}
i = internalAuth.GetIdentityFromContext(ctx)
)
@@ -1559,7 +1558,7 @@ func (svc auth) ValidateEmailOTP(ctx context.Context, code string) (err error) {
return AuthErrInvalidEmailOTP()
}
- cc, _, err = store.SearchCredentials(ctx, s, types.CredentialsFilter{
+ cc, _, err = store.SearchCredentials(ctx, s, types.CredentialFilter{
OwnerID: u.ID,
Kind: kind,
Deleted: filter.StateExcluded,
@@ -1578,8 +1577,8 @@ func (svc auth) ValidateEmailOTP(ctx context.Context, code string) (err error) {
continue
}
- // Credentials found, remove it
- return store.DeleteCredentials(ctx, s, c)
+ // Credential found, remove it
+ return store.DeleteCredential(ctx, s, c)
}
return AuthErrInvalidEmailOTP()
diff --git a/system/service/auth_actions.gen.go b/system/service/auth_actions.gen.go
index c2d4ba424..e63db6b40 100644
--- a/system/service/auth_actions.gen.go
+++ b/system/service/auth_actions.gen.go
@@ -23,7 +23,7 @@ type (
authActionProps struct {
email string
provider string
- credentials *types.Credentials
+ credentials *types.Credential
role *types.Role
user *types.User
}
@@ -81,7 +81,7 @@ func (p *authActionProps) setProvider(provider string) *authActionProps {
//
// This function is auto-generated.
//
-func (p *authActionProps) setCredentials(credentials *types.Credentials) *authActionProps {
+func (p *authActionProps) setCredentials(credentials *types.Credential) *authActionProps {
p.credentials = credentials
return p
}
diff --git a/system/service/auth_actions.yaml b/system/service/auth_actions.yaml
index 4cd378a0c..cd9dc8891 100644
--- a/system/service/auth_actions.yaml
+++ b/system/service/auth_actions.yaml
@@ -16,7 +16,7 @@ props:
- name: email
- name: provider
- name: credentials
- type: "*types.Credentials"
+ type: "*types.Credential"
fields: [ kind, label, ID ]
- name: role
type: "*types.Role"
diff --git a/system/service/auth_test.go b/system/service/auth_test.go
index 3ef5973c6..f498fac36 100644
--- a/system/service/auth_test.go
+++ b/system/service/auth_test.go
@@ -9,7 +9,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/eventbus"
"github.com/cortezaproject/corteza-server/pkg/id"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/markbates/goth"
"github.com/stretchr/testify/require"
@@ -22,7 +22,7 @@ func makeMockAuthService() *auth {
var (
ctx = context.Background()
- mem, err = sqlite3.ConnectInMemory(ctx)
+ mem, err = sqlite.ConnectInMemory(ctx)
svc = &auth{
providerValidator: func(s string) error {
@@ -61,7 +61,7 @@ func TestAuth_External(t *testing.T) {
return fmt.Sprintf("fresh-profile-id-%d", nextID())
}
- fooCredentials = &types.Credentials{
+ fooCredentials = &types.Credential{
ID: nextID(),
OwnerID: validUser.ID,
Label: "credentials for foo provider",
@@ -70,7 +70,7 @@ func TestAuth_External(t *testing.T) {
CreatedAt: time.Time{},
}
- barCredentials = &types.Credentials{
+ barCredentials = &types.Credential{
ID: nextID(),
OwnerID: validUser.ID,
Label: "credentials for bar provider",
@@ -108,7 +108,7 @@ func TestAuth_External(t *testing.T) {
req.NoError(svc.store.TruncateUsers(ctx))
req.NoError(svc.store.TruncateCredentials(ctx))
req.NoError(store.CreateUser(ctx, svc.store, validUser, suspendedUser))
- req.NoError(store.CreateCredentials(ctx, svc.store, fooCredentials, barCredentials))
+ req.NoError(store.CreateCredential(ctx, svc.store, fooCredentials, barCredentials))
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
@@ -359,10 +359,10 @@ func TestAuth_multiCreateUserTokenForPasswordReset(t *testing.T) {
validUser = &types.User{Email: "valid@test.cortezaproject.org", ID: nextID(), CreatedAt: *now(), EmailConfirmed: true}
// load credentials from token
- t2c = func(token string) *types.Credentials {
+ t2c = func(token string) *types.Credential {
id, _ := validateToken(token)
req.NotZero(id)
- c, err := store.LookupCredentialsByID(ctx, svc.store, id)
+ c, err := store.LookupCredentialByID(ctx, svc.store, id)
req.NoError(err)
return c
}
@@ -398,7 +398,7 @@ func Test_auth_checkPassword(t *testing.T) {
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(plainPassword), bcrypt.DefaultCost)
type args struct {
password string
- cc types.CredentialsSet
+ cc types.CredentialSet
}
tests := []struct {
name string
@@ -414,29 +414,29 @@ func Test_auth_checkPassword(t *testing.T) {
rval: false,
args: args{
password: " foo ",
- cc: types.CredentialsSet{&types.Credentials{ID: 1, Credentials: string(hashedPassword)}}}},
+ cc: types.CredentialSet{&types.Credential{ID: 1, Credentials: string(hashedPassword)}}}},
{
name: "invalid credentials",
rval: false,
args: args{
password: " foo ",
- cc: types.CredentialsSet{&types.Credentials{ID: 0, Credentials: string(hashedPassword)}}}},
+ cc: types.CredentialSet{&types.Credential{ID: 0, Credentials: string(hashedPassword)}}}},
{
name: "ok",
rval: true,
args: args{
password: plainPassword,
- cc: types.CredentialsSet{&types.Credentials{ID: 1, Credentials: string(hashedPassword)}}}},
+ cc: types.CredentialSet{&types.Credential{ID: 1, Credentials: string(hashedPassword)}}}},
{
name: "multipass",
rval: true,
args: args{
password: plainPassword,
- cc: types.CredentialsSet{
- &types.Credentials{ID: 0, Credentials: string(hashedPassword)},
- &types.Credentials{ID: 1, Credentials: "$2a$10$8sOZxfZinxnu3bAtpkqEx.wBBwOfci6aG1szgUyxm5.BL2WiLu.ni"},
- &types.Credentials{ID: 2, Credentials: string(hashedPassword)},
- &types.Credentials{ID: 3, Credentials: ""},
+ cc: types.CredentialSet{
+ &types.Credential{ID: 0, Credentials: string(hashedPassword)},
+ &types.Credential{ID: 1, Credentials: "$2a$10$8sOZxfZinxnu3bAtpkqEx.wBBwOfci6aG1szgUyxm5.BL2WiLu.ni"},
+ &types.Credential{ID: 2, Credentials: string(hashedPassword)},
+ &types.Credential{ID: 3, Credentials: ""},
}}},
}
diff --git a/system/service/settings.go b/system/service/settings.go
index 0b0a20146..eb2be88c3 100644
--- a/system/service/settings.go
+++ b/system/service/settings.go
@@ -17,7 +17,7 @@ import (
type (
settings struct {
- store store.Settings
+ store store.SettingValues
accessControl accessController
logger *zap.Logger
m sync.RWMutex
@@ -49,7 +49,7 @@ var (
ErrNoManagePermission = fmt.Errorf("not allowed to manage settings")
)
-func Settings(ctx context.Context, s store.Settings, log *zap.Logger, ac accessController, current interface{}) *settings {
+func Settings(ctx context.Context, s store.SettingValues, log *zap.Logger, ac accessController, current interface{}) *settings {
svc := &settings{
store: s,
accessControl: ac,
@@ -132,7 +132,7 @@ func (svc *settings) findByPrefix(ctx context.Context, pp ...string) (types.Sett
}
)
- vv, _, err := store.SearchSettings(ctx, svc.store, f)
+ vv, _, err := store.SearchSettingValues(ctx, svc.store, f)
return vv, err
}
@@ -141,7 +141,7 @@ func (svc *settings) Get(ctx context.Context, name string, ownedBy uint64) (out
return nil, ErrNoReadPermission
}
- out, err = store.LookupSettingByNameOwnedBy(ctx, svc.store, name, ownedBy)
+ out, err = store.LookupSettingValueByNameOwnedBy(ctx, svc.store, name, ownedBy)
if err != nil && !errors.IsNotFound(err) {
return nil, err
}
@@ -182,17 +182,17 @@ func (svc *settings) Set(ctx context.Context, v *types.SettingValue) (err error)
}
var current *types.SettingValue
- current, err = store.LookupSettingByNameOwnedBy(ctx, svc.store, v.Name, v.OwnedBy)
+ current, err = store.LookupSettingValueByNameOwnedBy(ctx, svc.store, v.Name, v.OwnedBy)
if errors.IsNotFound(err) {
v.UpdatedAt = *now()
- err = store.CreateSetting(ctx, svc.store, v)
+ err = store.CreateSettingValue(ctx, svc.store, v)
} else if err != nil {
return err
}
if !current.Eq(v) {
v.UpdatedAt = *now()
- err = store.UpdateSetting(ctx, svc.store, v)
+ err = store.UpdateSettingValue(ctx, svc.store, v)
}
if err != nil || current.Eq(v) {
@@ -224,15 +224,15 @@ func (svc *settings) BulkSet(ctx context.Context, vv types.SettingValueSet) (err
new = current.New(vv)
}
- if err = store.UpdateSetting(ctx, svc.store, old...); err != nil {
+ if err = store.UpdateSettingValue(ctx, svc.store, old...); err != nil {
return
}
- if err = store.CreateSetting(ctx, svc.store, new...); err != nil {
+ if err = store.CreateSettingValue(ctx, svc.store, new...); err != nil {
return
}
- if err = store.DeleteSetting(ctx, svc.store, vv.Trash()...); err != nil {
+ if err = store.DeleteSettingValue(ctx, svc.store, vv.Trash()...); err != nil {
return
}
@@ -257,14 +257,14 @@ func (svc *settings) Delete(ctx context.Context, name string, ownedBy uint64) er
return ErrNoManagePermission
}
- current, err := store.LookupSettingByNameOwnedBy(ctx, svc.store, name, ownedBy)
+ current, err := store.LookupSettingValueByNameOwnedBy(ctx, svc.store, name, ownedBy)
if errors.IsNotFound(err) {
return nil
} else if err != nil {
return err
}
- err = store.DeleteSetting(ctx, svc.store, current)
+ err = store.DeleteSettingValue(ctx, svc.store, current)
if err != nil {
return err
}
diff --git a/system/service/user_test.go b/system/service/user_test.go
index e14524da4..25b3c5880 100644
--- a/system/service/user_test.go
+++ b/system/service/user_test.go
@@ -8,7 +8,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/eventbus"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
@@ -34,7 +34,7 @@ func TestUser_ProtectedSearch(t *testing.T) {
s store.Storer
)
- if s, err = sqlite3.ConnectInMemory(ctx); err != nil {
+ if s, err = sqlite.ConnectInMemory(ctx); err != nil {
req.NoError(err)
} else if err = store.Upgrade(ctx, zap.NewNop(), s); err != nil {
req.NoError(err)
diff --git a/system/settings.cue b/system/settings.cue
new file mode 100644
index 000000000..8da9e0e0f
--- /dev/null
+++ b/system/settings.cue
@@ -0,0 +1,55 @@
+package system
+
+import (
+ "github.com/cortezaproject/corteza-server/codegen/schema"
+)
+
+settings: schema.#Resource & {
+ ident: "settingValue"
+ expIdent: "SettingValue"
+
+ features: {
+ labels: false
+ paging: false
+ sorting: false
+ checkFn: false
+ }
+
+ struct: {
+ name: { primaryKey: true, ignoreCase: true }
+ owned_by: { primaryKey: true, goType: "uint64", storeIdent: "rel_owner" }
+ value: { goType: "rawJson" }
+ updated_by: { goType: "uint64" }
+ updated_at: schema.SortableTimestampField
+ }
+
+ filter: {
+ expIdent: "SettingsFilter"
+
+ struct: {
+ prefix: {}
+ owned_by: { goType: "uint64", storeIdent: "rel_owner" }
+ }
+
+ byValue: [ "owned_by" ]
+ }
+
+ store: {
+ settings: {
+ rdbms: {
+ table: "settings"
+ }
+ }
+
+ api: {
+ lookups: [
+ {
+ fields: ["name", "owned_by"]
+ description: """
+ searches for settings by name and owner
+ """
+ }
+ ]
+ }
+ }
+}
diff --git a/system/template.cue b/system/template.cue
index c6f0e460b..10b813ccd 100644
--- a/system/template.cue
+++ b/system/template.cue
@@ -4,7 +4,37 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-template: schema.#resource & {
+template: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ language: {goType: "string"}
+ type: {goType: "types.DocumentType"}
+ partial: {goType: "bool"}
+ meta: {goType: "types.TemplateMeta"}
+ template: {goType: "string"}
+
+ owner_id: { ident: "ownerID", goType: "uint64", storeIdent: "rel_owner" }
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ last_used_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ template_id: {goType: "[]uint64", ident: "templateID", storeIdent: "id"}
+ handle: {goType: "string"}
+ type: {goType: "string"}
+ owner_id: {goType: "uint64", storeIdent: "rel_owner", ident: "ownerID" }
+ partial: {goType: "bool"}
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ }
+
+ byValue: ["template_id", "handle", "partial", "type", "owner_id"]
+ byNilState: ["deleted"]
+ }
+
rbac: {
operations: {
read: description: "Read template"
@@ -13,4 +43,28 @@ template: schema.#resource & {
render: description: "Render template"
}
}
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for template by ID
+
+ It also returns deleted templates.
+ """
+ }, {
+ fields: ["handle"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for template by handle
+
+ It returns only valid templates (not deleted)
+ """
+ },
+ ]
+ }
+ }
}
diff --git a/system/types/attachment.go b/system/types/attachment.go
index 30dcab023..9057118b6 100644
--- a/system/types/attachment.go
+++ b/system/types/attachment.go
@@ -3,9 +3,10 @@ package types
import (
"database/sql/driver"
"encoding/json"
- "github.com/cortezaproject/corteza-server/pkg/filter"
"time"
+ "github.com/cortezaproject/corteza-server/pkg/filter"
+
"github.com/pkg/errors"
)
@@ -17,7 +18,7 @@ type (
Url string `json:"url,omitempty"`
PreviewUrl string `json:"previewUrl,omitempty"`
Name string `json:"name,omitempty"`
- Meta attachmentMeta `json:"meta"`
+ Meta AttachmentMeta `json:"meta"`
CreatedAt time.Time `json:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
@@ -40,22 +41,22 @@ type (
filter.Paging
}
- attachmentImageMeta struct {
+ AttachmentImageMeta struct {
Width int `json:"width,omitempty"`
Height int `json:"height,omitempty"`
Animated bool `json:"animated"`
}
- attachmentFileMeta struct {
+ AttachmentFileMeta struct {
Size int64 `json:"size"`
Extension string `json:"ext"`
Mimetype string `json:"mimetype"`
- Image *attachmentImageMeta `json:"image,omitempty"`
+ Image *AttachmentImageMeta `json:"image,omitempty"`
}
- attachmentMeta struct {
- Original attachmentFileMeta `json:"original"`
- Preview *attachmentFileMeta `json:"preview,omitempty"`
+ AttachmentMeta struct {
+ Original AttachmentFileMeta `json:"original"`
+ Preview *AttachmentFileMeta `json:"preview,omitempty"`
Labels map[string]string `json:"labels,omitempty"`
}
)
@@ -64,23 +65,23 @@ const (
AttachmentKindSettings string = "settings"
)
-func (a *Attachment) SetOriginalImageMeta(width, height int, animated bool) *attachmentFileMeta {
+func (a *Attachment) SetOriginalImageMeta(width, height int, animated bool) *AttachmentFileMeta {
a.imageMeta(&a.Meta.Original, width, height, animated)
return &a.Meta.Original
}
-func (a *Attachment) SetPreviewImageMeta(width, height int, animated bool) *attachmentFileMeta {
+func (a *Attachment) SetPreviewImageMeta(width, height int, animated bool) *AttachmentFileMeta {
if a.Meta.Preview == nil {
- a.Meta.Preview = &attachmentFileMeta{}
+ a.Meta.Preview = &AttachmentFileMeta{}
}
a.imageMeta(a.Meta.Preview, width, height, animated)
return a.Meta.Preview
}
-func (a *Attachment) imageMeta(in *attachmentFileMeta, width, height int, animated bool) {
+func (a *Attachment) imageMeta(in *AttachmentFileMeta, width, height int, animated bool) {
if in.Image == nil {
- in.Image = &attachmentImageMeta{}
+ in.Image = &AttachmentImageMeta{}
}
if width > 0 && height > 0 {
@@ -90,11 +91,11 @@ func (a *Attachment) imageMeta(in *attachmentFileMeta, width, height int, animat
}
}
-func (meta *attachmentMeta) Scan(value interface{}) error {
+func (meta *AttachmentMeta) Scan(value interface{}) error {
//lint:ignore S1034 This typecast is intentional, we need to get []byte out of a []uint8
switch value.(type) {
case nil:
- *meta = attachmentMeta{}
+ *meta = AttachmentMeta{}
case []uint8:
if err := json.Unmarshal(value.([]byte), meta); err != nil {
return errors.Wrapf(err, "cannot scan '%v' into attachmentMeta", value)
@@ -104,6 +105,6 @@ func (meta *attachmentMeta) Scan(value interface{}) error {
return nil
}
-func (meta attachmentMeta) Value() (driver.Value, error) {
+func (meta AttachmentMeta) Value() (driver.Value, error) {
return json.Marshal(meta)
}
diff --git a/system/types/auth_client.go b/system/types/auth_client.go
index f1be51e02..811909770 100644
--- a/system/types/auth_client.go
+++ b/system/types/auth_client.go
@@ -111,6 +111,7 @@ type (
AuthConfirmedClientFilter struct {
UserID uint64
+ Limit uint
}
)
diff --git a/system/types/auth_oa2token.go b/system/types/auth_oa2token.go
index 286f067ca..85f215109 100644
--- a/system/types/auth_oa2token.go
+++ b/system/types/auth_oa2token.go
@@ -23,5 +23,6 @@ type (
AuthOa2tokenFilter struct {
UserID uint64
+ Limit uint
}
)
diff --git a/system/types/auth_session.go b/system/types/auth_session.go
index 321a2cfd8..0541d35a8 100644
--- a/system/types/auth_session.go
+++ b/system/types/auth_session.go
@@ -17,5 +17,6 @@ type (
AuthSessionFilter struct {
UserID uint64
+ Limit uint
}
)
diff --git a/system/types/credentials.go b/system/types/credential.go
similarity index 86%
rename from system/types/credentials.go
rename to system/types/credential.go
index da0a895e7..be7779bba 100644
--- a/system/types/credentials.go
+++ b/system/types/credential.go
@@ -9,7 +9,7 @@ import (
)
type (
- Credentials struct {
+ Credential struct {
ID uint64 `json:"credentialsID,string"`
OwnerID uint64 `json:"ownerID,string"`
Label string `json:"label"`
@@ -23,22 +23,23 @@ type (
DeletedAt *time.Time `json:"deletedAt,omitempty"`
}
- CredentialsFilter struct {
+ CredentialFilter struct {
OwnerID uint64 `json:"ownerID"`
Kind string `json:"kind"`
Credentials string `json:"credentials"`
Deleted filter.State `json:"deleted"`
+ Limit uint
}
)
-func (u *Credentials) Valid() bool {
+func (u *Credential) Valid() bool {
return u.ID > 0 && (u.ExpiresAt == nil || u.ExpiresAt.After(time.Now())) && u.DeletedAt == nil
}
// CompareHashAndPassword returns first valid credentials with matching hash
-func (cc CredentialsSet) CompareHashAndPassword(password string) *Credentials {
+func (set CredentialSet) CompareHashAndPassword(password string) *Credential {
// We need only valid credentials (skip deleted, expired)
- for _, c := range cc {
+ for _, c := range set {
if !c.Valid() {
continue
}
diff --git a/system/types/resource_translation.go b/system/types/resource_translation.go
index 90ea6e463..bb502cf80 100644
--- a/system/types/resource_translation.go
+++ b/system/types/resource_translation.go
@@ -30,11 +30,11 @@ type (
}
ResourceTranslationFilter struct {
- TranslationID []uint `json:"translationID"`
- Lang string `json:"lang"`
- Resource string `json:"resource"`
- ResourceType string `json:"resourceType"`
- OwnerID uint64 `json:"ownerID,string"`
+ TranslationID []uint64 `json:"translationID"`
+ Lang string `json:"lang"`
+ Resource string `json:"resource"`
+ ResourceType string `json:"resourceType"`
+ OwnerID uint64 `json:"ownerID,string"`
Deleted filter.State `json:"deleted"`
diff --git a/system/types/role_members.go b/system/types/role_members.go
index 49992e255..81dc0c01f 100644
--- a/system/types/role_members.go
+++ b/system/types/role_members.go
@@ -9,5 +9,6 @@ type (
RoleMemberFilter struct {
RoleID uint64
UserID uint64
+ Limit uint
}
)
diff --git a/system/types/settings.go b/system/types/settings.go
index d4f57c821..4c63ef198 100644
--- a/system/types/settings.go
+++ b/system/types/settings.go
@@ -32,6 +32,8 @@ type (
//
// Store then loads additional resources to satisfy the paging parameters
Check func(*SettingValue) (bool, error) `json:"-"`
+
+ Limit uint `json:"-"`
}
SettingsKV map[string]types.JSONText
diff --git a/system/types/type_set.gen.go b/system/types/type_set.gen.go
index 07c00aa9c..1a8cb7590 100644
--- a/system/types/type_set.gen.go
+++ b/system/types/type_set.gen.go
@@ -60,10 +60,10 @@ type (
// This type is auto-generated.
AuthSessionSet []*AuthSession
- // CredentialsSet slice of Credentials
+ // CredentialSet slice of Credential
//
// This type is auto-generated.
- CredentialsSet []*Credentials
+ CredentialSet []*Credential
// QueueSet slice of Queue
//
@@ -572,10 +572,10 @@ func (set AuthSessionSet) Filter(f func(*AuthSession) (bool, error)) (out AuthSe
return
}
-// Walk iterates through every slice item and calls w(Credentials) err
+// Walk iterates through every slice item and calls w(Credential) err
//
// This function is auto-generated.
-func (set CredentialsSet) Walk(w func(*Credentials) error) (err error) {
+func (set CredentialSet) Walk(w func(*Credential) error) (err error) {
for i := range set {
if err = w(set[i]); err != nil {
return
@@ -585,12 +585,12 @@ func (set CredentialsSet) Walk(w func(*Credentials) error) (err error) {
return
}
-// Filter iterates through every slice item, calls f(Credentials) (bool, err) and return filtered slice
+// Filter iterates through every slice item, calls f(Credential) (bool, err) and return filtered slice
//
// This function is auto-generated.
-func (set CredentialsSet) Filter(f func(*Credentials) (bool, error)) (out CredentialsSet, err error) {
+func (set CredentialSet) Filter(f func(*Credential) (bool, error)) (out CredentialSet, err error) {
var ok bool
- out = CredentialsSet{}
+ out = CredentialSet{}
for i := range set {
if ok, err = f(set[i]); err != nil {
return
@@ -605,7 +605,7 @@ func (set CredentialsSet) Filter(f func(*Credentials) (bool, error)) (out Creden
// FindByID finds items from slice by its ID property
//
// This function is auto-generated.
-func (set CredentialsSet) FindByID(ID uint64) *Credentials {
+func (set CredentialSet) FindByID(ID uint64) *Credential {
for i := range set {
if set[i].ID == ID {
return set[i]
@@ -618,7 +618,7 @@ func (set CredentialsSet) FindByID(ID uint64) *Credentials {
// IDs returns a slice of uint64s from all items in the set
//
// This function is auto-generated.
-func (set CredentialsSet) IDs() (IDs []uint64) {
+func (set CredentialSet) IDs() (IDs []uint64) {
IDs = make([]uint64, len(set))
for i := range set {
diff --git a/system/types/type_set.gen_test.go b/system/types/type_set.gen_test.go
index fa37d1990..2115813b8 100644
--- a/system/types/type_set.gen_test.go
+++ b/system/types/type_set.gen_test.go
@@ -778,33 +778,33 @@ func TestAuthSessionSetFilter(t *testing.T) {
}
}
-func TestCredentialsSetWalk(t *testing.T) {
+func TestCredentialSetWalk(t *testing.T) {
var (
- value = make(CredentialsSet, 3)
+ value = make(CredentialSet, 3)
req = require.New(t)
)
// check walk with no errors
{
- err := value.Walk(func(*Credentials) error {
+ err := value.Walk(func(*Credential) error {
return nil
})
req.NoError(err)
}
// check walk with error
- req.Error(value.Walk(func(*Credentials) error { return fmt.Errorf("walk error") }))
+ req.Error(value.Walk(func(*Credential) error { return fmt.Errorf("walk error") }))
}
-func TestCredentialsSetFilter(t *testing.T) {
+func TestCredentialSetFilter(t *testing.T) {
var (
- value = make(CredentialsSet, 3)
+ value = make(CredentialSet, 3)
req = require.New(t)
)
// filter nothing
{
- set, err := value.Filter(func(*Credentials) (bool, error) {
+ set, err := value.Filter(func(*Credential) (bool, error) {
return true, nil
})
req.NoError(err)
@@ -814,7 +814,7 @@ func TestCredentialsSetFilter(t *testing.T) {
// filter one item
{
found := false
- set, err := value.Filter(func(*Credentials) (bool, error) {
+ set, err := value.Filter(func(*Credential) (bool, error) {
if !found {
found = true
return found, nil
@@ -827,23 +827,23 @@ func TestCredentialsSetFilter(t *testing.T) {
// filter error
{
- _, err := value.Filter(func(*Credentials) (bool, error) {
+ _, err := value.Filter(func(*Credential) (bool, error) {
return false, fmt.Errorf("filter error")
})
req.Error(err)
}
}
-func TestCredentialsSetIDs(t *testing.T) {
+func TestCredentialSetIDs(t *testing.T) {
var (
- value = make(CredentialsSet, 3)
+ value = make(CredentialSet, 3)
req = require.New(t)
)
// construct objects
- value[0] = new(Credentials)
- value[1] = new(Credentials)
- value[2] = new(Credentials)
+ value[0] = new(Credential)
+ value[1] = new(Credential)
+ value[2] = new(Credential)
// set ids
value[0].ID = 1
value[1].ID = 2
diff --git a/system/types/types.yaml b/system/types/types.yaml
index 1b5b6d5c3..fcab2af1c 100644
--- a/system/types/types.yaml
+++ b/system/types/types.yaml
@@ -14,7 +14,7 @@ types:
labelResourceType: role
RoleMember:
noIdField: true
- Credentials: {}
+ Credential: {}
Reminder: {}
Attachment: {}
SettingValue:
diff --git a/system/types/user.go b/system/types/user.go
index 05e476e2c..626dd7e40 100644
--- a/system/types/user.go
+++ b/system/types/user.go
@@ -167,6 +167,11 @@ func (meta *UserMeta) Scan(value interface{}) error {
return errors.Wrapf(err, "cannot scan '%v' into User.Meta", value)
}
return nil
+ case string:
+ if err := json.Unmarshal([]byte(value.(string)), meta); err != nil {
+ return errors.Wrapf(err, "cannot scan '%v' into User.Meta", value)
+ }
+ return nil
}
return errors.Errorf("User.Meta: unknown type %T, expected []uint8", value)
}
diff --git a/system/user.cue b/system/user.cue
index 4614eb4c0..9e15c02fa 100644
--- a/system/user.cue
+++ b/system/user.cue
@@ -4,19 +4,41 @@ import (
"github.com/cortezaproject/corteza-server/codegen/schema"
)
-user: schema.#resource & {
- // fields: {
- // ID: schema.IdField
- // handle: schema.HandleField
- // email: { unique: true }
- // kind: {}
- // meta: {
- // note: type: string
- // sub: {
- // sub: { "non-unique-string-named-sub": {} }
- // }
- // }
- // }
+user: schema.#Resource & {
+ struct: {
+ id: schema.IdField
+ handle: schema.HandleField
+ email: {unique: true, ignoreCase: true}
+ email_confirmed: {goType: "bool"}
+ username: {unique: true, ignoreCase: true}
+ name: {}
+ kind: {goType: "types.UserKind"}
+ meta: {goType: "*types.UserMeta"}
+ created_at: schema.SortableTimestampField
+ updated_at: schema.SortableTimestampNilField
+ deleted_at: schema.SortableTimestampNilField
+ suspended_at: schema.SortableTimestampNilField
+ }
+
+ filter: {
+ struct: {
+ user_id: {goType: "[]uint64", ident: "userID", storeIdent: "id"}
+ role_id: {goType: "[]uint64", ident: "roleID"}
+ email: {goType: "string"}
+ name: {goType: "string"}
+ username: {goType: "string"}
+ handle: {goType: "string"}
+ kind: {goType: "types.UserKind"}
+ allKinds: {goType: "bool"}
+
+ deleted: {goType: "filter.State", storeIdent: "deleted_at"}
+ suspended: {goType: "filter.State", storeIdent: "suspended_at"}
+ }
+
+ query: ["email", "username", "handle", "name"]
+ byValue: ["user_id", "email", "username", "handle"]
+ byNilState: ["deleted", "suspended"]
+ }
rbac: {
operations: {
@@ -30,4 +52,57 @@ user: schema.#resource & {
"impersonate": description: "Impersonate user"
}
}
+
+ store: {
+ api: {
+ lookups: [
+ {
+ fields: ["id"]
+ description: """
+ searches for user by ID
+
+ It returns user even if deleted or suspended
+ """
+ }, {
+ fields: ["email"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for user by email
+
+ It returns only valid user (not deleted, not suspended)
+ """
+ }, {
+ fields: ["handle"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for user by handle
+
+ It returns only valid user (not deleted, not suspended)
+ """
+ }, {
+ fields: ["username"]
+ nullConstraint: ["deleted_at"]
+ constraintCheck: true
+ description: """
+ searches for user by username
+
+ It returns only valid user (not deleted, not suspended)
+ """
+ },
+ ]
+
+ functions: [
+ {
+ expIdent: "CountUsers"
+ args: [ {ident: "u", goType: "types.UserFilter"}]
+ return: [ "uint"]
+ }, {
+ expIdent: "UserMetrics"
+ return: [ "*types.UserMetrics"]
+ },
+ ]
+ }
+ }
}
diff --git a/tests/apigw/main_test.go b/tests/apigw/main_test.go
index f6a675cc9..30fefc3d5 100644
--- a/tests/apigw/main_test.go
+++ b/tests/apigw/main_test.go
@@ -25,7 +25,6 @@ import (
"github.com/cortezaproject/corteza-server/pkg/logger"
"github.com/cortezaproject/corteza-server/pkg/options"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
"github.com/cortezaproject/corteza-server/system/rest"
"github.com/cortezaproject/corteza-server/system/service"
sysTypes "github.com/cortezaproject/corteza-server/system/types"
@@ -63,7 +62,7 @@ func InitTestApp() {
if testApp == nil {
testApp = helpers.NewIntegrationTestApp(ctx, func(app *app.CortezaApp) (err error) {
- service.DefaultStore, err = sqlite3.ConnectInMemory(ctx)
+ service.DefaultStore, err = sqlite.ConnectInMemory(ctx)
if err != nil {
return err
}
diff --git a/tests/automation/main_test.go b/tests/automation/main_test.go
index 9a0311ddf..b83bbb9d6 100644
--- a/tests/automation/main_test.go
+++ b/tests/automation/main_test.go
@@ -20,7 +20,6 @@ import (
"github.com/cortezaproject/corteza-server/pkg/logger"
"github.com/cortezaproject/corteza-server/pkg/rand"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
sysTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/cortezaproject/corteza-server/tests/helpers"
"github.com/go-chi/chi/v5"
@@ -67,7 +66,7 @@ func InitTestApp() {
ctx := cli.Context()
testApp = helpers.NewIntegrationTestApp(ctx, func(app *app.CortezaApp) (err error) {
- service.DefaultStore, err = sqlite3.ConnectInMemory(ctx)
+ service.DefaultStore, err = sqlite.ConnectInMemory(ctx)
if err != nil {
return err
}
diff --git a/tests/compose/main_test.go b/tests/compose/main_test.go
index b23ff6b0e..805d91197 100644
--- a/tests/compose/main_test.go
+++ b/tests/compose/main_test.go
@@ -191,11 +191,11 @@ func cleanup(t *testing.T) {
)
err := collect(
- defStore.TruncateComposeNamespaces(ctx),
- defStore.TruncateComposePages(ctx),
- defStore.TruncateComposeModuleFields(ctx),
- defStore.TruncateComposeModules(ctx),
- defStore.TruncateComposeRecords(ctx, nil),
+ store.TruncateComposeNamespaces(ctx, defStore),
+ store.TruncateComposePages(ctx, defStore),
+ store.TruncateComposeModuleFields(ctx, defStore),
+ store.TruncateComposeModules(ctx, defStore),
+ store.TruncateComposeRecords(ctx, defStore, nil),
)
if err != nil {
t.Fatalf("failed to decode scenario data: %v", err)
diff --git a/tests/envoy/main.go b/tests/envoy/main.go
index 5f87b3c36..634da60d6 100644
--- a/tests/envoy/main.go
+++ b/tests/envoy/main.go
@@ -22,7 +22,7 @@ import (
"github.com/cortezaproject/corteza-server/pkg/provision"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
+ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
stypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
@@ -95,25 +95,25 @@ func encode(ctx context.Context, s store.Storer, nn []resource.Interface) error
func truncateStore(ctx context.Context, s store.Storer, t *testing.T) {
err := collect(
- s.TruncateComposeNamespaces(ctx),
- s.TruncateComposeModules(ctx),
- s.TruncateComposeModuleFields(ctx),
- s.TruncateComposeRecords(ctx, nil),
- s.TruncateComposePages(ctx),
- s.TruncateComposeCharts(ctx),
+ store.TruncateComposeNamespaces(ctx, s),
+ store.TruncateComposeModules(ctx, s),
+ store.TruncateComposeModuleFields(ctx, s),
+ store.TruncateComposeRecords(ctx, s, nil),
+ store.TruncateComposePages(ctx, s),
+ store.TruncateComposeCharts(ctx, s),
- s.TruncateRoles(ctx),
- s.TruncateUsers(ctx),
- s.TruncateTemplates(ctx),
- s.TruncateApplications(ctx),
- s.TruncateApigwRoutes(ctx),
- s.TruncateApigwFilters(ctx),
- s.TruncateReports(ctx),
- s.TruncateSettings(ctx),
- s.TruncateRbacRules(ctx),
+ store.TruncateRoles(ctx, s),
+ store.TruncateUsers(ctx, s),
+ store.TruncateTemplates(ctx, s),
+ store.TruncateApplications(ctx, s),
+ store.TruncateApigwRoutes(ctx, s),
+ store.TruncateApigwFilters(ctx, s),
+ store.TruncateReports(ctx, s),
+ store.TruncateSettingValues(ctx, s),
+ store.TruncateRbacRules(ctx, s),
- s.TruncateAutomationWorkflows(ctx),
- s.TruncateAutomationTriggers(ctx),
+ store.TruncateAutomationWorkflows(ctx, s),
+ store.TruncateAutomationTriggers(ctx, s),
)
if err != nil {
t.Fatal(err.Error())
@@ -130,7 +130,7 @@ func initServices(ctx context.Context, t *testing.T) store.Storer {
err error
)
- s, err = sqlite3.ConnectInMemoryWithDebug(ctx)
+ s, err = sqlite.ConnectInMemoryWithDebug(ctx)
if err != nil {
t.Fatalf("failed to init sqlite in-memory db: %v", err)
}
diff --git a/tests/helpers/app.go b/tests/helpers/app.go
index c829df0a7..776f40297 100644
--- a/tests/helpers/app.go
+++ b/tests/helpers/app.go
@@ -12,7 +12,7 @@ import (
"github.com/cortezaproject/corteza-server/system/types"
// Explicitly register SQLite (not done in the app as for testing only)
- _ "github.com/cortezaproject/corteza-server/store/sqlite3"
+ _ "github.com/cortezaproject/corteza-server/store/adapters/rdbms/drivers/sqlite"
)
func NewIntegrationTestApp(ctx context.Context, initTestServices func(*app.CortezaApp) error) *app.CortezaApp {
diff --git a/tests/messagebus/main_test.go b/tests/messagebus/main_test.go
index 18f5e2abd..b168db4bf 100644
--- a/tests/messagebus/main_test.go
+++ b/tests/messagebus/main_test.go
@@ -16,7 +16,6 @@ import (
"github.com/cortezaproject/corteza-server/pkg/messagebus"
"github.com/cortezaproject/corteza-server/pkg/options"
"github.com/cortezaproject/corteza-server/pkg/rand"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
"github.com/cortezaproject/corteza-server/system/service"
sysTypes "github.com/cortezaproject/corteza-server/system/types"
"github.com/cortezaproject/corteza-server/tests/helpers"
@@ -61,7 +60,7 @@ func InitTestApp() {
ctx := cli.Context()
testApp = helpers.NewIntegrationTestApp(ctx, func(app *app.CortezaApp) (err error) {
- service.DefaultStore, err = sqlite3.ConnectInMemory(ctx)
+ service.DefaultStore, err = sqlite.ConnectInMemory(ctx)
if err != nil {
return err
diff --git a/tests/system/main_test.go b/tests/system/main_test.go
index f1aa82263..749ffd36a 100644
--- a/tests/system/main_test.go
+++ b/tests/system/main_test.go
@@ -24,7 +24,6 @@ import (
"github.com/cortezaproject/corteza-server/pkg/rand"
"github.com/cortezaproject/corteza-server/pkg/rbac"
"github.com/cortezaproject/corteza-server/store"
- "github.com/cortezaproject/corteza-server/store/sqlite3"
"github.com/cortezaproject/corteza-server/system/rest"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
@@ -87,7 +86,7 @@ func InitTestApp() {
return err
}
- service.DefaultStore, err = sqlite3.ConnectInMemory(ctx)
+ service.DefaultStore, err = sqlite.ConnectInMemory(ctx)
if err != nil {
return err
}
diff --git a/vendor/github.com/Masterminds/squirrel/.gitignore b/vendor/github.com/Masterminds/squirrel/.gitignore
deleted file mode 100644
index 4a0699f0b..000000000
--- a/vendor/github.com/Masterminds/squirrel/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-squirrel.test
\ No newline at end of file
diff --git a/vendor/github.com/Masterminds/squirrel/.travis.yml b/vendor/github.com/Masterminds/squirrel/.travis.yml
deleted file mode 100644
index 7bb6da487..000000000
--- a/vendor/github.com/Masterminds/squirrel/.travis.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-language: go
-
-go:
- - 1.11.x
- - 1.12.x
- - 1.13.x
-
-services:
- - mysql
- - postgresql
-
-# Setting sudo access to false will let Travis CI use containers rather than
-# VMs to run the tests. For more details see:
-# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/
-# - http://docs.travis-ci.com/user/workers/standard-infrastructure/
-sudo: false
-
-before_script:
- - mysql -e 'CREATE DATABASE squirrel;'
- - psql -c 'CREATE DATABASE squirrel;' -U postgres
-
-script:
- - go test
- - cd integration
- - go test -args -driver sqlite3
- - go test -args -driver mysql -dataSource travis@/squirrel
- - go test -args -driver postgres -dataSource 'postgres://postgres@localhost/squirrel?sslmode=disable'
-
-notifications:
- irc: "irc.freenode.net#masterminds"
diff --git a/vendor/github.com/Masterminds/squirrel/LICENSE.txt b/vendor/github.com/Masterminds/squirrel/LICENSE.txt
deleted file mode 100644
index 74c20a2b9..000000000
--- a/vendor/github.com/Masterminds/squirrel/LICENSE.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-Squirrel
-The Masterminds
-Copyright (C) 2014-2015, Lann Martin
-Copyright (C) 2015-2016, Google
-Copyright (C) 2015, Matt Farina and Matt Butcher
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/vendor/github.com/Masterminds/squirrel/README.md b/vendor/github.com/Masterminds/squirrel/README.md
deleted file mode 100644
index 1d37f282f..000000000
--- a/vendor/github.com/Masterminds/squirrel/README.md
+++ /dev/null
@@ -1,142 +0,0 @@
-[](https://masterminds.github.io/stability/maintenance.html)
-### Squirrel is "complete".
-Bug fixes will still be merged (slowly). Bug reports are welcome, but I will not necessarily respond to them. If another fork (or substantially similar project) actively improves on what Squirrel does, let me know and I may link to it here.
-
-
-# Squirrel - fluent SQL generator for Go
-
-```go
-import "github.com/Masterminds/squirrel"
-```
-
-
-[](https://godoc.org/github.com/Masterminds/squirrel)
-[](https://travis-ci.org/Masterminds/squirrel)
-
-**Squirrel is not an ORM.** For an application of Squirrel, check out
-[structable, a table-struct mapper](https://github.com/Masterminds/structable)
-
-
-Squirrel helps you build SQL queries from composable parts:
-
-```go
-import sq "github.com/Masterminds/squirrel"
-
-users := sq.Select("*").From("users").Join("emails USING (email_id)")
-
-active := users.Where(sq.Eq{"deleted_at": nil})
-
-sql, args, err := active.ToSql()
-
-sql == "SELECT * FROM users JOIN emails USING (email_id) WHERE deleted_at IS NULL"
-```
-
-```go
-sql, args, err := sq.
- Insert("users").Columns("name", "age").
- Values("moe", 13).Values("larry", sq.Expr("? + 5", 12)).
- ToSql()
-
-sql == "INSERT INTO users (name,age) VALUES (?,?),(?,? + 5)"
-```
-
-Squirrel can also execute queries directly:
-
-```go
-stooges := users.Where(sq.Eq{"username": []string{"moe", "larry", "curly", "shemp"}})
-three_stooges := stooges.Limit(3)
-rows, err := three_stooges.RunWith(db).Query()
-
-// Behaves like:
-rows, err := db.Query("SELECT * FROM users WHERE username IN (?,?,?,?) LIMIT 3",
- "moe", "larry", "curly", "shemp")
-```
-
-Squirrel makes conditional query building a breeze:
-
-```go
-if len(q) > 0 {
- users = users.Where("name LIKE ?", fmt.Sprint("%", q, "%"))
-}
-```
-
-Squirrel wants to make your life easier:
-
-```go
-// StmtCache caches Prepared Stmts for you
-dbCache := sq.NewStmtCache(db)
-
-// StatementBuilder keeps your syntax neat
-mydb := sq.StatementBuilder.RunWith(dbCache)
-select_users := mydb.Select("*").From("users")
-```
-
-Squirrel loves PostgreSQL:
-
-```go
-psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
-
-// You use question marks for placeholders...
-sql, _, _ := psql.Select("*").From("elephants").Where("name IN (?,?)", "Dumbo", "Verna").ToSql()
-
-/// ...squirrel replaces them using PlaceholderFormat.
-sql == "SELECT * FROM elephants WHERE name IN ($1,$2)"
-
-
-/// You can retrieve id ...
-query := sq.Insert("nodes").
- Columns("uuid", "type", "data").
- Values(node.Uuid, node.Type, node.Data).
- Suffix("RETURNING \"id\"").
- RunWith(m.db).
- PlaceholderFormat(sq.Dollar)
-
-query.QueryRow().Scan(&node.id)
-```
-
-You can escape question marks by inserting two question marks:
-
-```sql
-SELECT * FROM nodes WHERE meta->'format' ??| array[?,?]
-```
-
-will generate with the Dollar Placeholder:
-
-```sql
-SELECT * FROM nodes WHERE meta->'format' ?| array[$1,$2]
-```
-
-## FAQ
-
-* **How can I build an IN query on composite keys / tuples, e.g. `WHERE (col1, col2) IN ((1,2),(3,4))`? ([#104](https://github.com/Masterminds/squirrel/issues/104))**
-
- Squirrel does not explicitly support tuples, but you can get the same effect with e.g.:
-
- ```go
- sq.Or{
- sq.Eq{"col1": 1, "col2": 2},
- sq.Eq{"col1": 3, "col2": 4}}
- ```
-
- ```sql
- WHERE (col1 = 1 AND col2 = 2) OR (col1 = 3 AND col2 = 4)
- ```
-
- (which should produce the same query plan as the tuple version)
-
-* **Why doesn't `Eq{"mynumber": []uint8{1,2,3}}` turn into an `IN` query? ([#114](https://github.com/Masterminds/squirrel/issues/114))**
-
- Values of type `[]byte` are handled specially by `database/sql`. In Go, [`byte` is just an alias of `uint8`](https://golang.org/pkg/builtin/#byte), so there is no way to distinguish `[]uint8` from `[]byte`.
-
-* **Some features are poorly documented!**
-
- This isn't a frequent complaints section!
-
-* **Some features are poorly documented?**
-
- Yes. The tests should be considered a part of the documentation; take a look at those for ideas on how to express more complex queries.
-
-## License
-
-Squirrel is released under the
-[MIT License](http://www.opensource.org/licenses/MIT).
diff --git a/vendor/github.com/Masterminds/squirrel/case.go b/vendor/github.com/Masterminds/squirrel/case.go
deleted file mode 100644
index 299e14b9d..000000000
--- a/vendor/github.com/Masterminds/squirrel/case.go
+++ /dev/null
@@ -1,128 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "errors"
-
- "github.com/lann/builder"
-)
-
-func init() {
- builder.Register(CaseBuilder{}, caseData{})
-}
-
-// sqlizerBuffer is a helper that allows to write many Sqlizers one by one
-// without constant checks for errors that may come from Sqlizer
-type sqlizerBuffer struct {
- bytes.Buffer
- args []interface{}
- err error
-}
-
-// WriteSql converts Sqlizer to SQL strings and writes it to buffer
-func (b *sqlizerBuffer) WriteSql(item Sqlizer) {
- if b.err != nil {
- return
- }
-
- var str string
- var args []interface{}
- str, args, b.err = nestedToSql(item)
-
- if b.err != nil {
- return
- }
-
- b.WriteString(str)
- b.WriteByte(' ')
- b.args = append(b.args, args...)
-}
-
-func (b *sqlizerBuffer) ToSql() (string, []interface{}, error) {
- return b.String(), b.args, b.err
-}
-
-// whenPart is a helper structure to describe SQLs "WHEN ... THEN ..." expression
-type whenPart struct {
- when Sqlizer
- then Sqlizer
-}
-
-func newWhenPart(when interface{}, then interface{}) whenPart {
- return whenPart{newPart(when), newPart(then)}
-}
-
-// caseData holds all the data required to build a CASE SQL construct
-type caseData struct {
- What Sqlizer
- WhenParts []whenPart
- Else Sqlizer
-}
-
-// ToSql implements Sqlizer
-func (d *caseData) ToSql() (sqlStr string, args []interface{}, err error) {
- if len(d.WhenParts) == 0 {
- err = errors.New("case expression must contain at lease one WHEN clause")
-
- return
- }
-
- sql := sqlizerBuffer{}
-
- sql.WriteString("CASE ")
- if d.What != nil {
- sql.WriteSql(d.What)
- }
-
- for _, p := range d.WhenParts {
- sql.WriteString("WHEN ")
- sql.WriteSql(p.when)
- sql.WriteString("THEN ")
- sql.WriteSql(p.then)
- }
-
- if d.Else != nil {
- sql.WriteString("ELSE ")
- sql.WriteSql(d.Else)
- }
-
- sql.WriteString("END")
-
- return sql.ToSql()
-}
-
-// CaseBuilder builds SQL CASE construct which could be used as parts of queries.
-type CaseBuilder builder.Builder
-
-// ToSql builds the query into a SQL string and bound args.
-func (b CaseBuilder) ToSql() (string, []interface{}, error) {
- data := builder.GetStruct(b).(caseData)
- return data.ToSql()
-}
-
-// MustSql builds the query into a SQL string and bound args.
-// It panics if there are any errors.
-func (b CaseBuilder) MustSql() (string, []interface{}) {
- sql, args, err := b.ToSql()
- if err != nil {
- panic(err)
- }
- return sql, args
-}
-
-// what sets optional value for CASE construct "CASE [value] ..."
-func (b CaseBuilder) what(expr interface{}) CaseBuilder {
- return builder.Set(b, "What", newPart(expr)).(CaseBuilder)
-}
-
-// When adds "WHEN ... THEN ..." part to CASE construct
-func (b CaseBuilder) When(when interface{}, then interface{}) CaseBuilder {
- // TODO: performance hint: replace slice of WhenPart with just slice of parts
- // where even indices of the slice belong to "when"s and odd indices belong to "then"s
- return builder.Append(b, "WhenParts", newWhenPart(when, then)).(CaseBuilder)
-}
-
-// What sets optional "ELSE ..." part for CASE construct
-func (b CaseBuilder) Else(expr interface{}) CaseBuilder {
- return builder.Set(b, "Else", newPart(expr)).(CaseBuilder)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/delete.go b/vendor/github.com/Masterminds/squirrel/delete.go
deleted file mode 100644
index f3f31e63e..000000000
--- a/vendor/github.com/Masterminds/squirrel/delete.go
+++ /dev/null
@@ -1,191 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "database/sql"
- "fmt"
- "strings"
-
- "github.com/lann/builder"
-)
-
-type deleteData struct {
- PlaceholderFormat PlaceholderFormat
- RunWith BaseRunner
- Prefixes []Sqlizer
- From string
- WhereParts []Sqlizer
- OrderBys []string
- Limit string
- Offset string
- Suffixes []Sqlizer
-}
-
-func (d *deleteData) Exec() (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return ExecWith(d.RunWith, d)
-}
-
-func (d *deleteData) ToSql() (sqlStr string, args []interface{}, err error) {
- if len(d.From) == 0 {
- err = fmt.Errorf("delete statements must specify a From table")
- return
- }
-
- sql := &bytes.Buffer{}
-
- if len(d.Prefixes) > 0 {
- args, err = appendToSql(d.Prefixes, sql, " ", args)
- if err != nil {
- return
- }
-
- sql.WriteString(" ")
- }
-
- sql.WriteString("DELETE FROM ")
- sql.WriteString(d.From)
-
- if len(d.WhereParts) > 0 {
- sql.WriteString(" WHERE ")
- args, err = appendToSql(d.WhereParts, sql, " AND ", args)
- if err != nil {
- return
- }
- }
-
- if len(d.OrderBys) > 0 {
- sql.WriteString(" ORDER BY ")
- sql.WriteString(strings.Join(d.OrderBys, ", "))
- }
-
- if len(d.Limit) > 0 {
- sql.WriteString(" LIMIT ")
- sql.WriteString(d.Limit)
- }
-
- if len(d.Offset) > 0 {
- sql.WriteString(" OFFSET ")
- sql.WriteString(d.Offset)
- }
-
- if len(d.Suffixes) > 0 {
- sql.WriteString(" ")
- args, err = appendToSql(d.Suffixes, sql, " ", args)
- if err != nil {
- return
- }
- }
-
- sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
- return
-}
-
-// Builder
-
-// DeleteBuilder builds SQL DELETE statements.
-type DeleteBuilder builder.Builder
-
-func init() {
- builder.Register(DeleteBuilder{}, deleteData{})
-}
-
-// Format methods
-
-// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
-// query.
-func (b DeleteBuilder) PlaceholderFormat(f PlaceholderFormat) DeleteBuilder {
- return builder.Set(b, "PlaceholderFormat", f).(DeleteBuilder)
-}
-
-// Runner methods
-
-// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
-func (b DeleteBuilder) RunWith(runner BaseRunner) DeleteBuilder {
- return setRunWith(b, runner).(DeleteBuilder)
-}
-
-// Exec builds and Execs the query with the Runner set by RunWith.
-func (b DeleteBuilder) Exec() (sql.Result, error) {
- data := builder.GetStruct(b).(deleteData)
- return data.Exec()
-}
-
-// SQL methods
-
-// ToSql builds the query into a SQL string and bound args.
-func (b DeleteBuilder) ToSql() (string, []interface{}, error) {
- data := builder.GetStruct(b).(deleteData)
- return data.ToSql()
-}
-
-// MustSql builds the query into a SQL string and bound args.
-// It panics if there are any errors.
-func (b DeleteBuilder) MustSql() (string, []interface{}) {
- sql, args, err := b.ToSql()
- if err != nil {
- panic(err)
- }
- return sql, args
-}
-
-// Prefix adds an expression to the beginning of the query
-func (b DeleteBuilder) Prefix(sql string, args ...interface{}) DeleteBuilder {
- return b.PrefixExpr(Expr(sql, args...))
-}
-
-// PrefixExpr adds an expression to the very beginning of the query
-func (b DeleteBuilder) PrefixExpr(expr Sqlizer) DeleteBuilder {
- return builder.Append(b, "Prefixes", expr).(DeleteBuilder)
-}
-
-// From sets the table to be deleted from.
-func (b DeleteBuilder) From(from string) DeleteBuilder {
- return builder.Set(b, "From", from).(DeleteBuilder)
-}
-
-// Where adds WHERE expressions to the query.
-//
-// See SelectBuilder.Where for more information.
-func (b DeleteBuilder) Where(pred interface{}, args ...interface{}) DeleteBuilder {
- return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(DeleteBuilder)
-}
-
-// OrderBy adds ORDER BY expressions to the query.
-func (b DeleteBuilder) OrderBy(orderBys ...string) DeleteBuilder {
- return builder.Extend(b, "OrderBys", orderBys).(DeleteBuilder)
-}
-
-// Limit sets a LIMIT clause on the query.
-func (b DeleteBuilder) Limit(limit uint64) DeleteBuilder {
- return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(DeleteBuilder)
-}
-
-// Offset sets a OFFSET clause on the query.
-func (b DeleteBuilder) Offset(offset uint64) DeleteBuilder {
- return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(DeleteBuilder)
-}
-
-// Suffix adds an expression to the end of the query
-func (b DeleteBuilder) Suffix(sql string, args ...interface{}) DeleteBuilder {
- return b.SuffixExpr(Expr(sql, args...))
-}
-
-// SuffixExpr adds an expression to the end of the query
-func (b DeleteBuilder) SuffixExpr(expr Sqlizer) DeleteBuilder {
- return builder.Append(b, "Suffixes", expr).(DeleteBuilder)
-}
-
-func (b DeleteBuilder) Query() (*sql.Rows, error) {
- data := builder.GetStruct(b).(deleteData)
- return data.Query()
-}
-
-func (d *deleteData) Query() (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return QueryWith(d.RunWith, d)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/delete_ctx.go b/vendor/github.com/Masterminds/squirrel/delete_ctx.go
deleted file mode 100644
index de83c55df..000000000
--- a/vendor/github.com/Masterminds/squirrel/delete_ctx.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// +build go1.8
-
-package squirrel
-
-import (
- "context"
- "database/sql"
-
- "github.com/lann/builder"
-)
-
-func (d *deleteData) ExecContext(ctx context.Context) (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(ExecerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return ExecContextWith(ctx, ctxRunner, d)
-}
-
-func (d *deleteData) QueryContext(ctx context.Context) (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(QueryerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return QueryContextWith(ctx, ctxRunner, d)
-}
-
-func (d *deleteData) QueryRowContext(ctx context.Context) RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRowerContext)
- if !ok {
- if _, ok := d.RunWith.(QueryerContext); !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return &Row{err: NoContextSupport}
- }
- return QueryRowContextWith(ctx, queryRower, d)
-}
-
-// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
-func (b DeleteBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
- data := builder.GetStruct(b).(deleteData)
- return data.ExecContext(ctx)
-}
-
-// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
-func (b DeleteBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
- data := builder.GetStruct(b).(deleteData)
- return data.QueryContext(ctx)
-}
-
-// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
-func (b DeleteBuilder) QueryRowContext(ctx context.Context) RowScanner {
- data := builder.GetStruct(b).(deleteData)
- return data.QueryRowContext(ctx)
-}
-
-// ScanContext is a shortcut for QueryRowContext().Scan.
-func (b DeleteBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
- return b.QueryRowContext(ctx).Scan(dest...)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/expr.go b/vendor/github.com/Masterminds/squirrel/expr.go
deleted file mode 100644
index eba1b4579..000000000
--- a/vendor/github.com/Masterminds/squirrel/expr.go
+++ /dev/null
@@ -1,419 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "database/sql/driver"
- "fmt"
- "reflect"
- "sort"
- "strings"
-)
-
-const (
- // Portable true/false literals.
- sqlTrue = "(1=1)"
- sqlFalse = "(1=0)"
-)
-
-type expr struct {
- sql string
- args []interface{}
-}
-
-// Expr builds an expression from a SQL fragment and arguments.
-//
-// Ex:
-// Expr("FROM_UNIXTIME(?)", t)
-func Expr(sql string, args ...interface{}) Sqlizer {
- return expr{sql: sql, args: args}
-}
-
-func (e expr) ToSql() (sql string, args []interface{}, err error) {
- simple := true
- for _, arg := range e.args {
- if _, ok := arg.(Sqlizer); ok {
- simple = false
- }
- }
- if simple {
- return e.sql, e.args, nil
- }
-
- buf := &bytes.Buffer{}
- ap := e.args
- sp := e.sql
-
- var isql string
- var iargs []interface{}
-
- for err == nil && len(ap) > 0 && len(sp) > 0 {
- i := strings.Index(sp, "?")
- if i < 0 {
- // no more placeholders
- break
- }
- if len(sp) > i+1 && sp[i+1:i+2] == "?" {
- // escaped "??"; append it and step past
- buf.WriteString(sp[:i+2])
- sp = sp[i+2:]
- continue
- }
-
- if as, ok := ap[0].(Sqlizer); ok {
- // sqlizer argument; expand it and append the result
- isql, iargs, err = as.ToSql()
- buf.WriteString(sp[:i])
- buf.WriteString(isql)
- args = append(args, iargs...)
- } else {
- // normal argument; append it and the placeholder
- buf.WriteString(sp[:i+1])
- args = append(args, ap[0])
- }
-
- // step past the argument and placeholder
- ap = ap[1:]
- sp = sp[i+1:]
- }
-
- // append the remaining sql and arguments
- buf.WriteString(sp)
- return buf.String(), append(args, ap...), err
-}
-
-type concatExpr []interface{}
-
-func (ce concatExpr) ToSql() (sql string, args []interface{}, err error) {
- for _, part := range ce {
- switch p := part.(type) {
- case string:
- sql += p
- case Sqlizer:
- pSql, pArgs, err := p.ToSql()
- if err != nil {
- return "", nil, err
- }
- sql += pSql
- args = append(args, pArgs...)
- default:
- return "", nil, fmt.Errorf("%#v is not a string or Sqlizer", part)
- }
- }
- return
-}
-
-// ConcatExpr builds an expression by concatenating strings and other expressions.
-//
-// Ex:
-// name_expr := Expr("CONCAT(?, ' ', ?)", firstName, lastName)
-// ConcatExpr("COALESCE(full_name,", name_expr, ")")
-func ConcatExpr(parts ...interface{}) concatExpr {
- return concatExpr(parts)
-}
-
-// aliasExpr helps to alias part of SQL query generated with underlying "expr"
-type aliasExpr struct {
- expr Sqlizer
- alias string
-}
-
-// Alias allows to define alias for column in SelectBuilder. Useful when column is
-// defined as complex expression like IF or CASE
-// Ex:
-// .Column(Alias(caseStmt, "case_column"))
-func Alias(expr Sqlizer, alias string) aliasExpr {
- return aliasExpr{expr, alias}
-}
-
-func (e aliasExpr) ToSql() (sql string, args []interface{}, err error) {
- sql, args, err = e.expr.ToSql()
- if err == nil {
- sql = fmt.Sprintf("(%s) AS %s", sql, e.alias)
- }
- return
-}
-
-// Eq is syntactic sugar for use with Where/Having/Set methods.
-type Eq map[string]interface{}
-
-func (eq Eq) toSQL(useNotOpr bool) (sql string, args []interface{}, err error) {
- if len(eq) == 0 {
- // Empty Sql{} evaluates to true.
- sql = sqlTrue
- return
- }
-
- var (
- exprs []string
- equalOpr = "="
- inOpr = "IN"
- nullOpr = "IS"
- inEmptyExpr = sqlFalse
- )
-
- if useNotOpr {
- equalOpr = "<>"
- inOpr = "NOT IN"
- nullOpr = "IS NOT"
- inEmptyExpr = sqlTrue
- }
-
- sortedKeys := getSortedKeys(eq)
- for _, key := range sortedKeys {
- var expr string
- val := eq[key]
-
- switch v := val.(type) {
- case driver.Valuer:
- if val, err = v.Value(); err != nil {
- return
- }
- }
-
- r := reflect.ValueOf(val)
- if r.Kind() == reflect.Ptr {
- if r.IsNil() {
- val = nil
- } else {
- val = r.Elem().Interface()
- }
- }
-
- if val == nil {
- expr = fmt.Sprintf("%s %s NULL", key, nullOpr)
- } else {
- if isListType(val) {
- valVal := reflect.ValueOf(val)
- if valVal.Len() == 0 {
- expr = inEmptyExpr
- if args == nil {
- args = []interface{}{}
- }
- } else {
- for i := 0; i < valVal.Len(); i++ {
- args = append(args, valVal.Index(i).Interface())
- }
- expr = fmt.Sprintf("%s %s (%s)", key, inOpr, Placeholders(valVal.Len()))
- }
- } else {
- expr = fmt.Sprintf("%s %s ?", key, equalOpr)
- args = append(args, val)
- }
- }
- exprs = append(exprs, expr)
- }
- sql = strings.Join(exprs, " AND ")
- return
-}
-
-func (eq Eq) ToSql() (sql string, args []interface{}, err error) {
- return eq.toSQL(false)
-}
-
-// NotEq is syntactic sugar for use with Where/Having/Set methods.
-// Ex:
-// .Where(NotEq{"id": 1}) == "id <> 1"
-type NotEq Eq
-
-func (neq NotEq) ToSql() (sql string, args []interface{}, err error) {
- return Eq(neq).toSQL(true)
-}
-
-// Like is syntactic sugar for use with LIKE conditions.
-// Ex:
-// .Where(Like{"name": "%irrel"})
-type Like map[string]interface{}
-
-func (lk Like) toSql(opr string) (sql string, args []interface{}, err error) {
- var exprs []string
- for key, val := range lk {
- expr := ""
-
- switch v := val.(type) {
- case driver.Valuer:
- if val, err = v.Value(); err != nil {
- return
- }
- }
-
- if val == nil {
- err = fmt.Errorf("cannot use null with like operators")
- return
- } else {
- if isListType(val) {
- err = fmt.Errorf("cannot use array or slice with like operators")
- return
- } else {
- expr = fmt.Sprintf("%s %s ?", key, opr)
- args = append(args, val)
- }
- }
- exprs = append(exprs, expr)
- }
- sql = strings.Join(exprs, " AND ")
- return
-}
-
-func (lk Like) ToSql() (sql string, args []interface{}, err error) {
- return lk.toSql("LIKE")
-}
-
-// NotLike is syntactic sugar for use with LIKE conditions.
-// Ex:
-// .Where(NotLike{"name": "%irrel"})
-type NotLike Like
-
-func (nlk NotLike) ToSql() (sql string, args []interface{}, err error) {
- return Like(nlk).toSql("NOT LIKE")
-}
-
-// ILike is syntactic sugar for use with ILIKE conditions.
-// Ex:
-// .Where(ILike{"name": "sq%"})
-type ILike Like
-
-func (ilk ILike) ToSql() (sql string, args []interface{}, err error) {
- return Like(ilk).toSql("ILIKE")
-}
-
-// NotILike is syntactic sugar for use with ILIKE conditions.
-// Ex:
-// .Where(NotILike{"name": "sq%"})
-type NotILike Like
-
-func (nilk NotILike) ToSql() (sql string, args []interface{}, err error) {
- return Like(nilk).toSql("NOT ILIKE")
-}
-
-// Lt is syntactic sugar for use with Where/Having/Set methods.
-// Ex:
-// .Where(Lt{"id": 1})
-type Lt map[string]interface{}
-
-func (lt Lt) toSql(opposite, orEq bool) (sql string, args []interface{}, err error) {
- var (
- exprs []string
- opr = "<"
- )
-
- if opposite {
- opr = ">"
- }
-
- if orEq {
- opr = fmt.Sprintf("%s%s", opr, "=")
- }
-
- sortedKeys := getSortedKeys(lt)
- for _, key := range sortedKeys {
- var expr string
- val := lt[key]
-
- switch v := val.(type) {
- case driver.Valuer:
- if val, err = v.Value(); err != nil {
- return
- }
- }
-
- if val == nil {
- err = fmt.Errorf("cannot use null with less than or greater than operators")
- return
- }
- if isListType(val) {
- err = fmt.Errorf("cannot use array or slice with less than or greater than operators")
- return
- }
- expr = fmt.Sprintf("%s %s ?", key, opr)
- args = append(args, val)
-
- exprs = append(exprs, expr)
- }
- sql = strings.Join(exprs, " AND ")
- return
-}
-
-func (lt Lt) ToSql() (sql string, args []interface{}, err error) {
- return lt.toSql(false, false)
-}
-
-// LtOrEq is syntactic sugar for use with Where/Having/Set methods.
-// Ex:
-// .Where(LtOrEq{"id": 1}) == "id <= 1"
-type LtOrEq Lt
-
-func (ltOrEq LtOrEq) ToSql() (sql string, args []interface{}, err error) {
- return Lt(ltOrEq).toSql(false, true)
-}
-
-// Gt is syntactic sugar for use with Where/Having/Set methods.
-// Ex:
-// .Where(Gt{"id": 1}) == "id > 1"
-type Gt Lt
-
-func (gt Gt) ToSql() (sql string, args []interface{}, err error) {
- return Lt(gt).toSql(true, false)
-}
-
-// GtOrEq is syntactic sugar for use with Where/Having/Set methods.
-// Ex:
-// .Where(GtOrEq{"id": 1}) == "id >= 1"
-type GtOrEq Lt
-
-func (gtOrEq GtOrEq) ToSql() (sql string, args []interface{}, err error) {
- return Lt(gtOrEq).toSql(true, true)
-}
-
-type conj []Sqlizer
-
-func (c conj) join(sep, defaultExpr string) (sql string, args []interface{}, err error) {
- if len(c) == 0 {
- return defaultExpr, []interface{}{}, nil
- }
- var sqlParts []string
- for _, sqlizer := range c {
- partSQL, partArgs, err := nestedToSql(sqlizer)
- if err != nil {
- return "", nil, err
- }
- if partSQL != "" {
- sqlParts = append(sqlParts, partSQL)
- args = append(args, partArgs...)
- }
- }
- if len(sqlParts) > 0 {
- sql = fmt.Sprintf("(%s)", strings.Join(sqlParts, sep))
- }
- return
-}
-
-// And conjunction Sqlizers
-type And conj
-
-func (a And) ToSql() (string, []interface{}, error) {
- return conj(a).join(" AND ", sqlTrue)
-}
-
-// Or conjunction Sqlizers
-type Or conj
-
-func (o Or) ToSql() (string, []interface{}, error) {
- return conj(o).join(" OR ", sqlFalse)
-}
-
-func getSortedKeys(exp map[string]interface{}) []string {
- sortedKeys := make([]string, 0, len(exp))
- for k := range exp {
- sortedKeys = append(sortedKeys, k)
- }
- sort.Strings(sortedKeys)
- return sortedKeys
-}
-
-func isListType(val interface{}) bool {
- if driver.IsValue(val) {
- return false
- }
- valVal := reflect.ValueOf(val)
- return valVal.Kind() == reflect.Array || valVal.Kind() == reflect.Slice
-}
diff --git a/vendor/github.com/Masterminds/squirrel/insert.go b/vendor/github.com/Masterminds/squirrel/insert.go
deleted file mode 100644
index c23a57935..000000000
--- a/vendor/github.com/Masterminds/squirrel/insert.go
+++ /dev/null
@@ -1,298 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "database/sql"
- "errors"
- "fmt"
- "io"
- "sort"
- "strings"
-
- "github.com/lann/builder"
-)
-
-type insertData struct {
- PlaceholderFormat PlaceholderFormat
- RunWith BaseRunner
- Prefixes []Sqlizer
- StatementKeyword string
- Options []string
- Into string
- Columns []string
- Values [][]interface{}
- Suffixes []Sqlizer
- Select *SelectBuilder
-}
-
-func (d *insertData) Exec() (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return ExecWith(d.RunWith, d)
-}
-
-func (d *insertData) Query() (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return QueryWith(d.RunWith, d)
-}
-
-func (d *insertData) QueryRow() RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRower)
- if !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return QueryRowWith(queryRower, d)
-}
-
-func (d *insertData) ToSql() (sqlStr string, args []interface{}, err error) {
- if len(d.Into) == 0 {
- err = errors.New("insert statements must specify a table")
- return
- }
- if len(d.Values) == 0 && d.Select == nil {
- err = errors.New("insert statements must have at least one set of values or select clause")
- return
- }
-
- sql := &bytes.Buffer{}
-
- if len(d.Prefixes) > 0 {
- args, err = appendToSql(d.Prefixes, sql, " ", args)
- if err != nil {
- return
- }
-
- sql.WriteString(" ")
- }
-
- if d.StatementKeyword == "" {
- sql.WriteString("INSERT ")
- } else {
- sql.WriteString(d.StatementKeyword)
- sql.WriteString(" ")
- }
-
- if len(d.Options) > 0 {
- sql.WriteString(strings.Join(d.Options, " "))
- sql.WriteString(" ")
- }
-
- sql.WriteString("INTO ")
- sql.WriteString(d.Into)
- sql.WriteString(" ")
-
- if len(d.Columns) > 0 {
- sql.WriteString("(")
- sql.WriteString(strings.Join(d.Columns, ","))
- sql.WriteString(") ")
- }
-
- if d.Select != nil {
- args, err = d.appendSelectToSQL(sql, args)
- } else {
- args, err = d.appendValuesToSQL(sql, args)
- }
- if err != nil {
- return
- }
-
- if len(d.Suffixes) > 0 {
- sql.WriteString(" ")
- args, err = appendToSql(d.Suffixes, sql, " ", args)
- if err != nil {
- return
- }
- }
-
- sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
- return
-}
-
-func (d *insertData) appendValuesToSQL(w io.Writer, args []interface{}) ([]interface{}, error) {
- if len(d.Values) == 0 {
- return args, errors.New("values for insert statements are not set")
- }
-
- io.WriteString(w, "VALUES ")
-
- valuesStrings := make([]string, len(d.Values))
- for r, row := range d.Values {
- valueStrings := make([]string, len(row))
- for v, val := range row {
- if vs, ok := val.(Sqlizer); ok {
- vsql, vargs, err := vs.ToSql()
- if err != nil {
- return nil, err
- }
- valueStrings[v] = vsql
- args = append(args, vargs...)
- } else {
- valueStrings[v] = "?"
- args = append(args, val)
- }
- }
- valuesStrings[r] = fmt.Sprintf("(%s)", strings.Join(valueStrings, ","))
- }
-
- io.WriteString(w, strings.Join(valuesStrings, ","))
-
- return args, nil
-}
-
-func (d *insertData) appendSelectToSQL(w io.Writer, args []interface{}) ([]interface{}, error) {
- if d.Select == nil {
- return args, errors.New("select clause for insert statements are not set")
- }
-
- selectClause, sArgs, err := d.Select.ToSql()
- if err != nil {
- return args, err
- }
-
- io.WriteString(w, selectClause)
- args = append(args, sArgs...)
-
- return args, nil
-}
-
-// Builder
-
-// InsertBuilder builds SQL INSERT statements.
-type InsertBuilder builder.Builder
-
-func init() {
- builder.Register(InsertBuilder{}, insertData{})
-}
-
-// Format methods
-
-// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
-// query.
-func (b InsertBuilder) PlaceholderFormat(f PlaceholderFormat) InsertBuilder {
- return builder.Set(b, "PlaceholderFormat", f).(InsertBuilder)
-}
-
-// Runner methods
-
-// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
-func (b InsertBuilder) RunWith(runner BaseRunner) InsertBuilder {
- return setRunWith(b, runner).(InsertBuilder)
-}
-
-// Exec builds and Execs the query with the Runner set by RunWith.
-func (b InsertBuilder) Exec() (sql.Result, error) {
- data := builder.GetStruct(b).(insertData)
- return data.Exec()
-}
-
-// Query builds and Querys the query with the Runner set by RunWith.
-func (b InsertBuilder) Query() (*sql.Rows, error) {
- data := builder.GetStruct(b).(insertData)
- return data.Query()
-}
-
-// QueryRow builds and QueryRows the query with the Runner set by RunWith.
-func (b InsertBuilder) QueryRow() RowScanner {
- data := builder.GetStruct(b).(insertData)
- return data.QueryRow()
-}
-
-// Scan is a shortcut for QueryRow().Scan.
-func (b InsertBuilder) Scan(dest ...interface{}) error {
- return b.QueryRow().Scan(dest...)
-}
-
-// SQL methods
-
-// ToSql builds the query into a SQL string and bound args.
-func (b InsertBuilder) ToSql() (string, []interface{}, error) {
- data := builder.GetStruct(b).(insertData)
- return data.ToSql()
-}
-
-// MustSql builds the query into a SQL string and bound args.
-// It panics if there are any errors.
-func (b InsertBuilder) MustSql() (string, []interface{}) {
- sql, args, err := b.ToSql()
- if err != nil {
- panic(err)
- }
- return sql, args
-}
-
-// Prefix adds an expression to the beginning of the query
-func (b InsertBuilder) Prefix(sql string, args ...interface{}) InsertBuilder {
- return b.PrefixExpr(Expr(sql, args...))
-}
-
-// PrefixExpr adds an expression to the very beginning of the query
-func (b InsertBuilder) PrefixExpr(expr Sqlizer) InsertBuilder {
- return builder.Append(b, "Prefixes", expr).(InsertBuilder)
-}
-
-// Options adds keyword options before the INTO clause of the query.
-func (b InsertBuilder) Options(options ...string) InsertBuilder {
- return builder.Extend(b, "Options", options).(InsertBuilder)
-}
-
-// Into sets the INTO clause of the query.
-func (b InsertBuilder) Into(from string) InsertBuilder {
- return builder.Set(b, "Into", from).(InsertBuilder)
-}
-
-// Columns adds insert columns to the query.
-func (b InsertBuilder) Columns(columns ...string) InsertBuilder {
- return builder.Extend(b, "Columns", columns).(InsertBuilder)
-}
-
-// Values adds a single row's values to the query.
-func (b InsertBuilder) Values(values ...interface{}) InsertBuilder {
- return builder.Append(b, "Values", values).(InsertBuilder)
-}
-
-// Suffix adds an expression to the end of the query
-func (b InsertBuilder) Suffix(sql string, args ...interface{}) InsertBuilder {
- return b.SuffixExpr(Expr(sql, args...))
-}
-
-// SuffixExpr adds an expression to the end of the query
-func (b InsertBuilder) SuffixExpr(expr Sqlizer) InsertBuilder {
- return builder.Append(b, "Suffixes", expr).(InsertBuilder)
-}
-
-// SetMap set columns and values for insert builder from a map of column name and value
-// note that it will reset all previous columns and values was set if any
-func (b InsertBuilder) SetMap(clauses map[string]interface{}) InsertBuilder {
- // Keep the columns in a consistent order by sorting the column key string.
- cols := make([]string, 0, len(clauses))
- for col := range clauses {
- cols = append(cols, col)
- }
- sort.Strings(cols)
-
- vals := make([]interface{}, 0, len(clauses))
- for _, col := range cols {
- vals = append(vals, clauses[col])
- }
-
- b = builder.Set(b, "Columns", cols).(InsertBuilder)
- b = builder.Set(b, "Values", [][]interface{}{vals}).(InsertBuilder)
-
- return b
-}
-
-// Select set Select clause for insert query
-// If Values and Select are used, then Select has higher priority
-func (b InsertBuilder) Select(sb SelectBuilder) InsertBuilder {
- return builder.Set(b, "Select", &sb).(InsertBuilder)
-}
-
-func (b InsertBuilder) statementKeyword(keyword string) InsertBuilder {
- return builder.Set(b, "StatementKeyword", keyword).(InsertBuilder)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/insert_ctx.go b/vendor/github.com/Masterminds/squirrel/insert_ctx.go
deleted file mode 100644
index 4541c2fed..000000000
--- a/vendor/github.com/Masterminds/squirrel/insert_ctx.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// +build go1.8
-
-package squirrel
-
-import (
- "context"
- "database/sql"
-
- "github.com/lann/builder"
-)
-
-func (d *insertData) ExecContext(ctx context.Context) (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(ExecerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return ExecContextWith(ctx, ctxRunner, d)
-}
-
-func (d *insertData) QueryContext(ctx context.Context) (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(QueryerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return QueryContextWith(ctx, ctxRunner, d)
-}
-
-func (d *insertData) QueryRowContext(ctx context.Context) RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRowerContext)
- if !ok {
- if _, ok := d.RunWith.(QueryerContext); !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return &Row{err: NoContextSupport}
- }
- return QueryRowContextWith(ctx, queryRower, d)
-}
-
-// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
-func (b InsertBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
- data := builder.GetStruct(b).(insertData)
- return data.ExecContext(ctx)
-}
-
-// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
-func (b InsertBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
- data := builder.GetStruct(b).(insertData)
- return data.QueryContext(ctx)
-}
-
-// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
-func (b InsertBuilder) QueryRowContext(ctx context.Context) RowScanner {
- data := builder.GetStruct(b).(insertData)
- return data.QueryRowContext(ctx)
-}
-
-// ScanContext is a shortcut for QueryRowContext().Scan.
-func (b InsertBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
- return b.QueryRowContext(ctx).Scan(dest...)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/part.go b/vendor/github.com/Masterminds/squirrel/part.go
deleted file mode 100644
index f3a7b1545..000000000
--- a/vendor/github.com/Masterminds/squirrel/part.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package squirrel
-
-import (
- "fmt"
- "io"
-)
-
-type part struct {
- pred interface{}
- args []interface{}
-}
-
-func newPart(pred interface{}, args ...interface{}) Sqlizer {
- return &part{pred, args}
-}
-
-func (p part) ToSql() (sql string, args []interface{}, err error) {
- switch pred := p.pred.(type) {
- case nil:
- // no-op
- case Sqlizer:
- sql, args, err = pred.ToSql()
- case string:
- sql = pred
- args = p.args
- default:
- err = fmt.Errorf("expected string or Sqlizer, not %T", pred)
- }
- return
-}
-
-func nestedToSql(s Sqlizer) (string, []interface{}, error) {
- if raw, ok := s.(rawSqlizer); ok {
- return raw.toSqlRaw()
- } else {
- return s.ToSql()
- }
-}
-
-func appendToSql(parts []Sqlizer, w io.Writer, sep string, args []interface{}) ([]interface{}, error) {
- for i, p := range parts {
- partSql, partArgs, err := nestedToSql(p)
- if err != nil {
- return nil, err
- } else if len(partSql) == 0 {
- continue
- }
-
- if i > 0 {
- _, err := io.WriteString(w, sep)
- if err != nil {
- return nil, err
- }
- }
-
- _, err = io.WriteString(w, partSql)
- if err != nil {
- return nil, err
- }
- args = append(args, partArgs...)
- }
- return args, nil
-}
diff --git a/vendor/github.com/Masterminds/squirrel/placeholder.go b/vendor/github.com/Masterminds/squirrel/placeholder.go
deleted file mode 100644
index 8e97a6c62..000000000
--- a/vendor/github.com/Masterminds/squirrel/placeholder.go
+++ /dev/null
@@ -1,114 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "fmt"
- "strings"
-)
-
-// PlaceholderFormat is the interface that wraps the ReplacePlaceholders method.
-//
-// ReplacePlaceholders takes a SQL statement and replaces each question mark
-// placeholder with a (possibly different) SQL placeholder.
-type PlaceholderFormat interface {
- ReplacePlaceholders(sql string) (string, error)
-}
-
-type placeholderDebugger interface {
- debugPlaceholder() string
-}
-
-var (
- // Question is a PlaceholderFormat instance that leaves placeholders as
- // question marks.
- Question = questionFormat{}
-
- // Dollar is a PlaceholderFormat instance that replaces placeholders with
- // dollar-prefixed positional placeholders (e.g. $1, $2, $3).
- Dollar = dollarFormat{}
-
- // Colon is a PlaceholderFormat instance that replaces placeholders with
- // colon-prefixed positional placeholders (e.g. :1, :2, :3).
- Colon = colonFormat{}
-
- // AtP is a PlaceholderFormat instance that replaces placeholders with
- // "@p"-prefixed positional placeholders (e.g. @p1, @p2, @p3).
- AtP = atpFormat{}
-)
-
-type questionFormat struct{}
-
-func (questionFormat) ReplacePlaceholders(sql string) (string, error) {
- return sql, nil
-}
-
-func (questionFormat) debugPlaceholder() string {
- return "?"
-}
-
-type dollarFormat struct{}
-
-func (dollarFormat) ReplacePlaceholders(sql string) (string, error) {
- return replacePositionalPlaceholders(sql, "$")
-}
-
-func (dollarFormat) debugPlaceholder() string {
- return "$"
-}
-
-type colonFormat struct{}
-
-func (colonFormat) ReplacePlaceholders(sql string) (string, error) {
- return replacePositionalPlaceholders(sql, ":")
-}
-
-func (colonFormat) debugPlaceholder() string {
- return ":"
-}
-
-type atpFormat struct{}
-
-func (atpFormat) ReplacePlaceholders(sql string) (string, error) {
- return replacePositionalPlaceholders(sql, "@p")
-}
-
-func (atpFormat) debugPlaceholder() string {
- return "@p"
-}
-
-// Placeholders returns a string with count ? placeholders joined with commas.
-func Placeholders(count int) string {
- if count < 1 {
- return ""
- }
-
- return strings.Repeat(",?", count)[1:]
-}
-
-func replacePositionalPlaceholders(sql, prefix string) (string, error) {
- buf := &bytes.Buffer{}
- i := 0
- for {
- p := strings.Index(sql, "?")
- if p == -1 {
- break
- }
-
- if len(sql[p:]) > 1 && sql[p:p+2] == "??" { // escape ?? => ?
- buf.WriteString(sql[:p])
- buf.WriteString("?")
- if len(sql[p:]) == 1 {
- break
- }
- sql = sql[p+2:]
- } else {
- i++
- buf.WriteString(sql[:p])
- fmt.Fprintf(buf, "%s%d", prefix, i)
- sql = sql[p+1:]
- }
- }
-
- buf.WriteString(sql)
- return buf.String(), nil
-}
diff --git a/vendor/github.com/Masterminds/squirrel/row.go b/vendor/github.com/Masterminds/squirrel/row.go
deleted file mode 100644
index 74ffda92b..000000000
--- a/vendor/github.com/Masterminds/squirrel/row.go
+++ /dev/null
@@ -1,22 +0,0 @@
-package squirrel
-
-// RowScanner is the interface that wraps the Scan method.
-//
-// Scan behaves like database/sql.Row.Scan.
-type RowScanner interface {
- Scan(...interface{}) error
-}
-
-// Row wraps database/sql.Row to let squirrel return new errors on Scan.
-type Row struct {
- RowScanner
- err error
-}
-
-// Scan returns Row.err or calls RowScanner.Scan.
-func (r *Row) Scan(dest ...interface{}) error {
- if r.err != nil {
- return r.err
- }
- return r.RowScanner.Scan(dest...)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/select.go b/vendor/github.com/Masterminds/squirrel/select.go
deleted file mode 100644
index b585344ce..000000000
--- a/vendor/github.com/Masterminds/squirrel/select.go
+++ /dev/null
@@ -1,396 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "database/sql"
- "fmt"
- "strings"
-
- "github.com/lann/builder"
-)
-
-type selectData struct {
- PlaceholderFormat PlaceholderFormat
- RunWith BaseRunner
- Prefixes []Sqlizer
- Options []string
- Columns []Sqlizer
- From Sqlizer
- Joins []Sqlizer
- WhereParts []Sqlizer
- GroupBys []string
- HavingParts []Sqlizer
- OrderByParts []Sqlizer
- Limit string
- Offset string
- Suffixes []Sqlizer
-}
-
-func (d *selectData) Exec() (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return ExecWith(d.RunWith, d)
-}
-
-func (d *selectData) Query() (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return QueryWith(d.RunWith, d)
-}
-
-func (d *selectData) QueryRow() RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRower)
- if !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return QueryRowWith(queryRower, d)
-}
-
-func (d *selectData) ToSql() (sqlStr string, args []interface{}, err error) {
- sqlStr, args, err = d.toSqlRaw()
- if err != nil {
- return
- }
-
- sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sqlStr)
- return
-}
-
-func (d *selectData) toSqlRaw() (sqlStr string, args []interface{}, err error) {
- if len(d.Columns) == 0 {
- err = fmt.Errorf("select statements must have at least one result column")
- return
- }
-
- sql := &bytes.Buffer{}
-
- if len(d.Prefixes) > 0 {
- args, err = appendToSql(d.Prefixes, sql, " ", args)
- if err != nil {
- return
- }
-
- sql.WriteString(" ")
- }
-
- sql.WriteString("SELECT ")
-
- if len(d.Options) > 0 {
- sql.WriteString(strings.Join(d.Options, " "))
- sql.WriteString(" ")
- }
-
- if len(d.Columns) > 0 {
- args, err = appendToSql(d.Columns, sql, ", ", args)
- if err != nil {
- return
- }
- }
-
- if d.From != nil {
- sql.WriteString(" FROM ")
- args, err = appendToSql([]Sqlizer{d.From}, sql, "", args)
- if err != nil {
- return
- }
- }
-
- if len(d.Joins) > 0 {
- sql.WriteString(" ")
- args, err = appendToSql(d.Joins, sql, " ", args)
- if err != nil {
- return
- }
- }
-
- if len(d.WhereParts) > 0 {
- sql.WriteString(" WHERE ")
- args, err = appendToSql(d.WhereParts, sql, " AND ", args)
- if err != nil {
- return
- }
- }
-
- if len(d.GroupBys) > 0 {
- sql.WriteString(" GROUP BY ")
- sql.WriteString(strings.Join(d.GroupBys, ", "))
- }
-
- if len(d.HavingParts) > 0 {
- sql.WriteString(" HAVING ")
- args, err = appendToSql(d.HavingParts, sql, " AND ", args)
- if err != nil {
- return
- }
- }
-
- if len(d.OrderByParts) > 0 {
- sql.WriteString(" ORDER BY ")
- args, err = appendToSql(d.OrderByParts, sql, ", ", args)
- if err != nil {
- return
- }
- }
-
- if len(d.Limit) > 0 {
- sql.WriteString(" LIMIT ")
- sql.WriteString(d.Limit)
- }
-
- if len(d.Offset) > 0 {
- sql.WriteString(" OFFSET ")
- sql.WriteString(d.Offset)
- }
-
- if len(d.Suffixes) > 0 {
- sql.WriteString(" ")
-
- args, err = appendToSql(d.Suffixes, sql, " ", args)
- if err != nil {
- return
- }
- }
-
- sqlStr = sql.String()
- return
-}
-
-// Builder
-
-// SelectBuilder builds SQL SELECT statements.
-type SelectBuilder builder.Builder
-
-func init() {
- builder.Register(SelectBuilder{}, selectData{})
-}
-
-// Format methods
-
-// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
-// query.
-func (b SelectBuilder) PlaceholderFormat(f PlaceholderFormat) SelectBuilder {
- return builder.Set(b, "PlaceholderFormat", f).(SelectBuilder)
-}
-
-// Runner methods
-
-// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
-// For most cases runner will be a database connection.
-//
-// Internally we use this to mock out the database connection for testing.
-func (b SelectBuilder) RunWith(runner BaseRunner) SelectBuilder {
- return setRunWith(b, runner).(SelectBuilder)
-}
-
-// Exec builds and Execs the query with the Runner set by RunWith.
-func (b SelectBuilder) Exec() (sql.Result, error) {
- data := builder.GetStruct(b).(selectData)
- return data.Exec()
-}
-
-// Query builds and Querys the query with the Runner set by RunWith.
-func (b SelectBuilder) Query() (*sql.Rows, error) {
- data := builder.GetStruct(b).(selectData)
- return data.Query()
-}
-
-// QueryRow builds and QueryRows the query with the Runner set by RunWith.
-func (b SelectBuilder) QueryRow() RowScanner {
- data := builder.GetStruct(b).(selectData)
- return data.QueryRow()
-}
-
-// Scan is a shortcut for QueryRow().Scan.
-func (b SelectBuilder) Scan(dest ...interface{}) error {
- return b.QueryRow().Scan(dest...)
-}
-
-// SQL methods
-
-// ToSql builds the query into a SQL string and bound args.
-func (b SelectBuilder) ToSql() (string, []interface{}, error) {
- data := builder.GetStruct(b).(selectData)
- return data.ToSql()
-}
-
-func (b SelectBuilder) toSqlRaw() (string, []interface{}, error) {
- data := builder.GetStruct(b).(selectData)
- return data.toSqlRaw()
-}
-
-// MustSql builds the query into a SQL string and bound args.
-// It panics if there are any errors.
-func (b SelectBuilder) MustSql() (string, []interface{}) {
- sql, args, err := b.ToSql()
- if err != nil {
- panic(err)
- }
- return sql, args
-}
-
-// Prefix adds an expression to the beginning of the query
-func (b SelectBuilder) Prefix(sql string, args ...interface{}) SelectBuilder {
- return b.PrefixExpr(Expr(sql, args...))
-}
-
-// PrefixExpr adds an expression to the very beginning of the query
-func (b SelectBuilder) PrefixExpr(expr Sqlizer) SelectBuilder {
- return builder.Append(b, "Prefixes", expr).(SelectBuilder)
-}
-
-// Distinct adds a DISTINCT clause to the query.
-func (b SelectBuilder) Distinct() SelectBuilder {
- return b.Options("DISTINCT")
-}
-
-// Options adds select option to the query
-func (b SelectBuilder) Options(options ...string) SelectBuilder {
- return builder.Extend(b, "Options", options).(SelectBuilder)
-}
-
-// Columns adds result columns to the query.
-func (b SelectBuilder) Columns(columns ...string) SelectBuilder {
- parts := make([]interface{}, 0, len(columns))
- for _, str := range columns {
- parts = append(parts, newPart(str))
- }
- return builder.Extend(b, "Columns", parts).(SelectBuilder)
-}
-
-// Column adds a result column to the query.
-// Unlike Columns, Column accepts args which will be bound to placeholders in
-// the columns string, for example:
-// Column("IF(col IN ("+squirrel.Placeholders(3)+"), 1, 0) as col", 1, 2, 3)
-func (b SelectBuilder) Column(column interface{}, args ...interface{}) SelectBuilder {
- return builder.Append(b, "Columns", newPart(column, args...)).(SelectBuilder)
-}
-
-// From sets the FROM clause of the query.
-func (b SelectBuilder) From(from string) SelectBuilder {
- return builder.Set(b, "From", newPart(from)).(SelectBuilder)
-}
-
-// FromSelect sets a subquery into the FROM clause of the query.
-func (b SelectBuilder) FromSelect(from SelectBuilder, alias string) SelectBuilder {
- // Prevent misnumbered parameters in nested selects (#183).
- from = from.PlaceholderFormat(Question)
- return builder.Set(b, "From", Alias(from, alias)).(SelectBuilder)
-}
-
-// JoinClause adds a join clause to the query.
-func (b SelectBuilder) JoinClause(pred interface{}, args ...interface{}) SelectBuilder {
- return builder.Append(b, "Joins", newPart(pred, args...)).(SelectBuilder)
-}
-
-// Join adds a JOIN clause to the query.
-func (b SelectBuilder) Join(join string, rest ...interface{}) SelectBuilder {
- return b.JoinClause("JOIN "+join, rest...)
-}
-
-// LeftJoin adds a LEFT JOIN clause to the query.
-func (b SelectBuilder) LeftJoin(join string, rest ...interface{}) SelectBuilder {
- return b.JoinClause("LEFT JOIN "+join, rest...)
-}
-
-// RightJoin adds a RIGHT JOIN clause to the query.
-func (b SelectBuilder) RightJoin(join string, rest ...interface{}) SelectBuilder {
- return b.JoinClause("RIGHT JOIN "+join, rest...)
-}
-
-// InnerJoin adds a INNER JOIN clause to the query.
-func (b SelectBuilder) InnerJoin(join string, rest ...interface{}) SelectBuilder {
- return b.JoinClause("INNER JOIN "+join, rest...)
-}
-
-// CrossJoin adds a CROSS JOIN clause to the query.
-func (b SelectBuilder) CrossJoin(join string, rest ...interface{}) SelectBuilder {
- return b.JoinClause("CROSS JOIN "+join, rest...)
-}
-
-// Where adds an expression to the WHERE clause of the query.
-//
-// Expressions are ANDed together in the generated SQL.
-//
-// Where accepts several types for its pred argument:
-//
-// nil OR "" - ignored.
-//
-// string - SQL expression.
-// If the expression has SQL placeholders then a set of arguments must be passed
-// as well, one for each placeholder.
-//
-// map[string]interface{} OR Eq - map of SQL expressions to values. Each key is
-// transformed into an expression like " = ?", with the corresponding value
-// bound to the placeholder. If the value is nil, the expression will be "
-// IS NULL". If the value is an array or slice, the expression will be " IN
-// (?,?,...)", with one placeholder for each item in the value. These expressions
-// are ANDed together.
-//
-// Where will panic if pred isn't any of the above types.
-func (b SelectBuilder) Where(pred interface{}, args ...interface{}) SelectBuilder {
- if pred == nil || pred == "" {
- return b
- }
- return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(SelectBuilder)
-}
-
-// GroupBy adds GROUP BY expressions to the query.
-func (b SelectBuilder) GroupBy(groupBys ...string) SelectBuilder {
- return builder.Extend(b, "GroupBys", groupBys).(SelectBuilder)
-}
-
-// Having adds an expression to the HAVING clause of the query.
-//
-// See Where.
-func (b SelectBuilder) Having(pred interface{}, rest ...interface{}) SelectBuilder {
- return builder.Append(b, "HavingParts", newWherePart(pred, rest...)).(SelectBuilder)
-}
-
-// OrderByClause adds ORDER BY clause to the query.
-func (b SelectBuilder) OrderByClause(pred interface{}, args ...interface{}) SelectBuilder {
- return builder.Append(b, "OrderByParts", newPart(pred, args...)).(SelectBuilder)
-}
-
-// OrderBy adds ORDER BY expressions to the query.
-func (b SelectBuilder) OrderBy(orderBys ...string) SelectBuilder {
- for _, orderBy := range orderBys {
- b = b.OrderByClause(orderBy)
- }
-
- return b
-}
-
-// Limit sets a LIMIT clause on the query.
-func (b SelectBuilder) Limit(limit uint64) SelectBuilder {
- return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(SelectBuilder)
-}
-
-// Limit ALL allows to access all records with limit
-func (b SelectBuilder) RemoveLimit() SelectBuilder {
- return builder.Delete(b, "Limit").(SelectBuilder)
-}
-
-// Offset sets a OFFSET clause on the query.
-func (b SelectBuilder) Offset(offset uint64) SelectBuilder {
- return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(SelectBuilder)
-}
-
-// RemoveOffset removes OFFSET clause.
-func (b SelectBuilder) RemoveOffset() SelectBuilder {
- return builder.Delete(b, "Offset").(SelectBuilder)
-}
-
-// Suffix adds an expression to the end of the query
-func (b SelectBuilder) Suffix(sql string, args ...interface{}) SelectBuilder {
- return b.SuffixExpr(Expr(sql, args...))
-}
-
-// SuffixExpr adds an expression to the end of the query
-func (b SelectBuilder) SuffixExpr(expr Sqlizer) SelectBuilder {
- return builder.Append(b, "Suffixes", expr).(SelectBuilder)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/select_ctx.go b/vendor/github.com/Masterminds/squirrel/select_ctx.go
deleted file mode 100644
index 4c42c13f4..000000000
--- a/vendor/github.com/Masterminds/squirrel/select_ctx.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// +build go1.8
-
-package squirrel
-
-import (
- "context"
- "database/sql"
-
- "github.com/lann/builder"
-)
-
-func (d *selectData) ExecContext(ctx context.Context) (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(ExecerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return ExecContextWith(ctx, ctxRunner, d)
-}
-
-func (d *selectData) QueryContext(ctx context.Context) (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(QueryerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return QueryContextWith(ctx, ctxRunner, d)
-}
-
-func (d *selectData) QueryRowContext(ctx context.Context) RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRowerContext)
- if !ok {
- if _, ok := d.RunWith.(QueryerContext); !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return &Row{err: NoContextSupport}
- }
- return QueryRowContextWith(ctx, queryRower, d)
-}
-
-// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
-func (b SelectBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
- data := builder.GetStruct(b).(selectData)
- return data.ExecContext(ctx)
-}
-
-// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
-func (b SelectBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
- data := builder.GetStruct(b).(selectData)
- return data.QueryContext(ctx)
-}
-
-// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
-func (b SelectBuilder) QueryRowContext(ctx context.Context) RowScanner {
- data := builder.GetStruct(b).(selectData)
- return data.QueryRowContext(ctx)
-}
-
-// ScanContext is a shortcut for QueryRowContext().Scan.
-func (b SelectBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
- return b.QueryRowContext(ctx).Scan(dest...)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/squirrel.go b/vendor/github.com/Masterminds/squirrel/squirrel.go
deleted file mode 100644
index 46d456eb6..000000000
--- a/vendor/github.com/Masterminds/squirrel/squirrel.go
+++ /dev/null
@@ -1,183 +0,0 @@
-// Package squirrel provides a fluent SQL generator.
-//
-// See https://github.com/Masterminds/squirrel for examples.
-package squirrel
-
-import (
- "bytes"
- "database/sql"
- "fmt"
- "strings"
-
- "github.com/lann/builder"
-)
-
-// Sqlizer is the interface that wraps the ToSql method.
-//
-// ToSql returns a SQL representation of the Sqlizer, along with a slice of args
-// as passed to e.g. database/sql.Exec. It can also return an error.
-type Sqlizer interface {
- ToSql() (string, []interface{}, error)
-}
-
-// rawSqlizer is expected to do what Sqlizer does, but without finalizing placeholders.
-// This is useful for nested queries.
-type rawSqlizer interface {
- toSqlRaw() (string, []interface{}, error)
-}
-
-// Execer is the interface that wraps the Exec method.
-//
-// Exec executes the given query as implemented by database/sql.Exec.
-type Execer interface {
- Exec(query string, args ...interface{}) (sql.Result, error)
-}
-
-// Queryer is the interface that wraps the Query method.
-//
-// Query executes the given query as implemented by database/sql.Query.
-type Queryer interface {
- Query(query string, args ...interface{}) (*sql.Rows, error)
-}
-
-// QueryRower is the interface that wraps the QueryRow method.
-//
-// QueryRow executes the given query as implemented by database/sql.QueryRow.
-type QueryRower interface {
- QueryRow(query string, args ...interface{}) RowScanner
-}
-
-// BaseRunner groups the Execer and Queryer interfaces.
-type BaseRunner interface {
- Execer
- Queryer
-}
-
-// Runner groups the Execer, Queryer, and QueryRower interfaces.
-type Runner interface {
- Execer
- Queryer
- QueryRower
-}
-
-// WrapStdSql wraps a type implementing the standard SQL interface with methods that
-// squirrel expects.
-func WrapStdSql(stdSql StdSql) Runner {
- return &stdsqlRunner{stdSql}
-}
-
-// StdSql encompasses the standard methods of the *sql.DB type, and other types that
-// wrap these methods.
-type StdSql interface {
- Query(string, ...interface{}) (*sql.Rows, error)
- QueryRow(string, ...interface{}) *sql.Row
- Exec(string, ...interface{}) (sql.Result, error)
-}
-
-type stdsqlRunner struct {
- StdSql
-}
-
-func (r *stdsqlRunner) QueryRow(query string, args ...interface{}) RowScanner {
- return r.StdSql.QueryRow(query, args...)
-}
-
-func setRunWith(b interface{}, runner BaseRunner) interface{} {
- switch r := runner.(type) {
- case StdSqlCtx:
- runner = WrapStdSqlCtx(r)
- case StdSql:
- runner = WrapStdSql(r)
- }
- return builder.Set(b, "RunWith", runner)
-}
-
-// RunnerNotSet is returned by methods that need a Runner if it isn't set.
-var RunnerNotSet = fmt.Errorf("cannot run; no Runner set (RunWith)")
-
-// RunnerNotQueryRunner is returned by QueryRow if the RunWith value doesn't implement QueryRower.
-var RunnerNotQueryRunner = fmt.Errorf("cannot QueryRow; Runner is not a QueryRower")
-
-// ExecWith Execs the SQL returned by s with db.
-func ExecWith(db Execer, s Sqlizer) (res sql.Result, err error) {
- query, args, err := s.ToSql()
- if err != nil {
- return
- }
- return db.Exec(query, args...)
-}
-
-// QueryWith Querys the SQL returned by s with db.
-func QueryWith(db Queryer, s Sqlizer) (rows *sql.Rows, err error) {
- query, args, err := s.ToSql()
- if err != nil {
- return
- }
- return db.Query(query, args...)
-}
-
-// QueryRowWith QueryRows the SQL returned by s with db.
-func QueryRowWith(db QueryRower, s Sqlizer) RowScanner {
- query, args, err := s.ToSql()
- return &Row{RowScanner: db.QueryRow(query, args...), err: err}
-}
-
-// DebugSqlizer calls ToSql on s and shows the approximate SQL to be executed
-//
-// If ToSql returns an error, the result of this method will look like:
-// "[ToSql error: %s]" or "[DebugSqlizer error: %s]"
-//
-// IMPORTANT: As its name suggests, this function should only be used for
-// debugging. While the string result *might* be valid SQL, this function does
-// not try very hard to ensure it. Additionally, executing the output of this
-// function with any untrusted user input is certainly insecure.
-func DebugSqlizer(s Sqlizer) string {
- sql, args, err := s.ToSql()
- if err != nil {
- return fmt.Sprintf("[ToSql error: %s]", err)
- }
-
- var placeholder string
- downCast, ok := s.(placeholderDebugger)
- if !ok {
- placeholder = "?"
- } else {
- placeholder = downCast.debugPlaceholder()
- }
- // TODO: dedupe this with placeholder.go
- buf := &bytes.Buffer{}
- i := 0
- for {
- p := strings.Index(sql, placeholder)
- if p == -1 {
- break
- }
- if len(sql[p:]) > 1 && sql[p:p+2] == "??" { // escape ?? => ?
- buf.WriteString(sql[:p])
- buf.WriteString("?")
- if len(sql[p:]) == 1 {
- break
- }
- sql = sql[p+2:]
- } else {
- if i+1 > len(args) {
- return fmt.Sprintf(
- "[DebugSqlizer error: too many placeholders in %#v for %d args]",
- sql, len(args))
- }
- buf.WriteString(sql[:p])
- fmt.Fprintf(buf, "'%v'", args[i])
- // advance our sql string "cursor" beyond the arg we placed
- sql = sql[p+1:]
- i++
- }
- }
- if i < len(args) {
- return fmt.Sprintf(
- "[DebugSqlizer error: not enough placeholders in %#v for %d args]",
- sql, len(args))
- }
- // "append" any remaning sql that won't need interpolating
- buf.WriteString(sql)
- return buf.String()
-}
diff --git a/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go b/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go
deleted file mode 100644
index 504e763d2..000000000
--- a/vendor/github.com/Masterminds/squirrel/squirrel_ctx.go
+++ /dev/null
@@ -1,93 +0,0 @@
-// +build go1.8
-
-package squirrel
-
-import (
- "context"
- "database/sql"
- "errors"
-)
-
-// NoContextSupport is returned if a db doesn't support Context.
-var NoContextSupport = errors.New("DB does not support Context")
-
-// ExecerContext is the interface that wraps the ExecContext method.
-//
-// Exec executes the given query as implemented by database/sql.ExecContext.
-type ExecerContext interface {
- ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
-}
-
-// QueryerContext is the interface that wraps the QueryContext method.
-//
-// QueryContext executes the given query as implemented by database/sql.QueryContext.
-type QueryerContext interface {
- QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
-}
-
-// QueryRowerContext is the interface that wraps the QueryRowContext method.
-//
-// QueryRowContext executes the given query as implemented by database/sql.QueryRowContext.
-type QueryRowerContext interface {
- QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner
-}
-
-// RunnerContext groups the Runner interface, along with the Contect versions of each of
-// its methods
-type RunnerContext interface {
- Runner
- QueryerContext
- QueryRowerContext
- ExecerContext
-}
-
-// WrapStdSqlCtx wraps a type implementing the standard SQL interface plus the context
-// versions of the methods with methods that squirrel expects.
-func WrapStdSqlCtx(stdSqlCtx StdSqlCtx) RunnerContext {
- return &stdsqlCtxRunner{stdSqlCtx}
-}
-
-// StdSqlCtx encompasses the standard methods of the *sql.DB type, along with the Context
-// versions of those methods, and other types that wrap these methods.
-type StdSqlCtx interface {
- StdSql
- QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
- QueryRowContext(context.Context, string, ...interface{}) *sql.Row
- ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
-}
-
-type stdsqlCtxRunner struct {
- StdSqlCtx
-}
-
-func (r *stdsqlCtxRunner) QueryRow(query string, args ...interface{}) RowScanner {
- return r.StdSqlCtx.QueryRow(query, args...)
-}
-
-func (r *stdsqlCtxRunner) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {
- return r.StdSqlCtx.QueryRowContext(ctx, query, args...)
-}
-
-// ExecContextWith ExecContexts the SQL returned by s with db.
-func ExecContextWith(ctx context.Context, db ExecerContext, s Sqlizer) (res sql.Result, err error) {
- query, args, err := s.ToSql()
- if err != nil {
- return
- }
- return db.ExecContext(ctx, query, args...)
-}
-
-// QueryContextWith QueryContexts the SQL returned by s with db.
-func QueryContextWith(ctx context.Context, db QueryerContext, s Sqlizer) (rows *sql.Rows, err error) {
- query, args, err := s.ToSql()
- if err != nil {
- return
- }
- return db.QueryContext(ctx, query, args...)
-}
-
-// QueryRowContextWith QueryRowContexts the SQL returned by s with db.
-func QueryRowContextWith(ctx context.Context, db QueryRowerContext, s Sqlizer) RowScanner {
- query, args, err := s.ToSql()
- return &Row{RowScanner: db.QueryRowContext(ctx, query, args...), err: err}
-}
diff --git a/vendor/github.com/Masterminds/squirrel/statement.go b/vendor/github.com/Masterminds/squirrel/statement.go
deleted file mode 100644
index 9420c67f8..000000000
--- a/vendor/github.com/Masterminds/squirrel/statement.go
+++ /dev/null
@@ -1,104 +0,0 @@
-package squirrel
-
-import "github.com/lann/builder"
-
-// StatementBuilderType is the type of StatementBuilder.
-type StatementBuilderType builder.Builder
-
-// Select returns a SelectBuilder for this StatementBuilderType.
-func (b StatementBuilderType) Select(columns ...string) SelectBuilder {
- return SelectBuilder(b).Columns(columns...)
-}
-
-// Insert returns a InsertBuilder for this StatementBuilderType.
-func (b StatementBuilderType) Insert(into string) InsertBuilder {
- return InsertBuilder(b).Into(into)
-}
-
-// Replace returns a InsertBuilder for this StatementBuilderType with the
-// statement keyword set to "REPLACE".
-func (b StatementBuilderType) Replace(into string) InsertBuilder {
- return InsertBuilder(b).statementKeyword("REPLACE").Into(into)
-}
-
-// Update returns a UpdateBuilder for this StatementBuilderType.
-func (b StatementBuilderType) Update(table string) UpdateBuilder {
- return UpdateBuilder(b).Table(table)
-}
-
-// Delete returns a DeleteBuilder for this StatementBuilderType.
-func (b StatementBuilderType) Delete(from string) DeleteBuilder {
- return DeleteBuilder(b).From(from)
-}
-
-// PlaceholderFormat sets the PlaceholderFormat field for any child builders.
-func (b StatementBuilderType) PlaceholderFormat(f PlaceholderFormat) StatementBuilderType {
- return builder.Set(b, "PlaceholderFormat", f).(StatementBuilderType)
-}
-
-// RunWith sets the RunWith field for any child builders.
-func (b StatementBuilderType) RunWith(runner BaseRunner) StatementBuilderType {
- return setRunWith(b, runner).(StatementBuilderType)
-}
-
-// Where adds WHERE expressions to the query.
-//
-// See SelectBuilder.Where for more information.
-func (b StatementBuilderType) Where(pred interface{}, args ...interface{}) StatementBuilderType {
- return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(StatementBuilderType)
-}
-
-// StatementBuilder is a parent builder for other builders, e.g. SelectBuilder.
-var StatementBuilder = StatementBuilderType(builder.EmptyBuilder).PlaceholderFormat(Question)
-
-// Select returns a new SelectBuilder, optionally setting some result columns.
-//
-// See SelectBuilder.Columns.
-func Select(columns ...string) SelectBuilder {
- return StatementBuilder.Select(columns...)
-}
-
-// Insert returns a new InsertBuilder with the given table name.
-//
-// See InsertBuilder.Into.
-func Insert(into string) InsertBuilder {
- return StatementBuilder.Insert(into)
-}
-
-// Replace returns a new InsertBuilder with the statement keyword set to
-// "REPLACE" and with the given table name.
-//
-// See InsertBuilder.Into.
-func Replace(into string) InsertBuilder {
- return StatementBuilder.Replace(into)
-}
-
-// Update returns a new UpdateBuilder with the given table name.
-//
-// See UpdateBuilder.Table.
-func Update(table string) UpdateBuilder {
- return StatementBuilder.Update(table)
-}
-
-// Delete returns a new DeleteBuilder with the given table name.
-//
-// See DeleteBuilder.Table.
-func Delete(from string) DeleteBuilder {
- return StatementBuilder.Delete(from)
-}
-
-// Case returns a new CaseBuilder
-// "what" represents case value
-func Case(what ...interface{}) CaseBuilder {
- b := CaseBuilder(builder.EmptyBuilder)
-
- switch len(what) {
- case 0:
- case 1:
- b = b.what(what[0])
- default:
- b = b.what(newPart(what[0], what[1:]...))
-
- }
- return b
-}
diff --git a/vendor/github.com/Masterminds/squirrel/stmtcacher.go b/vendor/github.com/Masterminds/squirrel/stmtcacher.go
deleted file mode 100644
index 5bf267a13..000000000
--- a/vendor/github.com/Masterminds/squirrel/stmtcacher.go
+++ /dev/null
@@ -1,121 +0,0 @@
-package squirrel
-
-import (
- "database/sql"
- "fmt"
- "sync"
-)
-
-// Prepareer is the interface that wraps the Prepare method.
-//
-// Prepare executes the given query as implemented by database/sql.Prepare.
-type Preparer interface {
- Prepare(query string) (*sql.Stmt, error)
-}
-
-// DBProxy groups the Execer, Queryer, QueryRower, and Preparer interfaces.
-type DBProxy interface {
- Execer
- Queryer
- QueryRower
- Preparer
-}
-
-// NOTE: NewStmtCache is defined in stmtcacher_ctx.go (Go >= 1.8) or stmtcacher_noctx.go (Go < 1.8).
-
-// StmtCache wraps and delegates down to a Preparer type
-//
-// It also automatically prepares all statements sent to the underlying Preparer calls
-// for Exec, Query and QueryRow and caches the returns *sql.Stmt using the provided
-// query as the key. So that it can be automatically re-used.
-type StmtCache struct {
- prep Preparer
- cache map[string]*sql.Stmt
- mu sync.Mutex
-}
-
-// Prepare delegates down to the underlying Preparer and caches the result
-// using the provided query as a key
-func (sc *StmtCache) Prepare(query string) (*sql.Stmt, error) {
- sc.mu.Lock()
- defer sc.mu.Unlock()
-
- stmt, ok := sc.cache[query]
- if ok {
- return stmt, nil
- }
- stmt, err := sc.prep.Prepare(query)
- if err == nil {
- sc.cache[query] = stmt
- }
- return stmt, err
-}
-
-// Exec delegates down to the underlying Preparer using a prepared statement
-func (sc *StmtCache) Exec(query string, args ...interface{}) (res sql.Result, err error) {
- stmt, err := sc.Prepare(query)
- if err != nil {
- return
- }
- return stmt.Exec(args...)
-}
-
-// Query delegates down to the underlying Preparer using a prepared statement
-func (sc *StmtCache) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {
- stmt, err := sc.Prepare(query)
- if err != nil {
- return
- }
- return stmt.Query(args...)
-}
-
-// QueryRow delegates down to the underlying Preparer using a prepared statement
-func (sc *StmtCache) QueryRow(query string, args ...interface{}) RowScanner {
- stmt, err := sc.Prepare(query)
- if err != nil {
- return &Row{err: err}
- }
- return stmt.QueryRow(args...)
-}
-
-// Clear removes and closes all the currently cached prepared statements
-func (sc *StmtCache) Clear() (err error) {
- sc.mu.Lock()
- defer sc.mu.Unlock()
-
- for key, stmt := range sc.cache {
- delete(sc.cache, key)
-
- if stmt == nil {
- continue
- }
-
- if cerr := stmt.Close(); cerr != nil {
- err = cerr
- }
- }
-
- if err != nil {
- return fmt.Errorf("one or more Stmt.Close failed; last error: %v", err)
- }
-
- return
-}
-
-type DBProxyBeginner interface {
- DBProxy
- Begin() (*sql.Tx, error)
-}
-
-type stmtCacheProxy struct {
- DBProxy
- db *sql.DB
-}
-
-func NewStmtCacheProxy(db *sql.DB) DBProxyBeginner {
- return &stmtCacheProxy{DBProxy: NewStmtCache(db), db: db}
-}
-
-func (sp *stmtCacheProxy) Begin() (*sql.Tx, error) {
- return sp.db.Begin()
-}
diff --git a/vendor/github.com/Masterminds/squirrel/stmtcacher_ctx.go b/vendor/github.com/Masterminds/squirrel/stmtcacher_ctx.go
deleted file mode 100644
index 53603cf4c..000000000
--- a/vendor/github.com/Masterminds/squirrel/stmtcacher_ctx.go
+++ /dev/null
@@ -1,86 +0,0 @@
-// +build go1.8
-
-package squirrel
-
-import (
- "context"
- "database/sql"
-)
-
-// PrepareerContext is the interface that wraps the Prepare and PrepareContext methods.
-//
-// Prepare executes the given query as implemented by database/sql.Prepare.
-// PrepareContext executes the given query as implemented by database/sql.PrepareContext.
-type PreparerContext interface {
- Preparer
- PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
-}
-
-// DBProxyContext groups the Execer, Queryer, QueryRower and PreparerContext interfaces.
-type DBProxyContext interface {
- Execer
- Queryer
- QueryRower
- PreparerContext
-}
-
-// NewStmtCache returns a *StmtCache wrapping a PreparerContext that caches Prepared Stmts.
-//
-// Stmts are cached based on the string value of their queries.
-func NewStmtCache(prep PreparerContext) *StmtCache {
- return &StmtCache{prep: prep, cache: make(map[string]*sql.Stmt)}
-}
-
-// NewStmtCacher is deprecated
-//
-// Use NewStmtCache instead
-func NewStmtCacher(prep PreparerContext) DBProxyContext {
- return NewStmtCache(prep)
-}
-
-// PrepareContext delegates down to the underlying PreparerContext and caches the result
-// using the provided query as a key
-func (sc *StmtCache) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
- ctxPrep, ok := sc.prep.(PreparerContext)
- if !ok {
- return nil, NoContextSupport
- }
- sc.mu.Lock()
- defer sc.mu.Unlock()
- stmt, ok := sc.cache[query]
- if ok {
- return stmt, nil
- }
- stmt, err := ctxPrep.PrepareContext(ctx, query)
- if err == nil {
- sc.cache[query] = stmt
- }
- return stmt, err
-}
-
-// ExecContext delegates down to the underlying PreparerContext using a prepared statement
-func (sc *StmtCache) ExecContext(ctx context.Context, query string, args ...interface{}) (res sql.Result, err error) {
- stmt, err := sc.PrepareContext(ctx, query)
- if err != nil {
- return
- }
- return stmt.ExecContext(ctx, args...)
-}
-
-// QueryContext delegates down to the underlying PreparerContext using a prepared statement
-func (sc *StmtCache) QueryContext(ctx context.Context, query string, args ...interface{}) (rows *sql.Rows, err error) {
- stmt, err := sc.PrepareContext(ctx, query)
- if err != nil {
- return
- }
- return stmt.QueryContext(ctx, args...)
-}
-
-// QueryRowContext delegates down to the underlying PreparerContext using a prepared statement
-func (sc *StmtCache) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {
- stmt, err := sc.PrepareContext(ctx, query)
- if err != nil {
- return &Row{err: err}
- }
- return stmt.QueryRowContext(ctx, args...)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/stmtcacher_noctx.go b/vendor/github.com/Masterminds/squirrel/stmtcacher_noctx.go
deleted file mode 100644
index deac96777..000000000
--- a/vendor/github.com/Masterminds/squirrel/stmtcacher_noctx.go
+++ /dev/null
@@ -1,21 +0,0 @@
-// +build !go1.8
-
-package squirrel
-
-import (
- "database/sql"
-)
-
-// NewStmtCacher returns a DBProxy wrapping prep that caches Prepared Stmts.
-//
-// Stmts are cached based on the string value of their queries.
-func NewStmtCache(prep Preparer) *StmtCache {
- return &StmtCacher{prep: prep, cache: make(map[string]*sql.Stmt)}
-}
-
-// NewStmtCacher is deprecated
-//
-// Use NewStmtCache instead
-func NewStmtCacher(prep Preparer) DBProxy {
- return NewStmtCache(prep)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/update.go b/vendor/github.com/Masterminds/squirrel/update.go
deleted file mode 100644
index 8d658d721..000000000
--- a/vendor/github.com/Masterminds/squirrel/update.go
+++ /dev/null
@@ -1,266 +0,0 @@
-package squirrel
-
-import (
- "bytes"
- "database/sql"
- "fmt"
- "sort"
- "strings"
-
- "github.com/lann/builder"
-)
-
-type updateData struct {
- PlaceholderFormat PlaceholderFormat
- RunWith BaseRunner
- Prefixes []Sqlizer
- Table string
- SetClauses []setClause
- WhereParts []Sqlizer
- OrderBys []string
- Limit string
- Offset string
- Suffixes []Sqlizer
-}
-
-type setClause struct {
- column string
- value interface{}
-}
-
-func (d *updateData) Exec() (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return ExecWith(d.RunWith, d)
-}
-
-func (d *updateData) Query() (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- return QueryWith(d.RunWith, d)
-}
-
-func (d *updateData) QueryRow() RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRower)
- if !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return QueryRowWith(queryRower, d)
-}
-
-func (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {
- if len(d.Table) == 0 {
- err = fmt.Errorf("update statements must specify a table")
- return
- }
- if len(d.SetClauses) == 0 {
- err = fmt.Errorf("update statements must have at least one Set clause")
- return
- }
-
- sql := &bytes.Buffer{}
-
- if len(d.Prefixes) > 0 {
- args, err = appendToSql(d.Prefixes, sql, " ", args)
- if err != nil {
- return
- }
-
- sql.WriteString(" ")
- }
-
- sql.WriteString("UPDATE ")
- sql.WriteString(d.Table)
-
- sql.WriteString(" SET ")
- setSqls := make([]string, len(d.SetClauses))
- for i, setClause := range d.SetClauses {
- var valSql string
- if vs, ok := setClause.value.(Sqlizer); ok {
- vsql, vargs, err := vs.ToSql()
- if err != nil {
- return "", nil, err
- }
- if _, ok := vs.(SelectBuilder); ok {
- valSql = fmt.Sprintf("(%s)", vsql)
- } else {
- valSql = vsql
- }
- args = append(args, vargs...)
- } else {
- valSql = "?"
- args = append(args, setClause.value)
- }
- setSqls[i] = fmt.Sprintf("%s = %s", setClause.column, valSql)
- }
- sql.WriteString(strings.Join(setSqls, ", "))
-
- if len(d.WhereParts) > 0 {
- sql.WriteString(" WHERE ")
- args, err = appendToSql(d.WhereParts, sql, " AND ", args)
- if err != nil {
- return
- }
- }
-
- if len(d.OrderBys) > 0 {
- sql.WriteString(" ORDER BY ")
- sql.WriteString(strings.Join(d.OrderBys, ", "))
- }
-
- if len(d.Limit) > 0 {
- sql.WriteString(" LIMIT ")
- sql.WriteString(d.Limit)
- }
-
- if len(d.Offset) > 0 {
- sql.WriteString(" OFFSET ")
- sql.WriteString(d.Offset)
- }
-
- if len(d.Suffixes) > 0 {
- sql.WriteString(" ")
- args, err = appendToSql(d.Suffixes, sql, " ", args)
- if err != nil {
- return
- }
- }
-
- sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
- return
-}
-
-// Builder
-
-// UpdateBuilder builds SQL UPDATE statements.
-type UpdateBuilder builder.Builder
-
-func init() {
- builder.Register(UpdateBuilder{}, updateData{})
-}
-
-// Format methods
-
-// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
-// query.
-func (b UpdateBuilder) PlaceholderFormat(f PlaceholderFormat) UpdateBuilder {
- return builder.Set(b, "PlaceholderFormat", f).(UpdateBuilder)
-}
-
-// Runner methods
-
-// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.
-func (b UpdateBuilder) RunWith(runner BaseRunner) UpdateBuilder {
- return setRunWith(b, runner).(UpdateBuilder)
-}
-
-// Exec builds and Execs the query with the Runner set by RunWith.
-func (b UpdateBuilder) Exec() (sql.Result, error) {
- data := builder.GetStruct(b).(updateData)
- return data.Exec()
-}
-
-func (b UpdateBuilder) Query() (*sql.Rows, error) {
- data := builder.GetStruct(b).(updateData)
- return data.Query()
-}
-
-func (b UpdateBuilder) QueryRow() RowScanner {
- data := builder.GetStruct(b).(updateData)
- return data.QueryRow()
-}
-
-func (b UpdateBuilder) Scan(dest ...interface{}) error {
- return b.QueryRow().Scan(dest...)
-}
-
-// SQL methods
-
-// ToSql builds the query into a SQL string and bound args.
-func (b UpdateBuilder) ToSql() (string, []interface{}, error) {
- data := builder.GetStruct(b).(updateData)
- return data.ToSql()
-}
-
-// MustSql builds the query into a SQL string and bound args.
-// It panics if there are any errors.
-func (b UpdateBuilder) MustSql() (string, []interface{}) {
- sql, args, err := b.ToSql()
- if err != nil {
- panic(err)
- }
- return sql, args
-}
-
-// Prefix adds an expression to the beginning of the query
-func (b UpdateBuilder) Prefix(sql string, args ...interface{}) UpdateBuilder {
- return b.PrefixExpr(Expr(sql, args...))
-}
-
-// PrefixExpr adds an expression to the very beginning of the query
-func (b UpdateBuilder) PrefixExpr(expr Sqlizer) UpdateBuilder {
- return builder.Append(b, "Prefixes", expr).(UpdateBuilder)
-}
-
-// Table sets the table to be updated.
-func (b UpdateBuilder) Table(table string) UpdateBuilder {
- return builder.Set(b, "Table", table).(UpdateBuilder)
-}
-
-// Set adds SET clauses to the query.
-func (b UpdateBuilder) Set(column string, value interface{}) UpdateBuilder {
- return builder.Append(b, "SetClauses", setClause{column: column, value: value}).(UpdateBuilder)
-}
-
-// SetMap is a convenience method which calls .Set for each key/value pair in clauses.
-func (b UpdateBuilder) SetMap(clauses map[string]interface{}) UpdateBuilder {
- keys := make([]string, len(clauses))
- i := 0
- for key := range clauses {
- keys[i] = key
- i++
- }
- sort.Strings(keys)
- for _, key := range keys {
- val, _ := clauses[key]
- b = b.Set(key, val)
- }
- return b
-}
-
-// Where adds WHERE expressions to the query.
-//
-// See SelectBuilder.Where for more information.
-func (b UpdateBuilder) Where(pred interface{}, args ...interface{}) UpdateBuilder {
- return builder.Append(b, "WhereParts", newWherePart(pred, args...)).(UpdateBuilder)
-}
-
-// OrderBy adds ORDER BY expressions to the query.
-func (b UpdateBuilder) OrderBy(orderBys ...string) UpdateBuilder {
- return builder.Extend(b, "OrderBys", orderBys).(UpdateBuilder)
-}
-
-// Limit sets a LIMIT clause on the query.
-func (b UpdateBuilder) Limit(limit uint64) UpdateBuilder {
- return builder.Set(b, "Limit", fmt.Sprintf("%d", limit)).(UpdateBuilder)
-}
-
-// Offset sets a OFFSET clause on the query.
-func (b UpdateBuilder) Offset(offset uint64) UpdateBuilder {
- return builder.Set(b, "Offset", fmt.Sprintf("%d", offset)).(UpdateBuilder)
-}
-
-// Suffix adds an expression to the end of the query
-func (b UpdateBuilder) Suffix(sql string, args ...interface{}) UpdateBuilder {
- return b.SuffixExpr(Expr(sql, args...))
-}
-
-// SuffixExpr adds an expression to the end of the query
-func (b UpdateBuilder) SuffixExpr(expr Sqlizer) UpdateBuilder {
- return builder.Append(b, "Suffixes", expr).(UpdateBuilder)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/update_ctx.go b/vendor/github.com/Masterminds/squirrel/update_ctx.go
deleted file mode 100644
index ad479f96f..000000000
--- a/vendor/github.com/Masterminds/squirrel/update_ctx.go
+++ /dev/null
@@ -1,69 +0,0 @@
-// +build go1.8
-
-package squirrel
-
-import (
- "context"
- "database/sql"
-
- "github.com/lann/builder"
-)
-
-func (d *updateData) ExecContext(ctx context.Context) (sql.Result, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(ExecerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return ExecContextWith(ctx, ctxRunner, d)
-}
-
-func (d *updateData) QueryContext(ctx context.Context) (*sql.Rows, error) {
- if d.RunWith == nil {
- return nil, RunnerNotSet
- }
- ctxRunner, ok := d.RunWith.(QueryerContext)
- if !ok {
- return nil, NoContextSupport
- }
- return QueryContextWith(ctx, ctxRunner, d)
-}
-
-func (d *updateData) QueryRowContext(ctx context.Context) RowScanner {
- if d.RunWith == nil {
- return &Row{err: RunnerNotSet}
- }
- queryRower, ok := d.RunWith.(QueryRowerContext)
- if !ok {
- if _, ok := d.RunWith.(QueryerContext); !ok {
- return &Row{err: RunnerNotQueryRunner}
- }
- return &Row{err: NoContextSupport}
- }
- return QueryRowContextWith(ctx, queryRower, d)
-}
-
-// ExecContext builds and ExecContexts the query with the Runner set by RunWith.
-func (b UpdateBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
- data := builder.GetStruct(b).(updateData)
- return data.ExecContext(ctx)
-}
-
-// QueryContext builds and QueryContexts the query with the Runner set by RunWith.
-func (b UpdateBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {
- data := builder.GetStruct(b).(updateData)
- return data.QueryContext(ctx)
-}
-
-// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.
-func (b UpdateBuilder) QueryRowContext(ctx context.Context) RowScanner {
- data := builder.GetStruct(b).(updateData)
- return data.QueryRowContext(ctx)
-}
-
-// ScanContext is a shortcut for QueryRowContext().Scan.
-func (b UpdateBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {
- return b.QueryRowContext(ctx).Scan(dest...)
-}
diff --git a/vendor/github.com/Masterminds/squirrel/where.go b/vendor/github.com/Masterminds/squirrel/where.go
deleted file mode 100644
index 976b63ace..000000000
--- a/vendor/github.com/Masterminds/squirrel/where.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package squirrel
-
-import (
- "fmt"
-)
-
-type wherePart part
-
-func newWherePart(pred interface{}, args ...interface{}) Sqlizer {
- return &wherePart{pred: pred, args: args}
-}
-
-func (p wherePart) ToSql() (sql string, args []interface{}, err error) {
- switch pred := p.pred.(type) {
- case nil:
- // no-op
- case rawSqlizer:
- return pred.toSqlRaw()
- case Sqlizer:
- return pred.ToSql()
- case map[string]interface{}:
- return Eq(pred).ToSql()
- case string:
- sql = pred
- args = p.args
- default:
- err = fmt.Errorf("expected string-keyed map or string, not %T", pred)
- }
- return
-}
diff --git a/vendor/github.com/dop251/goja/vm.go b/vendor/github.com/dop251/goja/vm.go
index 6dcdd5575..e3901c1e4 100644
--- a/vendor/github.com/dop251/goja/vm.go
+++ b/vendor/github.com/dop251/goja/vm.go
@@ -1842,9 +1842,11 @@ func (_newArrayFromIter) exec(vm *vm) {
iter := vm.iterStack[l].iter
vm.iterStack[l] = iterStackItem{}
vm.iterStack = vm.iterStack[:l]
- iter.iterate(func(val Value) {
- values = append(values, val)
- })
+ if iter.iterator != nil {
+ iter.iterate(func(val Value) {
+ values = append(values, val)
+ })
+ }
vm.push(vm.r.newArrayValues(values))
vm.pc++
}
diff --git a/vendor/github.com/doug-martin/goqu/v9/.gitignore b/vendor/github.com/doug-martin/goqu/v9/.gitignore
new file mode 100644
index 000000000..d884bf352
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/.gitignore
@@ -0,0 +1,4 @@
+.idea
+src
+*.iml
+coverage.*
\ No newline at end of file
diff --git a/vendor/github.com/doug-martin/goqu/v9/.golangci.yml b/vendor/github.com/doug-martin/goqu/v9/.golangci.yml
new file mode 100644
index 000000000..01a93ea36
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/.golangci.yml
@@ -0,0 +1,140 @@
+linters-settings:
+ funlen:
+ lines: 140
+ statements: 50
+ gci:
+ local-prefixes: github.com/golangci/golangci-lint
+ goconst:
+ min-len: 2
+ min-occurrences: 2
+ gocritic:
+ enabled-tags:
+ - diagnostic
+ - experimental
+ - opinionated
+ - performance
+ - style
+ disabled-checks:
+ - dupImport # https://github.com/go-critic/go-critic/issues/845
+ - ifElseChain
+ - octalLiteral
+ - whyNoLint
+ - wrapperFunc
+ - sqlQuery # used by tests
+ gocyclo:
+ min-complexity: 20
+ goimports:
+ local-prefixes: github.com/golangci/golangci-lint
+ golint:
+ min-confidence: 0
+ gomnd:
+ settings:
+ mnd:
+ # don't include the "operation" and "assign"
+ checks: argument,case,condition,return
+ govet:
+ check-shadowing: true
+ settings:
+ printf:
+ funcs:
+ - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
+ - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
+ - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
+ - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
+ lll:
+ line-length: 140
+ maligned:
+ suggest-new: true
+ misspell:
+ locale: US
+ nolintlint:
+ allow-leading-space: true # don't require machine-readable nolint directives (i.e. with no leading space)
+ allow-unused: false # report any unused nolint directives
+ require-explanation: false # don't require an explanation for nolint directives
+ require-specific: false # don't require nolint directives to be specific about which linter is being skipped
+ exhaustive:
+ default-signifies-exhaustive: true
+
+linters:
+ # please, do not use `enable-all`: it's deprecated and will be removed soon.
+ # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
+ disable-all: true
+ enable:
+ - asciicheck
+ - bodyclose
+ - deadcode
+ - depguard
+ - dogsled
+ - errcheck
+ - exportloopref
+ - exhaustive
+ - errcheck
+ - errorlint
+ - funlen
+ - forbidigo
+ - forcetypeassert
+ - goconst
+ - gocritic
+ - gocyclo
+ - gofmt
+ - goimports
+ - golint
+ - gomnd
+ - goprintffuncname
+ - gosec
+ - gosimple
+ - govet
+ - ifshort
+ - ineffassign
+ - lll
+ - makezero
+ - misspell
+ - nakedret
+ - nilerr
+ - noctx
+ - nolintlint
+ - prealloc
+ - predeclared
+ - rowserrcheck
+ - staticcheck
+ - structcheck
+ - stylecheck
+ - testpackage
+ - typecheck
+ - unconvert
+ - unparam
+ - unused
+ - varcheck
+ - whitespace
+
+ # don't enable:
+ # - gochecknoglobals
+ # - gocognit
+ # - godot
+ # - godox
+ # - goerr113
+ # - interfacer
+ # - maligned
+ # - nestif
+ # - revive
+ # - wsl
+ # - wrapcheck
+
+issues:
+ # Excluding configuration per-path, per-linter, per-text and per-source
+ exclude-rules:
+ - path: _test\.go
+ linters:
+ - gomnd
+
+ # https://github.com/go-critic/go-critic/issues/926
+ - linters:
+ - gocritic
+ text: "unnecessaryDefer:"
+
+run:
+ skip-dirs:
+ - test/testdata_etc
+ - internal/cache
+ - internal/renameio
+ - internal/robustio
\ No newline at end of file
diff --git a/vendor/github.com/doug-martin/goqu/v9/CODE_OF_CONDUCT.md b/vendor/github.com/doug-martin/goqu/v9/CODE_OF_CONDUCT.md
new file mode 100644
index 000000000..fbab7764d
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/CODE_OF_CONDUCT.md
@@ -0,0 +1,46 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at doug@dougamartin.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
+
+[homepage]: http://contributor-covenant.org
+[version]: http://contributor-covenant.org/version/1/4/
diff --git a/vendor/github.com/doug-martin/goqu/v9/CONTRIBUTING.md b/vendor/github.com/doug-martin/goqu/v9/CONTRIBUTING.md
new file mode 100644
index 000000000..659e0f27d
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/CONTRIBUTING.md
@@ -0,0 +1,31 @@
+## Contributions
+
+I am always welcoming contributions of any type. Please open an issue or create a PR if you find an issue with any of the following.
+
+* An issue with Documentation
+* You found the documentation lacking in some way
+
+If you have an issue with the package please include the following
+
+* The dialect you are using
+* A description of the problem
+* A short example of how to reproduce (if applicable)
+
+Without those basics it can be difficult to reproduce your issue locally. You may be asked for more information but that is a good starting point.
+
+### New Features
+
+New features and/or enhancements are great and I encourage you to either submit a PR or create an issue. In both cases include the following as the need/requirement may not be readily apparent.
+
+1. The use case
+2. A short example
+
+If you are issuing a PR also also include the following
+
+1. Tests - otherwise the PR will not be merged
+2. Documentation - otherwise the PR will not be merged
+3. Examples - [If applicable] see example_test.go for examples
+
+If you find an issue you want to work on please comment on it letting other people know you are looking at it and I will assign the issue to you.
+
+If want to work on an issue but dont know where to start just leave a comment and I'll be more than happy to point you in the right direction.
diff --git a/vendor/github.com/doug-martin/goqu/v9/HISTORY.md b/vendor/github.com/doug-martin/goqu/v9/HISTORY.md
new file mode 100644
index 000000000..04e0ce169
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/HISTORY.md
@@ -0,0 +1,404 @@
+# v9.18.0
+* [FEATURE] Add support for aliasing insert datasets to support upsert alias [#306](https://github.com/doug-martin/goqu/pull/306) - [@XIELongDragon](https://github.com/XIELongDragon)
+* [FEATURE] Add support for aliasing BooleanExpressions [#307](https://github.com/doug-martin/goqu/pull/307) - [@XIELongDragon](https://github.com/XIELongDragon)
+
+# v9.17.0
+* [FEATURE] Add support bitwise operations [#303](https://github.com/doug-martin/goqu/pull/303) - [@XIELongDragon](https://github.com/XIELongDragon)
+* [FEATURE] Add support for specifying tables to be locked in ForUpdate, ForNoKeyUpdate, ForKeyShare, ForShare [#299](https://github.com/doug-martin/goqu/pull/299) - [@jbub](https://github.com/jbub)
+
+# v9.16.0
+* [FEATURE] Allow ordering by case expression [#282](https://github.com/doug-martin/goqu/issues/282), [#292](https://github.com/doug-martin/goqu/pull/292)
+
+# v9.15.1
+* [FIX] Field indexes in the columnMap getting overridden [290](https://github.com/doug-martin/goqu/issues/290), [#291](https://github.com/doug-martin/goqu/pull/291)
+
+# v9.15.0
+* [FEATURE] Add SetDefaultPrepared which controls query value interpolation [#288](https://github.com/doug-martin/goqu/pull/288) - [@Deiz](https://github.com/Deiz)
+
+# v9.14.0
+* [FEATURE] GroupByAppend to the SelectDataset and SelectClauses [#276](https://github.com/doug-martin/goqu/pull/276), [#287](https://github.com/doug-martin/goqu/pull/287) - [@ashishkf](https://github.com/ashishkf)
+* [FEATURE] Allow untagged fields to be ignored [#285](https://github.com/doug-martin/goqu/pull/285) - [@Deiz](https://github.com/Deiz)
+* [FIX] Nil valuer [#277](https://github.com/doug-martin/goqu/pull/277) - [@benzolium](https://github.com/benzolium), [@Diggs](https://github.com/Diggs)
+* [FIX] Fix old import URL in doc comments [#286](https://github.com/doug-martin/goqu/pull/286) - [@maito1201](https://github.com/maito1201)
+
+# v9.13.0
+
+* [ADDED] ScanStructs, ScanVals to Scanner interface [#273](https://github.com/doug-martin/goqu/issues/273) - [@vlanse](https://github.com/vlanse)
+
+# v9.12.0
+
+* Update golangci-lint and updates for all associated linters
+* Update dependencies
+ * github.com/DATA-DOG/go-sqlmock v1.3.3 -> v1.5.0
+ * github.com/denisenkom/go-mssqldb v0.0.0-20200206145737-bbfc9a55622e -> v0.10.0
+ * github.com/go-sql-driver/mysql v1.4.1 -> v1.6.0
+ * github.com/lib/pq v1.2.0 -> v1.10.1
+ * github.com/mattn/go-sqlite3 v1.11.0 -> v1.14.7
+ * github.com/stretchr/testify -> v1.4.0 -> v1.7.0
+
+
+# v9.11.1
+
+* [FIXED] Avoid mutation of join slice for separate datasets when joins slice capacity is not yet reached [#261](https://github.com/doug-martin/goqu/pull/261) - [@fhaifler](https://github.com/fhaifler)
+
+# v9.11.0
+
+* [FIXED] Use valid 'IS' operator for sqlserver dialect [#240](https://github.com/doug-martin/goqu/pull/240), [#239](https://github.com/doug-martin/goqu/pull/229) - [@vlanse](https://github.com/vlanse)
+* [ADDED] Implement Orderable interface for SQL Functions [#251](https://github.com/doug-martin/goqu/pull/251) - [@GlebBeloded](https://github.com/GlebBeloded)
+* [ADDED] Support for table hint in multi-table MySQL DELETE queries [#252](https://github.com/doug-martin/goqu/pull/252) - [@vlanse](https://github.com/vlanse)
+
+# v9.10.0
+
+* [FIXED] SELECT inherits dialect from INSERT in INSERT FROM SELECT. [#229](https://github.com/doug-martin/goqu/pull/229), [#223](https://github.com/doug-martin/goqu/issues/223) - [@vlanse](https://github.com/vlanse)
+* [FIXED] SQLServer dialect: support prepared statements with TOP. [#230](https://github.com/doug-martin/goqu/pull/230), [#225](https://github.com/doug-martin/goqu/issues/225) - [@vlanse](https://github.com/vlanse)
+* [ADDED] IsPrepared to SQLExpression interface. [#231](https://github.com/doug-martin/goqu/pull/231) - [@vlanse](https://github.com/vlanse)
+
+# v9.9.0
+
+* [FIXED] SQLite do not add FOR UPDATE in SELECT. [#218](https://github.com/doug-martin/goqu/pull/218) - [@vlanse](https://github.com/vlanse)
+* [ADDED] Support for INSERT ON CONFLICT in SQLite. [#218](https://github.com/doug-martin/goqu/pull/218) - [@vlanse](https://github.com/vlanse)
+
+# v9.8.0
+
+* [ADDED] Support for ANY and ALL operators. [#196](https://github.com/doug-martin/goqu/issues/196)
+* [ADDED] Support for CASE statements [#193](https://github.com/doug-martin/goqu/issues/193)
+* [ADDED] Support for getting column identifiers from AliasExpressions. [#203](https://github.com/doug-martin/goqu/issues/203)
+
+# v9.7.1
+
+* Fix all formatting for golangci-lint
+* Move to golangci-lint github action
+
+# v9.7.0
+
+* [ADDED] Support for sqlserver dialect [#197](https://github.com/doug-martin/goqu/issues/197),[#205](https://github.com/doug-martin/goqu/issues/205) - [@vlanse](https://github.com/vlanse)
+
+# v9.6.0
+
+* [ADDED] Support for Lateral queries [#182](https://github.com/doug-martin/goqu/issues/182)
+
+# v9.5.1
+
+* [FIXED] WITH clause without a RETURNING clause will panic [#177](https://github.com/doug-martin/goqu/issues/177)
+* [FIXED] SQlite dialect escapes single quotes wrong, leads to SQL syntax error [#178](https://github.com/doug-martin/goqu/issues/178)
+* [FIXED] Fix ReturnsColumns() nil pointer panic [#181](https://github.com/doug-martin/goqu/issues/181) - [@yeaha](https://github.com/yeaha)
+* [FIXED] SelectDataset From with Error [#183](https://github.com/doug-martin/goqu/issues/183)
+* [FIXED] Unable to execute union with order by expression [#185](https://github.com/doug-martin/goqu/issues/185)
+
+# v9.5.0
+
+* [ADDED] Ability to use regexp like, ilike, notlike, and notilike without a regexp [#172](https://github.com/doug-martin/goqu/issues/172)
+
+# v9.4.0
+
+* [ADDED] Ability to scan into struct fields from multiple tables [#160](https://github.com/doug-martin/goqu/issues/160)
+
+# v9.3.0
+
+* [ADDED] Using Update, Insert, or Delete datasets in sub selects and CTEs [#164](https://github.com/doug-martin/goqu/issues/164)
+
+# v9.2.0
+
+* [ADDED] exec.Scanner: New exposed scanner supports iterative scanning [#157](https://github.com/doug-martin/goqu/pull/157) - [@akarl](https://github.com/akarl)
+
+# v9.1.0
+
+* [FIXED] ExampleDoUpdate does't work in postgres [#156](https://github.com/doug-martin/goqu/issues/156)
+* [FIXED] Issue with timezone being lost [#163](https://github.com/doug-martin/goqu/issues/163)
+
+# v9.0.1
+
+* [FIXED] Issue where `NULL`, `TRUE` and `FALSE` are interpolated when using an `IS` clause. [#165](https://github.com/doug-martin/goqu/issues/165)
+
+# v9.0.0
+
+* Changed `NULL`, `TRUE`, `FALSE` to not be interpolated when creating prepared statements. [#132](https://github.com/doug-martin/goqu/pull/132), [#158](https://github.com/doug-martin/goqu/pull/158) - [@marshallmcmullen](https://github.com/marshallmcmullen)
+* Updated dependencies
+ * `github.com/lib/pq v1.1.1 -> v1.2.0`
+ * `github.com/mattn/go-sqlite3 v1.10.0 -> v1.11.0`
+ * `github.com/stretchr/testify v1.3.0 -> v1.4.0`
+
+## v8.6.0
+
+* [ADDED] `SetError()` and `Error()` to all datasets. [#152](https://github.com/doug-martin/goqu/pull/152) and [#150](https://github.com/doug-martin/goqu/pull/150) - [@marshallmcmullen](https://github.com/marshallmcmullen)
+
+## v8.5.0
+
+* [ADDED] Window Function support [#128](https://github.com/doug-martin/goqu/issues/128) - [@Xuyuanp](https://github.com/Xuyuanp)
+
+## v8.4.1
+
+* [FIXED] Returning func be able to handle nil [#140](https://github.com/doug-martin/goqu/issues/140)
+
+## v8.4.0
+
+* Created new `sqlgen` module to encapsulate sql generation
+ * Broke SQLDialect inti new SQL generators for each statement type.
+* Test refactor
+ * Moved to a test case pattern to allow for quickly adding new test cases.
+
+## v8.3.2
+
+* [FIXED] Data race during query factory initialization [#133](https://github.com/doug-martin/goqu/issues/133) and [#136](https://github.com/doug-martin/goqu/issues/136) - [@o1egl](https://github.com/o1egl)
+
+## v8.3.1
+
+* [FIXED] InsertDataset.WithDialect return old dataset [#126](https://github.com/doug-martin/goqu/issues/126) - [@chen56](https://github.com/chen56)
+* Test clean up and more testing pattern consistency
+ * Changed to use assertion methods off of suite
+ * Updated Equals assertions to have expected output first
+* Increase overall test coverage.
+
+## v8.3.0
+
+* [Added] Support for `DISTINCT ON` clauses [#119](https://github.com/doug-martin/goqu/issues/119)
+
+## v8.2.2
+
+* [FIX] Scanner errors on pointers to primitive values [#122](https://github.com/doug-martin/goqu/issues/122)
+
+## v8.2.1
+
+* [FIX] Return an error when an empty identifier is encountered [#115](https://github.com/doug-martin/goqu/issues/115)
+
+## v8.2.0
+
+* [FIX] Fix reflection errors related to nil pointers and unexported fields [#118](https://github.com/doug-martin/goqu/issues/118)
+ * Unexported fields are ignored when creating a columnMap
+ * Nil embedded pointers will no longer cause a panic
+ * Fields on nil embedded pointers will be ignored when creating update or insert statements.
+* [ADDED] You can now ingore embedded structs and their fields by using `db:"-"` tag on the embedded struct.
+
+## v8.1.0
+
+* [ADDED] Support column DEFAULT when inserting/updating via struct [#27](https://github.com/doug-martin/goqu/issues/27)
+
+## v8.0.1
+
+* [ADDED] Multi table update support for `mysql` and `postgres` [#60](https://github.com/doug-martin/goqu/issues/60)
+* [ADDED] `goqu.V` so values can be used on the LHS of expressions [#104](https://github.com/doug-martin/goqu/issues/104)
+
+## v8.0.0
+
+A major change the the API was made in `v8` to seperate concerns between the different SQL statement types.
+
+**Why the change?**
+
+1. There were feature requests that could not be cleanly implemented with everything in a single dataset.
+2. Too much functionality was encapsulated in a single datastructure.
+ * It was unclear what methods could be used for each SQL statement type.
+ * Changing a feature for one statement type had the possiblity of breaking another statement type.
+ * Test coverage was decent but was almost solely concerned about SELECT statements, breaking them up allowed for focused testing on each statement type.
+ * Most the SQL generation methods (`ToInsertSQL`, `ToUpdateSQL` etc.) took arguments which lead to an ugly API that was not uniform for each statement type, and proved to be inflexible.
+
+**What Changed**
+
+There are now five dataset types, `SelectDataset`, `InsertDataset`, `UpdateDataset`, `DeleteDataset` and `TruncateDataset`
+
+Each dataset type has its own entry point.
+
+* `goqu.From`, `Database#From`, `DialectWrapper#From` - Create SELECT
+* `goqu.Insert`, `Database#Insert`, `DialectWrapper#Insert` - Create INSERT
+* `goqu.Update`, `Database#db.Update`, `DialectWrapper#Update` - Create UPDATE
+* `goqu.Delete`, `Database#Delete`, `DialectWrapper#Delete` - Create DELETE
+* `goqu.Truncate`, `Database#Truncate`, `DialectWrapper#Truncate` - Create TRUNCATE
+
+`ToInsertSQL`, `ToUpdateSQL`, `ToDeleteSQL`, and `ToTruncateSQL` (and variations of them) methods have been removed from the `SelectDataset`. Instead use the `ToSQL` methods on each dataset type.
+
+Each dataset type will have an `Executor` and `ToSQL` method so a common interface can be created for each type.
+
+
+## v7.4.0
+
+* [FIXED] literalTime use t.UTC() , This behavior is different from the original sql.DB [#106](https://github.com/doug-martin/goqu/issues/106) - [chen56](https://github.com/chen56)
+* [ADDED] Add new method WithTx for Database [#108](https://github.com/doug-martin/goqu/issues/108) - [Xuyuanp](https://github.com/Xuyuanp)
+
+## v7.3.1
+
+* [ADDED] Exposed `goqu.NewTx` to allow creating a goqu tx directly from a `sql.Tx` instead of using `goqu.Database#Begin` [#95](https://github.com/doug-martin/goqu/issues/95)
+* [ADDED] `goqu.Database.BeginTx` [#98](https://github.com/doug-martin/goqu/issues/98)
+
+## v7.3.0
+
+* [ADDED] UPDATE and INSERT should use struct Field name if db tag is not specified [#57](https://github.com/doug-martin/goqu/issues/57)
+* [CHANGE] Changed goqu.Database to accept a SQLDatabase interface to allow using goqu.Database with other libraries such as `sqlx` [#95](https://github.com/doug-martin/goqu/issues/95)
+
+## v7.2.0
+
+* [FIXED] Sqlite3 does not accept SELECT * UNION (SELECT *) [#79](https://github.com/doug-martin/goqu/issues/79)
+* [FIXED] Where(Ex{}) causes panics [mysql] [#49](https://github.com/doug-martin/goqu/issues/49)
+* [ADDED] Support for OrderPrepend [#61](https://github.com/doug-martin/goqu/issues/61)
+* [DOCS] Added new section about loading a dialect and using it to build SQL [#44](https://github.com/doug-martin/goqu/issues/44)
+
+## v7.1.0
+
+* [FIXED] Embedded pointers with property names that duplicate parent struct properties. [#23](https://github.com/doug-martin/goqu/issues/23)
+* [FIXED] Can't scan values using []byte or []string [#90](https://github.com/doug-martin/goqu/issues/90)
+ * When a slice that is `*sql.RawBytes`, `*[]byte` or `sql.Scanner` no errors will be returned.
+
+## v7.0.1
+
+* Fix issue where structs with pointer fields where not set properly [#86](https://github.com/doug-martin/goqu/pull/86) and [#89](https://github.com/doug-martin/goqu/pull/89) - [@efureev](https://github.com/efureev)
+
+## v7.0.0
+
+**Linting**
+* Add linting checks and fixed errors
+ * Renamed all snake_case variables to be camelCase.
+ * Fixed examples to always map to a defined method
+* Renamed `adapters` to `dialect` to more closely match their intended purpose.
+
+**API Changes**
+* Updated all sql generations methods to from `Sql` to `SQL`
+ * `ToSql` -> `ToSQL`
+ * `ToInsertSql` -> `ToInsertSQL`
+ * `ToUpdateSql` -> `ToUpdateSQL`
+ * `ToDeleteSql` -> `ToDeleteSQL`
+ * `ToTruncateSql` -> `ToTruncateSQL`
+* Abstracted out `dialect_options` from the adapter to make the dialect self contained.
+ * This also removed the dataset<->adapter co dependency making the dialect self contained.
+* Refactored the `goqu.I` method.
+ * Added new `goqu.S`, `goqu.T` and `goqu.C` methods to clarify why type of identifier you are using.
+ * `goqu.I` should only be used when you have a qualified identifier (e.g. `goqu.I("my_schema.my_table.my_col")
+* Added new `goqu.Dialect` method to make using `goqu` as an SQL builder easier.
+
+**Internal Changes**
+* Pulled expressions into their own package
+ * Broke up expressions.go into multiple files to make working with and defining them easier.
+ * Moved the user facing methods into the main `goqu` to keep the same API as before.
+* Added more examples
+* Moved non-user facing structs and interfaces to internal modules to clean up API.
+* Increased test coverage.
+
+
+## v6.1.0
+
+* Handle nil *time.Time Literal [#73](https://github.com/doug-martin/goqu/pull/73) and [#52](https://github.com/doug-martin/goqu/pull/52) - [@RoarkeRandall](https://github.com/RoarkeRandall) and [@quetz](https://github.com/quetz)
+* Add ability to change column rename function [#66](https://github.com/doug-martin/goqu/pull/66) - [@blainehansen](https://github.com/blainehansen)
+
+## v6.0.0
+
+* Updated go support to `1.10`, `1.11` and `1.12`
+* Change testify dependency from c2fo/testify back to stretchr/testify.
+* Add support for "FOR UPDATE" and "SKIP LOCKED" [#62](https://github.com/doug-martin/goqu/pull/62) - [@btubbs](https://github.com/btubbs)
+* Changed to use go modules
+
+## v5.0.0
+
+* Drop go 1.6 support, supported versions are `1.8`, `1.9` and latest
+* Add context support [#64](https://github.com/doug-martin/goqu/pull/64) - [@cmoad](https://github.com/cmoad)
+
+## v4.2.0
+
+* Add support for ON CONFLICT when using a dataset [#55](https://github.com/doug-martin/goqu/pull/55) - [@bobrnor](https://github.com/bobrnor)
+
+## v4.1.0
+
+* Support for defining WITH clauses for Common Table Expressions (CTE) [#39](https://github.com/doug-martin/goqu/pull/39) - [@Oscil8](https://github.com/Oscil8)
+
+## v4.0
+
+* Prepared(true) issues when using IS NULL comparisson operation [#33](https://github.com/doug-martin/goqu/pull/33) - [@danielfbm](https://github.com/danielfbm)
+
+## v3.3
+
+* Add `upsert` support via `InsertIgnore` and `InsertConflict` methods - [#25](https://github.com/doug-martin/goqu/pull/28) - [@aheuermann](https://github.com/aheuermann)
+* Adding vendor dependencies and updating tests to run in docker containers [#29](https://github.com/doug-martin/goqu/pull/29) - [@aheuermann](https://github.com/aheuermann)
+
+## v3.2
+
+* Add range clauses ([NOT] BETWEEN) support - [#25](https://github.com/doug-martin/goqu/pull/25) - [@denisvm](https://github.com/denisvm)
+* Readmefix [#26](https://github.com/doug-martin/goqu/pull/26) - [@tiagopotencia](https://github.com/tiagopotencia)
+
+## v3.1.3
+
+* Bugfix for chained Where() [#20](https://github.com/doug-martin/goqu/pull/20) - [@Emreu](https://github.com/Emreu)
+
+
+## v3.1.2
+
+* Fixing ScanStruct issue with embedded pointers in crud_exec [#20](https://github.com/doug-martin/goqu/pull/20) - [@ruzz311](https://github.com/ruzz311)
+
+## v3.1.1
+
+* Fixing race condition with struct_map_cache in crud_exec [#18](https://github.com/doug-martin/goqu/pull/18) - [@andymoon](https://github.com/andymoon), [@aheuermann](https://github.com/aheuermann)
+
+## v3.1.0
+
+* Version 3.1 [#14](https://github.com/doug-martin/goqu/pull/14) - [@andymoon](https://github.com/andymoon)
+ * Fix an issue with a nil pointer access on the inserts and updates.
+ * Allowing ScanStructs to take a struct with an embedded pointer to a struct.
+ * Change to check if struct is Anonymous when recursing through an embedded struct.
+ * Updated to use the latest version of github.com/DATA-DOG/go-sqlmock.
+
+## v3.0.1
+
+* Add literal bytes and update to c2fo testify [#15](https://github.com/doug-martin/goqu/pull/15) - [@TechnotronicOz](https://github.com/TechnotronicOz)
+
+## v3.0.0
+
+* Added support for embedded structs when inserting or updating. [#13](https://github.com/doug-martin/goqu/pull/13) - [@andymoon](https://github.com/andymoon)
+
+## v2.0.3
+
+* Fixed issue with transient columns and the auto select of columns.
+
+## v2.0.2
+
+* Changed references to "github.com/doug-martin/goqu" to "gopkg.in/doug-martin/goqu.v2"
+
+## v2.0.1
+
+* Fixed issue when `ScanStruct(s)` was used with `SelectDistinct` and caused a panic.
+
+## v2.0.0
+
+* When scanning a struct or slice of structs, the struct(s) will be parsed for the column names to select. [#9](https://github.com/doug-martin/goqu/pull/9) - [@technotronicoz](https://github.com/TechnotronicOz)
+
+## v1.0.0
+
+* You can now passed an IdentiferExpression to `As` [#8](https://github.com/doug-martin/goqu/pull/8) - [@croachrose](https://github.com/croachrose)
+* Added info about installation through [gopkg.in](http://labix.org/gopkg.in)
+
+## v0.3.1
+
+* Fixed issue setting Logger when starting a new transaction.
+
+## v0.3.0
+
+* Changed sql generation methods to use a common naming convention. `To(Sql|Insert|Update|Delete)`
+ * Also changed to have common return values `string, []interface{}, error)`
+* Added `Dataset.Prepared` which allows a user to specify whether or not SQL should be interpolated. [#7](https://github.com/doug-martin/goqu/issues/7)
+* Updated Docs
+ * More examples
+* Increased test coverage.
+
+## v0.2.0
+
+* Changed `CrudExec` to not wrap driver errors in a GoquError [#2](https://github.com/doug-martin/goqu/issues/2)
+* Added ability to use a dataset in an `Ex` map or `Eq` expression without having to use `In` [#3](https://github.com/doug-martin/goqu/issues/3)
+ * `db.From("test").Where(goqu.Ex{"a": db.From("test").Select("b")})`
+* Updated readme with links to [`DefaultAdapter`](https://godoc.org/github.com/doug-martin/goqu#DefaultAdapter)
+
+## v0.1.1
+
+* Added SQLite3 adapter [#1](https://github.com/doug-martin/goqu/pull/1) - [@mattn](https://github.com/mattn)
+
+## v0.1.0
+
+* Added:
+ * [`Ex`](https://godoc.org/github.com/doug-martin/goqu#Ex)
+ * [`ExOr`](https://godoc.org/github.com/doug-martin/goqu#ExOr)
+ * [`Op`](https://godoc.org/github.com/doug-martin/goqu#Op)
+* More tests and examples
+* Added CONTRIBUTING.md
+* Added LICENSE information
+* Removed godoc introduction in favor of just maintaining the README.
+
+## v0.0.2
+
+* Fixed issue with goqu.New not returning a pointer to a Database
+
+## v0.0.1
+
+* Initial release
diff --git a/vendor/github.com/lann/builder/LICENSE b/vendor/github.com/doug-martin/goqu/v9/LICENSE
similarity index 96%
rename from vendor/github.com/lann/builder/LICENSE
rename to vendor/github.com/doug-martin/goqu/v9/LICENSE
index a109e8051..a21ac62a3 100644
--- a/vendor/github.com/lann/builder/LICENSE
+++ b/vendor/github.com/doug-martin/goqu/v9/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2014-2015 Lann Martin
+Copyright (c) 2017 Doug Martin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/vendor/github.com/doug-martin/goqu/v9/Makefile b/vendor/github.com/doug-martin/goqu/v9/Makefile
new file mode 100644
index 000000000..38aa8958d
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/Makefile
@@ -0,0 +1,6 @@
+#phony dependency task that does nothing
+#"make executable" does not run if there is a ./executable directory, unless the task has a dependency
+phony:
+
+lint:
+ docker run --rm -v ${CURDIR}:/app -w /app golangci/golangci-lint:v1.23.8 golangci-lint run -v
diff --git a/vendor/github.com/doug-martin/goqu/v9/README.md b/vendor/github.com/doug-martin/goqu/v9/README.md
new file mode 100644
index 000000000..1f470fdb9
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/README.md
@@ -0,0 +1,310 @@
+```
+ __ _ ___ __ _ _ _
+ / _` |/ _ \ / _` | | | |
+| (_| | (_) | (_| | |_| |
+ \__, |\___/ \__, |\__,_|
+ |___/ |_|
+```
+[](https://github.com/doug-martin/goqu/releases)
+[](https://github.com/doug-martin/goqu/actions?query=workflow%3ATest+and+branch%3Amaster+)
+[](https://pkg.go.dev/github.com/doug-martin/goqu/v9)
+[](https://codecov.io/gh/doug-martin/goqu)
+[](https://goreportcard.com/report/github.com/doug-martin/goqu/v9)
+
+`goqu` is an expressive SQL builder and executor
+
+If you are upgrading from an older version please read the [Migrating Between Versions](./docs/version_migration.md) docs.
+
+
+## Installation
+
+If using go modules.
+
+```sh
+go get -u github.com/doug-martin/goqu/v9
+```
+
+If you are not using go modules...
+
+**NOTE** You should still be able to use this package if you are using go version `>v1.10` but, you will need to drop the version from the package. `import "github.com/doug-martin/goqu/v9` -> `import "github.com/doug-martin/goqu"`
+
+```sh
+go get -u github.com/doug-martin/goqu
+```
+
+### [Migrating Between Versions](./docs/version_migration.md)
+
+## Features
+
+`goqu` comes with many features but here are a few of the more notable ones
+
+* Query Builder
+* Parameter interpolation (e.g `SELECT * FROM "items" WHERE "id" = ?` -> `SELECT * FROM "items" WHERE "id" = 1`)
+* Built from the ground up with multiple dialects in mind
+* Insert, Multi Insert, Update, and Delete support
+* Scanning of rows to struct[s] or primitive value[s]
+
+While goqu may support the scanning of rows into structs it is not intended to be used as an ORM if you are looking for common ORM features like associations,
+or hooks I would recommend looking at some of the great ORM libraries such as:
+
+* [gorm](https://github.com/jinzhu/gorm)
+* [hood](https://github.com/eaigner/hood)
+
+## Why?
+
+We tried a few other sql builders but each was a thin wrapper around sql fragments that we found error prone. `goqu` was built with the following goals in mind:
+
+* Make the generation of SQL easy and enjoyable
+* Create an expressive DSL that would find common errors with SQL at compile time.
+* Provide a DSL that accounts for the common SQL expressions, NOT every nuance for each database.
+* Provide developers the ability to:
+ * Use SQL when desired
+ * Easily scan results into primitive values and structs
+ * Use the native sql.Db methods when desired
+
+## Docs
+
+* [Dialect](./docs/dialect.md) - Introduction to different dialects (`mysql`, `postgres`, `sqlite3`, `sqlserver` etc)
+* [Expressions](./docs/expressions.md) - Introduction to `goqu` expressions and common examples.
+* [Select Dataset](./docs/selecting.md) - Docs and examples about creating and executing SELECT sql statements.
+* [Insert Dataset](./docs/inserting.md) - Docs and examples about creating and executing INSERT sql statements.
+* [Update Dataset](./docs/updating.md) - Docs and examples about creating and executing UPDATE sql statements.
+* [Delete Dataset](./docs/deleting.md) - Docs and examples about creating and executing DELETE sql statements.
+* [Prepared Statements](./docs/interpolation.md) - Docs about interpolation and prepared statements in `goqu`.
+* [Database](./docs/database.md) - Docs and examples of using a Database to execute queries in `goqu`
+* [Working with time.Time](./docs/time.md) - Docs on how to use alternate time locations.
+
+## Quick Examples
+
+### Select
+
+See the [select dataset](./docs/selecting.md) docs for more in depth examples
+
+```go
+sql, _, _ := goqu.From("test").ToSQL()
+fmt.Println(sql)
+```
+
+Output:
+
+```
+SELECT * FROM "test"
+```
+
+```go
+sql, _, _ := goqu.From("test").Where(goqu.Ex{
+ "d": []string{"a", "b", "c"},
+}).ToSQL()
+fmt.Println(sql)
+```
+
+Output:
+
+```
+SELECT * FROM "test" WHERE ("d" IN ('a', 'b', 'c'))
+```
+
+### Insert
+
+See the [insert dataset](./docs/inserting.md) docs for more in depth examples
+
+```go
+ds := goqu.Insert("user").
+ Cols("first_name", "last_name").
+ Vals(
+ goqu.Vals{"Greg", "Farley"},
+ goqu.Vals{"Jimmy", "Stewart"},
+ goqu.Vals{"Jeff", "Jeffers"},
+ )
+insertSQL, args, _ := ds.ToSQL()
+fmt.Println(insertSQL, args)
+```
+
+Output:
+```sql
+INSERT INTO "user" ("first_name", "last_name") VALUES ('Greg', 'Farley'), ('Jimmy', 'Stewart'), ('Jeff', 'Jeffers') []
+```
+
+```go
+ds := goqu.Insert("user").Rows(
+ goqu.Record{"first_name": "Greg", "last_name": "Farley"},
+ goqu.Record{"first_name": "Jimmy", "last_name": "Stewart"},
+ goqu.Record{"first_name": "Jeff", "last_name": "Jeffers"},
+)
+insertSQL, args, _ := ds.ToSQL()
+fmt.Println(insertSQL, args)
+```
+
+Output:
+```
+INSERT INTO "user" ("first_name", "last_name") VALUES ('Greg', 'Farley'), ('Jimmy', 'Stewart'), ('Jeff', 'Jeffers') []
+```
+
+
+```go
+type User struct {
+ FirstName string `db:"first_name"`
+ LastName string `db:"last_name"`
+}
+ds := goqu.Insert("user").Rows(
+ User{FirstName: "Greg", LastName: "Farley"},
+ User{FirstName: "Jimmy", LastName: "Stewart"},
+ User{FirstName: "Jeff", LastName: "Jeffers"},
+)
+insertSQL, args, _ := ds.ToSQL()
+fmt.Println(insertSQL, args)
+```
+
+Output:
+```
+INSERT INTO "user" ("first_name", "last_name") VALUES ('Greg', 'Farley'), ('Jimmy', 'Stewart'), ('Jeff', 'Jeffers') []
+```
+
+```go
+ds := goqu.Insert("user").Prepared(true).
+ FromQuery(goqu.From("other_table"))
+insertSQL, args, _ := ds.ToSQL()
+fmt.Println(insertSQL, args)
+```
+
+Output:
+```
+INSERT INTO "user" SELECT * FROM "other_table" []
+```
+
+```go
+ds := goqu.Insert("user").Prepared(true).
+ Cols("first_name", "last_name").
+ FromQuery(goqu.From("other_table").Select("fn", "ln"))
+insertSQL, args, _ := ds.ToSQL()
+fmt.Println(insertSQL, args)
+```
+
+Output:
+```
+INSERT INTO "user" ("first_name", "last_name") SELECT "fn", "ln" FROM "other_table" []
+```
+
+### Update
+
+See the [update dataset](./docs/updating.md) docs for more in depth examples
+
+```go
+sql, args, _ := goqu.Update("items").Set(
+ goqu.Record{"name": "Test", "address": "111 Test Addr"},
+).ToSQL()
+fmt.Println(sql, args)
+```
+
+Output:
+```
+UPDATE "items" SET "address"='111 Test Addr',"name"='Test' []
+```
+
+```go
+type item struct {
+ Address string `db:"address"`
+ Name string `db:"name" goqu:"skipupdate"`
+}
+sql, args, _ := goqu.Update("items").Set(
+ item{Name: "Test", Address: "111 Test Addr"},
+).ToSQL()
+fmt.Println(sql, args)
+```
+
+Output:
+```
+UPDATE "items" SET "address"='111 Test Addr' []
+```
+
+```go
+sql, _, _ := goqu.Update("test").
+ Set(goqu.Record{"foo": "bar"}).
+ Where(goqu.Ex{
+ "a": goqu.Op{"gt": 10}
+ }).ToSQL()
+fmt.Println(sql)
+```
+
+Output:
+```
+UPDATE "test" SET "foo"='bar' WHERE ("a" > 10)
+```
+
+### Delete
+
+See the [delete dataset](./docs/deleting.md) docs for more in depth examples
+
+```go
+ds := goqu.Delete("items")
+
+sql, args, _ := ds.ToSQL()
+fmt.Println(sql, args)
+```
+
+```go
+sql, _, _ := goqu.Delete("test").Where(goqu.Ex{
+ "c": nil
+ }).ToSQL()
+fmt.Println(sql)
+```
+
+Output:
+```
+DELETE FROM "test" WHERE ("c" IS NULL)
+```
+
+
+## Contributions
+
+I am always welcoming contributions of any type. Please open an issue or create a PR if you find an issue with any of the following.
+
+* An issue with Documentation
+* You found the documentation lacking in some way
+
+If you have an issue with the package please include the following
+
+* The dialect you are using
+* A description of the problem
+* A short example of how to reproduce (if applicable)
+
+Without those basics it can be difficult to reproduce your issue locally. You may be asked for more information but that is a good starting point.
+
+### New Features
+
+New features and/or enhancements are great and I encourage you to either submit a PR or create an issue. In both cases include the following as the need/requirement may not be readily apparent.
+
+1. The use case
+2. A short example
+
+If you are issuing a PR also include the following
+
+1. Tests - otherwise the PR will not be merged
+2. Documentation - otherwise the PR will not be merged
+3. Examples - [If applicable] see example_test.go for examples
+
+If you find an issue you want to work on please comment on it letting other people know you are looking at it and I will assign the issue to you.
+
+If want to work on an issue but dont know where to start just leave a comment and I'll be more than happy to point you in the right direction.
+
+### Running tests
+The test suite requires a postgres, mysql and sqlserver databases. You can override the connection strings with the [`MYSQL_URI`, `PG_URI`, `SQLSERVER_URI` environment variables](https://github.com/doug-martin/goqu/blob/2fe3349/docker-compose.yml#L26)*
+
+```sh
+go test -v -race ./...
+```
+
+You can also run the tests in a container using [docker-compose](https://docs.docker.com/compose/).
+
+```sh
+MYSQL_VERSION=8 POSTGRES_VERSION=13.4 SQLSERVER_VERSION=2017-CU8-ubuntu GO_VERSION=latest docker-compose run goqu
+```
+
+## License
+
+`goqu` is released under the [MIT License](http://www.opensource.org/licenses/MIT).
+
+
+
+
+
diff --git a/vendor/github.com/doug-martin/goqu/v9/_config.yml b/vendor/github.com/doug-martin/goqu/v9/_config.yml
new file mode 100644
index 000000000..c4192631f
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/_config.yml
@@ -0,0 +1 @@
+theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/vendor/github.com/doug-martin/goqu/v9/codecov.yml b/vendor/github.com/doug-martin/goqu/v9/codecov.yml
new file mode 100644
index 000000000..a3d9cd50b
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/codecov.yml
@@ -0,0 +1,3 @@
+ignore:
+ - "**/mocks/**" # glob accepted
+ - "mocks/**" # glob accepted
\ No newline at end of file
diff --git a/vendor/github.com/doug-martin/goqu/v9/database.go b/vendor/github.com/doug-martin/goqu/v9/database.go
new file mode 100644
index 000000000..3dce8d5c7
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/database.go
@@ -0,0 +1,648 @@
+package goqu
+
+import (
+ "context"
+ "database/sql"
+ "sync"
+
+ "github.com/doug-martin/goqu/v9/exec"
+)
+
+type (
+ Logger interface {
+ Printf(format string, v ...interface{})
+ }
+ // Interface for sql.DB, an interface is used so you can use with other
+ // libraries such as sqlx instead of the native sql.DB
+ SQLDatabase interface {
+ Begin() (*sql.Tx, error)
+ BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
+ ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
+ PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
+ QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
+ QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
+ }
+ // This struct is the wrapper for a Db. The struct delegates most calls to either an Exec instance or to the Db
+ // passed into the constructor.
+ Database struct {
+ logger Logger
+ dialect string
+ // nolint: stylecheck // keep for backwards compatibility
+ Db SQLDatabase
+ qf exec.QueryFactory
+ qfOnce sync.Once
+ }
+)
+
+// This is the common entry point into goqu.
+//
+// dialect: This is the adapter dialect, you should see your database adapter for the string to use. Built in adapters
+// can be found at https://github.com/doug-martin/goqu/tree/master/adapters
+//
+// db: A sql.Db to use for querying the database
+// import (
+// "database/sql"
+// "fmt"
+// "github.com/doug-martin/goqu/v9"
+// _ "github.com/doug-martin/goqu/v9/dialect/postgres"
+// _ "github.com/lib/pq"
+// )
+//
+// func main() {
+// sqlDb, err := sql.Open("postgres", "user=postgres dbname=goqupostgres sslmode=disable ")
+// if err != nil {
+// panic(err.Error())
+// }
+// db := goqu.New("postgres", sqlDb)
+// }
+// The most commonly used Database method is From, which creates a new Dataset that uses the correct adapter and
+// supports queries.
+// var ids []uint32
+// if err := db.From("items").Where(goqu.I("id").Gt(10)).Pluck("id", &ids); err != nil {
+// panic(err.Error())
+// }
+// fmt.Printf("%+v", ids)
+func newDatabase(dialect string, db SQLDatabase) *Database {
+ return &Database{
+ logger: nil,
+ dialect: dialect,
+ Db: db,
+ qf: nil,
+ qfOnce: sync.Once{},
+ }
+}
+
+// returns this databases dialect
+func (d *Database) Dialect() string {
+ return d.dialect
+}
+
+// Starts a new Transaction.
+func (d *Database) Begin() (*TxDatabase, error) {
+ sqlTx, err := d.Db.Begin()
+ if err != nil {
+ return nil, err
+ }
+ tx := NewTx(d.dialect, sqlTx)
+ tx.Logger(d.logger)
+ return tx, nil
+}
+
+// Starts a new Transaction. See sql.DB#BeginTx for option description
+func (d *Database) BeginTx(ctx context.Context, opts *sql.TxOptions) (*TxDatabase, error) {
+ sqlTx, err := d.Db.BeginTx(ctx, opts)
+ if err != nil {
+ return nil, err
+ }
+ tx := NewTx(d.dialect, sqlTx)
+ tx.Logger(d.logger)
+ return tx, nil
+}
+
+// WithTx starts a new transaction and executes it in Wrap method
+func (d *Database) WithTx(fn func(*TxDatabase) error) error {
+ tx, err := d.Begin()
+ if err != nil {
+ return err
+ }
+ return tx.Wrap(func() error { return fn(tx) })
+}
+
+// Creates a new Dataset that uses the correct adapter and supports queries.
+// var ids []uint32
+// if err := db.From("items").Where(goqu.I("id").Gt(10)).Pluck("id", &ids); err != nil {
+// panic(err.Error())
+// }
+// fmt.Printf("%+v", ids)
+//
+// from...: Sources for you dataset, could be table names (strings), a goqu.Literal or another goqu.Dataset
+func (d *Database) From(from ...interface{}) *SelectDataset {
+ return newDataset(d.dialect, d.queryFactory()).From(from...)
+}
+
+func (d *Database) Select(cols ...interface{}) *SelectDataset {
+ return newDataset(d.dialect, d.queryFactory()).Select(cols...)
+}
+
+func (d *Database) Update(table interface{}) *UpdateDataset {
+ return newUpdateDataset(d.dialect, d.queryFactory()).Table(table)
+}
+
+func (d *Database) Insert(table interface{}) *InsertDataset {
+ return newInsertDataset(d.dialect, d.queryFactory()).Into(table)
+}
+
+func (d *Database) Delete(table interface{}) *DeleteDataset {
+ return newDeleteDataset(d.dialect, d.queryFactory()).From(table)
+}
+
+func (d *Database) Truncate(table ...interface{}) *TruncateDataset {
+ return newTruncateDataset(d.dialect, d.queryFactory()).Table(table...)
+}
+
+// Sets the logger for to use when logging queries
+func (d *Database) Logger(logger Logger) {
+ d.logger = logger
+}
+
+// Logs a given operation with the specified sql and arguments
+func (d *Database) Trace(op, sqlString string, args ...interface{}) {
+ if d.logger != nil {
+ if sqlString != "" {
+ if len(args) != 0 {
+ d.logger.Printf("[goqu] %s [query:=`%s` args:=%+v]", op, sqlString, args)
+ } else {
+ d.logger.Printf("[goqu] %s [query:=`%s`]", op, sqlString)
+ }
+ } else {
+ d.logger.Printf("[goqu] %s", op)
+ }
+ }
+}
+
+// Uses the db to Execute the query with arguments and return the sql.Result
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) Exec(query string, args ...interface{}) (sql.Result, error) {
+ return d.ExecContext(context.Background(), query, args...)
+}
+
+// Uses the db to Execute the query with arguments and return the sql.Result
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
+ d.Trace("EXEC", query, args...)
+ return d.Db.ExecContext(ctx, query, args...)
+}
+
+// Can be used to prepare a query.
+//
+// You can use this in tandem with a dataset by doing the following.
+// sql, args, err := db.From("items").Where(goqu.I("id").Gt(10)).ToSQL(true)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// stmt, err := db.Prepare(sql)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// defer stmt.Close()
+// rows, err := stmt.Query(args)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// defer rows.Close()
+// for rows.Next(){
+// //scan your rows
+// }
+// if rows.Err() != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+//
+// query: The SQL statement to prepare.
+func (d *Database) Prepare(query string) (*sql.Stmt, error) {
+ return d.PrepareContext(context.Background(), query)
+}
+
+// Can be used to prepare a query.
+//
+// You can use this in tandem with a dataset by doing the following.
+// sql, args, err := db.From("items").Where(goqu.I("id").Gt(10)).ToSQL(true)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// stmt, err := db.Prepare(sql)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// defer stmt.Close()
+// rows, err := stmt.QueryContext(ctx, args)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// defer rows.Close()
+// for rows.Next(){
+// //scan your rows
+// }
+// if rows.Err() != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+//
+// query: The SQL statement to prepare.
+func (d *Database) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
+ d.Trace("PREPARE", query)
+ return d.Db.PrepareContext(ctx, query)
+}
+
+// Used to query for multiple rows.
+//
+// You can use this in tandem with a dataset by doing the following.
+// sql, err := db.From("items").Where(goqu.I("id").Gt(10)).ToSQL()
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// rows, err := stmt.Query(args)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// defer rows.Close()
+// for rows.Next(){
+// //scan your rows
+// }
+// if rows.Err() != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) Query(query string, args ...interface{}) (*sql.Rows, error) {
+ return d.QueryContext(context.Background(), query, args...)
+}
+
+// Used to query for multiple rows.
+//
+// You can use this in tandem with a dataset by doing the following.
+// sql, err := db.From("items").Where(goqu.I("id").Gt(10)).ToSQL()
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// rows, err := stmt.QueryContext(ctx, args)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// defer rows.Close()
+// for rows.Next(){
+// //scan your rows
+// }
+// if rows.Err() != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
+ d.Trace("QUERY", query, args...)
+ return d.Db.QueryContext(ctx, query, args...)
+}
+
+// Used to query for a single row.
+//
+// You can use this in tandem with a dataset by doing the following.
+// sql, err := db.From("items").Where(goqu.I("id").Gt(10)).Limit(1).ToSQL()
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// rows, err := stmt.QueryRow(args)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// //scan your row
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) QueryRow(query string, args ...interface{}) *sql.Row {
+ return d.QueryRowContext(context.Background(), query, args...)
+}
+
+// Used to query for a single row.
+//
+// You can use this in tandem with a dataset by doing the following.
+// sql, err := db.From("items").Where(goqu.I("id").Gt(10)).Limit(1).ToSQL()
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// rows, err := stmt.QueryRowContext(ctx, args)
+// if err != nil{
+// panic(err.Error()) //you could gracefully handle the error also
+// }
+// //scan your row
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
+ d.Trace("QUERY ROW", query, args...)
+ return d.Db.QueryRowContext(ctx, query, args...)
+}
+
+func (d *Database) queryFactory() exec.QueryFactory {
+ d.qfOnce.Do(func() {
+ d.qf = exec.NewQueryFactory(d)
+ })
+ return d.qf
+}
+
+// Queries the database using the supplied query, and args and uses CrudExec.ScanStructs to scan the results into a
+// slice of structs
+//
+// i: A pointer to a slice of structs
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanStructs(i interface{}, query string, args ...interface{}) error {
+ return d.ScanStructsContext(context.Background(), i, query, args...)
+}
+
+// Queries the database using the supplied context, query, and args and uses CrudExec.ScanStructsContext to scan the
+// results into a slice of structs
+//
+// i: A pointer to a slice of structs
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanStructsContext(ctx context.Context, i interface{}, query string, args ...interface{}) error {
+ return d.queryFactory().FromSQL(query, args...).ScanStructsContext(ctx, i)
+}
+
+// Queries the database using the supplied query, and args and uses CrudExec.ScanStruct to scan the results into a
+// struct
+//
+// i: A pointer to a struct
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanStruct(i interface{}, query string, args ...interface{}) (bool, error) {
+ return d.ScanStructContext(context.Background(), i, query, args...)
+}
+
+// Queries the database using the supplied context, query, and args and uses CrudExec.ScanStructContext to scan the
+// results into a struct
+//
+// i: A pointer to a struct
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanStructContext(ctx context.Context, i interface{}, query string, args ...interface{}) (bool, error) {
+ return d.queryFactory().FromSQL(query, args...).ScanStructContext(ctx, i)
+}
+
+// Queries the database using the supplied query, and args and uses CrudExec.ScanVals to scan the results into a slice
+// of primitive values
+//
+// i: A pointer to a slice of primitive values
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanVals(i interface{}, query string, args ...interface{}) error {
+ return d.ScanValsContext(context.Background(), i, query, args...)
+}
+
+// Queries the database using the supplied context, query, and args and uses CrudExec.ScanValsContext to scan the
+// results into a slice of primitive values
+//
+// i: A pointer to a slice of primitive values
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanValsContext(ctx context.Context, i interface{}, query string, args ...interface{}) error {
+ return d.queryFactory().FromSQL(query, args...).ScanValsContext(ctx, i)
+}
+
+// Queries the database using the supplied query, and args and uses CrudExec.ScanVal to scan the results into a
+// primitive value
+//
+// i: A pointer to a primitive value
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanVal(i interface{}, query string, args ...interface{}) (bool, error) {
+ return d.ScanValContext(context.Background(), i, query, args...)
+}
+
+// Queries the database using the supplied context, query, and args and uses CrudExec.ScanValContext to scan the
+// results into a primitive value
+//
+// i: A pointer to a primitive value
+//
+// query: The SQL to execute
+//
+// args...: for any placeholder parameters in the query
+func (d *Database) ScanValContext(ctx context.Context, i interface{}, query string, args ...interface{}) (bool, error) {
+ return d.queryFactory().FromSQL(query, args...).ScanValContext(ctx, i)
+}
+
+// A wrapper around a sql.Tx and works the same way as Database
+type (
+ // Interface for sql.Tx, an interface is used so you can use with other
+ // libraries such as sqlx instead of the native sql.DB
+ SQLTx interface {
+ ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
+ PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
+ QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
+ QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
+ Commit() error
+ Rollback() error
+ }
+ TxDatabase struct {
+ logger Logger
+ dialect string
+ Tx SQLTx
+ qf exec.QueryFactory
+ qfOnce sync.Once
+ }
+)
+
+// Creates a new TxDatabase
+func NewTx(dialect string, tx SQLTx) *TxDatabase {
+ return &TxDatabase{dialect: dialect, Tx: tx}
+}
+
+// returns this databases dialect
+func (td *TxDatabase) Dialect() string {
+ return td.dialect
+}
+
+// Creates a new Dataset for querying a Database.
+func (td *TxDatabase) From(cols ...interface{}) *SelectDataset {
+ return newDataset(td.dialect, td.queryFactory()).From(cols...)
+}
+
+func (td *TxDatabase) Select(cols ...interface{}) *SelectDataset {
+ return newDataset(td.dialect, td.queryFactory()).Select(cols...)
+}
+
+func (td *TxDatabase) Update(table interface{}) *UpdateDataset {
+ return newUpdateDataset(td.dialect, td.queryFactory()).Table(table)
+}
+
+func (td *TxDatabase) Insert(table interface{}) *InsertDataset {
+ return newInsertDataset(td.dialect, td.queryFactory()).Into(table)
+}
+
+func (td *TxDatabase) Delete(table interface{}) *DeleteDataset {
+ return newDeleteDataset(td.dialect, td.queryFactory()).From(table)
+}
+
+func (td *TxDatabase) Truncate(table ...interface{}) *TruncateDataset {
+ return newTruncateDataset(td.dialect, td.queryFactory()).Table(table...)
+}
+
+// Sets the logger
+func (td *TxDatabase) Logger(logger Logger) {
+ td.logger = logger
+}
+
+func (td *TxDatabase) Trace(op, sqlString string, args ...interface{}) {
+ if td.logger != nil {
+ if sqlString != "" {
+ if len(args) != 0 {
+ td.logger.Printf("[goqu - transaction] %s [query:=`%s` args:=%+v] ", op, sqlString, args)
+ } else {
+ td.logger.Printf("[goqu - transaction] %s [query:=`%s`] ", op, sqlString)
+ }
+ } else {
+ td.logger.Printf("[goqu - transaction] %s", op)
+ }
+ }
+}
+
+// See Database#Exec
+func (td *TxDatabase) Exec(query string, args ...interface{}) (sql.Result, error) {
+ return td.ExecContext(context.Background(), query, args...)
+}
+
+// See Database#ExecContext
+func (td *TxDatabase) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
+ td.Trace("EXEC", query, args...)
+ return td.Tx.ExecContext(ctx, query, args...)
+}
+
+// See Database#Prepare
+func (td *TxDatabase) Prepare(query string) (*sql.Stmt, error) {
+ return td.PrepareContext(context.Background(), query)
+}
+
+// See Database#PrepareContext
+func (td *TxDatabase) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
+ td.Trace("PREPARE", query)
+ return td.Tx.PrepareContext(ctx, query)
+}
+
+// See Database#Query
+func (td *TxDatabase) Query(query string, args ...interface{}) (*sql.Rows, error) {
+ return td.QueryContext(context.Background(), query, args...)
+}
+
+// See Database#QueryContext
+func (td *TxDatabase) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
+ td.Trace("QUERY", query, args...)
+ return td.Tx.QueryContext(ctx, query, args...)
+}
+
+// See Database#QueryRow
+func (td *TxDatabase) QueryRow(query string, args ...interface{}) *sql.Row {
+ return td.QueryRowContext(context.Background(), query, args...)
+}
+
+// See Database#QueryRowContext
+func (td *TxDatabase) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
+ td.Trace("QUERY ROW", query, args...)
+ return td.Tx.QueryRowContext(ctx, query, args...)
+}
+
+func (td *TxDatabase) queryFactory() exec.QueryFactory {
+ td.qfOnce.Do(func() {
+ td.qf = exec.NewQueryFactory(td)
+ })
+ return td.qf
+}
+
+// See Database#ScanStructs
+func (td *TxDatabase) ScanStructs(i interface{}, query string, args ...interface{}) error {
+ return td.ScanStructsContext(context.Background(), i, query, args...)
+}
+
+// See Database#ScanStructsContext
+func (td *TxDatabase) ScanStructsContext(ctx context.Context, i interface{}, query string, args ...interface{}) error {
+ return td.queryFactory().FromSQL(query, args...).ScanStructsContext(ctx, i)
+}
+
+// See Database#ScanStruct
+func (td *TxDatabase) ScanStruct(i interface{}, query string, args ...interface{}) (bool, error) {
+ return td.ScanStructContext(context.Background(), i, query, args...)
+}
+
+// See Database#ScanStructContext
+func (td *TxDatabase) ScanStructContext(ctx context.Context, i interface{}, query string, args ...interface{}) (bool, error) {
+ return td.queryFactory().FromSQL(query, args...).ScanStructContext(ctx, i)
+}
+
+// See Database#ScanVals
+func (td *TxDatabase) ScanVals(i interface{}, query string, args ...interface{}) error {
+ return td.ScanValsContext(context.Background(), i, query, args...)
+}
+
+// See Database#ScanValsContext
+func (td *TxDatabase) ScanValsContext(ctx context.Context, i interface{}, query string, args ...interface{}) error {
+ return td.queryFactory().FromSQL(query, args...).ScanValsContext(ctx, i)
+}
+
+// See Database#ScanVal
+func (td *TxDatabase) ScanVal(i interface{}, query string, args ...interface{}) (bool, error) {
+ return td.ScanValContext(context.Background(), i, query, args...)
+}
+
+// See Database#ScanValContext
+func (td *TxDatabase) ScanValContext(ctx context.Context, i interface{}, query string, args ...interface{}) (bool, error) {
+ return td.queryFactory().FromSQL(query, args...).ScanValContext(ctx, i)
+}
+
+// COMMIT the transaction
+func (td *TxDatabase) Commit() error {
+ td.Trace("COMMIT", "")
+ return td.Tx.Commit()
+}
+
+// ROLLBACK the transaction
+func (td *TxDatabase) Rollback() error {
+ td.Trace("ROLLBACK", "")
+ return td.Tx.Rollback()
+}
+
+// A helper method that will automatically COMMIT or ROLLBACK once the supplied function is done executing
+//
+// tx, err := db.Begin()
+// if err != nil{
+// panic(err.Error()) // you could gracefully handle the error also
+// }
+// if err := tx.Wrap(func() error{
+// if _, err := tx.From("test").Insert(Record{"a":1, "b": "b"}).Exec(){
+// // this error will be the return error from the Wrap call
+// return err
+// }
+// return nil
+// }); err != nil{
+// panic(err.Error()) // you could gracefully handle the error also
+// }
+func (td *TxDatabase) Wrap(fn func() error) (err error) {
+ defer func() {
+ if p := recover(); p != nil {
+ _ = td.Rollback()
+ panic(p)
+ }
+ if err != nil {
+ if rollbackErr := td.Rollback(); rollbackErr != nil {
+ err = rollbackErr
+ }
+ } else {
+ if commitErr := td.Commit(); commitErr != nil {
+ err = commitErr
+ }
+ }
+ }()
+ return fn()
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/delete_dataset.go b/vendor/github.com/doug-martin/goqu/v9/delete_dataset.go
new file mode 100644
index 000000000..320925a97
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/delete_dataset.go
@@ -0,0 +1,244 @@
+package goqu
+
+import (
+ "github.com/doug-martin/goqu/v9/exec"
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+var ErrBadFromArgument = errors.New("unsupported DeleteDataset#From argument, a string or identifier expression is required")
+
+type DeleteDataset struct {
+ dialect SQLDialect
+ clauses exp.DeleteClauses
+ isPrepared prepared
+ queryFactory exec.QueryFactory
+ err error
+}
+
+// used internally by database to create a database with a specific adapter
+func newDeleteDataset(d string, queryFactory exec.QueryFactory) *DeleteDataset {
+ return &DeleteDataset{
+ clauses: exp.NewDeleteClauses(),
+ dialect: GetDialect(d),
+ queryFactory: queryFactory,
+ isPrepared: preparedNoPreference,
+ err: nil,
+ }
+}
+
+func Delete(table interface{}) *DeleteDataset {
+ return newDeleteDataset("default", nil).From(table)
+}
+
+func (dd *DeleteDataset) Expression() exp.Expression {
+ return dd
+}
+
+// Clones the dataset
+func (dd *DeleteDataset) Clone() exp.Expression {
+ return dd.copy(dd.clauses)
+}
+
+// Set the parameter interpolation behavior. See examples
+//
+// prepared: If true the dataset WILL NOT interpolate the parameters.
+func (dd *DeleteDataset) Prepared(prepared bool) *DeleteDataset {
+ ret := dd.copy(dd.clauses)
+ ret.isPrepared = preparedFromBool(prepared)
+ return ret
+}
+
+// Returns true if Prepared(true) has been called on this dataset
+func (dd *DeleteDataset) IsPrepared() bool {
+ return dd.isPrepared.Bool()
+}
+
+// Sets the adapter used to serialize values and create the SQL statement
+func (dd *DeleteDataset) WithDialect(dl string) *DeleteDataset {
+ ds := dd.copy(dd.GetClauses())
+ ds.dialect = GetDialect(dl)
+ return ds
+}
+
+// Returns the current SQLDialect on the dataset
+func (dd *DeleteDataset) Dialect() SQLDialect {
+ return dd.dialect
+}
+
+// Set the dialect for this dataset.
+func (dd *DeleteDataset) SetDialect(dialect SQLDialect) *DeleteDataset {
+ cd := dd.copy(dd.GetClauses())
+ cd.dialect = dialect
+ return cd
+}
+
+// Returns the current clauses on the dataset.
+func (dd *DeleteDataset) GetClauses() exp.DeleteClauses {
+ return dd.clauses
+}
+
+// used interally to copy the dataset
+func (dd *DeleteDataset) copy(clauses exp.DeleteClauses) *DeleteDataset {
+ return &DeleteDataset{
+ dialect: dd.dialect,
+ clauses: clauses,
+ isPrepared: dd.isPrepared,
+ queryFactory: dd.queryFactory,
+ err: dd.err,
+ }
+}
+
+// Creates a WITH clause for a common table expression (CTE).
+//
+// The name will be available to SELECT from in the associated query; and can optionally
+// contain a list of column names "name(col1, col2, col3)".
+//
+// The name will refer to the results of the specified subquery.
+func (dd *DeleteDataset) With(name string, subquery exp.Expression) *DeleteDataset {
+ return dd.copy(dd.clauses.CommonTablesAppend(exp.NewCommonTableExpression(false, name, subquery)))
+}
+
+// Creates a WITH RECURSIVE clause for a common table expression (CTE)
+//
+// The name will be available to SELECT from in the associated query; and must
+// contain a list of column names "name(col1, col2, col3)" for a recursive clause.
+//
+// The name will refer to the results of the specified subquery. The subquery for
+// a recursive query will always end with a UNION or UNION ALL with a clause that
+// refers to the CTE by name.
+func (dd *DeleteDataset) WithRecursive(name string, subquery exp.Expression) *DeleteDataset {
+ return dd.copy(dd.clauses.CommonTablesAppend(exp.NewCommonTableExpression(true, name, subquery)))
+}
+
+// Adds a FROM clause. This return a new dataset with the original sources replaced. See examples.
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// Dataset: Will be added as a sub select. If the Dataset is not aliased it will automatically be aliased
+// LiteralExpression: (See Literal) Will use the literal SQL
+func (dd *DeleteDataset) From(table interface{}) *DeleteDataset {
+ switch t := table.(type) {
+ case exp.IdentifierExpression:
+ return dd.copy(dd.clauses.SetFrom(t))
+ case string:
+ return dd.copy(dd.clauses.SetFrom(exp.ParseIdentifier(t)))
+ default:
+ panic(ErrBadFromArgument)
+ }
+}
+
+// Adds a WHERE clause. See examples.
+func (dd *DeleteDataset) Where(expressions ...exp.Expression) *DeleteDataset {
+ return dd.copy(dd.clauses.WhereAppend(expressions...))
+}
+
+// Removes the WHERE clause. See examples.
+func (dd *DeleteDataset) ClearWhere() *DeleteDataset {
+ return dd.copy(dd.clauses.ClearWhere())
+}
+
+// Adds a ORDER clause. If the ORDER is currently set it replaces it. See examples.
+func (dd *DeleteDataset) Order(order ...exp.OrderedExpression) *DeleteDataset {
+ return dd.copy(dd.clauses.SetOrder(order...))
+}
+
+// Adds a more columns to the current ORDER BY clause. If no order has be previously specified it is the same as
+// calling Order. See examples.
+func (dd *DeleteDataset) OrderAppend(order ...exp.OrderedExpression) *DeleteDataset {
+ return dd.copy(dd.clauses.OrderAppend(order...))
+}
+
+// Adds a more columns to the beginning of the current ORDER BY clause. If no order has be previously specified it is the same as
+// calling Order. See examples.
+func (dd *DeleteDataset) OrderPrepend(order ...exp.OrderedExpression) *DeleteDataset {
+ return dd.copy(dd.clauses.OrderPrepend(order...))
+}
+
+// Removes the ORDER BY clause. See examples.
+func (dd *DeleteDataset) ClearOrder() *DeleteDataset {
+ return dd.copy(dd.clauses.ClearOrder())
+}
+
+// Adds a LIMIT clause. If the LIMIT is currently set it replaces it. See examples.
+func (dd *DeleteDataset) Limit(limit uint) *DeleteDataset {
+ if limit > 0 {
+ return dd.copy(dd.clauses.SetLimit(limit))
+ }
+ return dd.copy(dd.clauses.ClearLimit())
+}
+
+// Adds a LIMIT ALL clause. If the LIMIT is currently set it replaces it. See examples.
+func (dd *DeleteDataset) LimitAll() *DeleteDataset {
+ return dd.copy(dd.clauses.SetLimit(L("ALL")))
+}
+
+// Removes the LIMIT clause.
+func (dd *DeleteDataset) ClearLimit() *DeleteDataset {
+ return dd.copy(dd.clauses.ClearLimit())
+}
+
+// Adds a RETURNING clause to the dataset if the adapter supports it.
+func (dd *DeleteDataset) Returning(returning ...interface{}) *DeleteDataset {
+ return dd.copy(dd.clauses.SetReturning(exp.NewColumnListExpression(returning...)))
+}
+
+// Get any error that has been set or nil if no error has been set.
+func (dd *DeleteDataset) Error() error {
+ return dd.err
+}
+
+// Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
+// or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
+// track those separately.
+func (dd *DeleteDataset) SetError(err error) *DeleteDataset {
+ if dd.err == nil {
+ dd.err = err
+ }
+
+ return dd
+}
+
+// Generates a DELETE sql statement, if Prepared has been called with true then the parameters will not be interpolated.
+// See examples.
+//
+// Errors:
+// * There is an error generating the SQL
+func (dd *DeleteDataset) ToSQL() (sql string, params []interface{}, err error) {
+ return dd.deleteSQLBuilder().ToSQL()
+}
+
+// Appends this Dataset's DELETE statement to the SQLBuilder
+// This is used internally when using deletes in CTEs
+func (dd *DeleteDataset) AppendSQL(b sb.SQLBuilder) {
+ if dd.err != nil {
+ b.SetError(dd.err)
+ return
+ }
+ dd.dialect.ToDeleteSQL(b, dd.GetClauses())
+}
+
+func (dd *DeleteDataset) GetAs() exp.IdentifierExpression {
+ return nil
+}
+
+func (dd *DeleteDataset) ReturnsColumns() bool {
+ return dd.clauses.HasReturning()
+}
+
+// Creates an QueryExecutor to execute the query.
+// db.Delete("test").Exec()
+//
+// See Dataset#ToUpdateSQL for arguments
+func (dd *DeleteDataset) Executor() exec.QueryExecutor {
+ return dd.queryFactory.FromSQLBuilder(dd.deleteSQLBuilder())
+}
+
+func (dd *DeleteDataset) deleteSQLBuilder() sb.SQLBuilder {
+ buf := sb.NewSQLBuilder(dd.isPrepared.Bool())
+ if dd.err != nil {
+ return buf.SetError(dd.err)
+ }
+ dd.dialect.ToDeleteSQL(buf, dd.clauses)
+ return buf
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/dialect/mysql/mysql.go b/vendor/github.com/doug-martin/goqu/v9/dialect/mysql/mysql.go
new file mode 100644
index 000000000..d5566e493
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/dialect/mysql/mysql.go
@@ -0,0 +1,87 @@
+package mysql
+
+import (
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
+)
+
+func DialectOptions() *goqu.SQLDialectOptions {
+ opts := goqu.DefaultDialectOptions()
+
+ opts.SupportsReturn = false
+ opts.SupportsOrderByOnUpdate = true
+ opts.SupportsLimitOnUpdate = true
+ opts.SupportsLimitOnDelete = true
+ opts.SupportsOrderByOnDelete = true
+ opts.SupportsConflictUpdateWhere = false
+ opts.SupportsInsertIgnoreSyntax = true
+ opts.SupportsConflictTarget = false
+ opts.SupportsWithCTE = false
+ opts.SupportsWithCTERecursive = false
+ opts.SupportsDistinctOn = false
+ opts.SupportsWindowFunction = false
+ opts.SupportsDeleteTableHint = true
+
+ opts.UseFromClauseForMultipleUpdateTables = false
+
+ opts.PlaceHolderFragment = []byte("?")
+ opts.IncludePlaceholderNum = false
+ opts.QuoteRune = '`'
+ opts.DefaultValuesFragment = []byte("")
+ opts.True = []byte("1")
+ opts.False = []byte("0")
+ opts.TimeFormat = "2006-01-02 15:04:05"
+ opts.BooleanOperatorLookup = map[exp.BooleanOperation][]byte{
+ exp.EqOp: []byte("="),
+ exp.NeqOp: []byte("!="),
+ exp.GtOp: []byte(">"),
+ exp.GteOp: []byte(">="),
+ exp.LtOp: []byte("<"),
+ exp.LteOp: []byte("<="),
+ exp.InOp: []byte("IN"),
+ exp.NotInOp: []byte("NOT IN"),
+ exp.IsOp: []byte("IS"),
+ exp.IsNotOp: []byte("IS NOT"),
+ exp.LikeOp: []byte("LIKE BINARY"),
+ exp.NotLikeOp: []byte("NOT LIKE BINARY"),
+ exp.ILikeOp: []byte("LIKE"),
+ exp.NotILikeOp: []byte("NOT LIKE"),
+ exp.RegexpLikeOp: []byte("REGEXP BINARY"),
+ exp.RegexpNotLikeOp: []byte("NOT REGEXP BINARY"),
+ exp.RegexpILikeOp: []byte("REGEXP"),
+ exp.RegexpNotILikeOp: []byte("NOT REGEXP"),
+ }
+ opts.BitwiseOperatorLookup = map[exp.BitwiseOperation][]byte{
+ exp.BitwiseInversionOp: []byte("~"),
+ exp.BitwiseOrOp: []byte("|"),
+ exp.BitwiseAndOp: []byte("&"),
+ exp.BitwiseXorOp: []byte("^"),
+ exp.BitwiseLeftShiftOp: []byte("<<"),
+ exp.BitwiseRightShiftOp: []byte(">>"),
+ }
+ opts.EscapedRunes = map[rune][]byte{
+ '\'': []byte("\\'"),
+ '"': []byte("\\\""),
+ '\\': []byte("\\\\"),
+ '\n': []byte("\\n"),
+ '\r': []byte("\\r"),
+ 0: []byte("\\x00"),
+ 0x1a: []byte("\\x1a"),
+ }
+ opts.InsertIgnoreClause = []byte("INSERT IGNORE INTO")
+ opts.ConflictFragment = []byte("")
+ opts.ConflictDoUpdateFragment = []byte(" ON DUPLICATE KEY UPDATE ")
+ opts.ConflictDoNothingFragment = []byte("")
+ return opts
+}
+
+func DialectOptionsV8() *goqu.SQLDialectOptions {
+ opts := DialectOptions()
+ opts.SupportsWindowFunction = true
+ return opts
+}
+
+func init() {
+ goqu.RegisterDialect("mysql", DialectOptions())
+ goqu.RegisterDialect("mysql8", DialectOptionsV8())
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/dialect/postgres/postgres.go b/vendor/github.com/doug-martin/goqu/v9/dialect/postgres/postgres.go
new file mode 100644
index 000000000..b069f802c
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/dialect/postgres/postgres.go
@@ -0,0 +1,16 @@
+package postgres
+
+import (
+ "github.com/doug-martin/goqu/v9"
+)
+
+func DialectOptions() *goqu.SQLDialectOptions {
+ do := goqu.DefaultDialectOptions()
+ do.PlaceHolderFragment = []byte("$")
+ do.IncludePlaceholderNum = true
+ return do
+}
+
+func init() {
+ goqu.RegisterDialect("postgres", DialectOptions())
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/dialect/sqlite3/sqlite3.go b/vendor/github.com/doug-martin/goqu/v9/dialect/sqlite3/sqlite3.go
new file mode 100644
index 000000000..40ddb2a5d
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/dialect/sqlite3/sqlite3.go
@@ -0,0 +1,76 @@
+package sqlite3
+
+import (
+ "time"
+
+ "github.com/doug-martin/goqu/v9"
+ "github.com/doug-martin/goqu/v9/exp"
+)
+
+func DialectOptions() *goqu.SQLDialectOptions {
+ opts := goqu.DefaultDialectOptions()
+
+ opts.SupportsReturn = false
+ opts.SupportsOrderByOnUpdate = true
+ opts.SupportsLimitOnUpdate = true
+ opts.SupportsOrderByOnDelete = true
+ opts.SupportsLimitOnDelete = true
+ opts.SupportsConflictUpdateWhere = false
+ opts.SupportsInsertIgnoreSyntax = true
+ opts.SupportsConflictTarget = true
+ opts.SupportsMultipleUpdateTables = false
+ opts.WrapCompoundsInParens = false
+ opts.SupportsDistinctOn = false
+ opts.SupportsWindowFunction = false
+ opts.SupportsLateral = false
+
+ opts.PlaceHolderFragment = []byte("?")
+ opts.IncludePlaceholderNum = false
+ opts.QuoteRune = '`'
+ opts.DefaultValuesFragment = []byte("")
+ opts.True = []byte("1")
+ opts.False = []byte("0")
+ opts.TimeFormat = time.RFC3339Nano
+ opts.BooleanOperatorLookup = map[exp.BooleanOperation][]byte{
+ exp.EqOp: []byte("="),
+ exp.NeqOp: []byte("!="),
+ exp.GtOp: []byte(">"),
+ exp.GteOp: []byte(">="),
+ exp.LtOp: []byte("<"),
+ exp.LteOp: []byte("<="),
+ exp.InOp: []byte("IN"),
+ exp.NotInOp: []byte("NOT IN"),
+ exp.IsOp: []byte("IS"),
+ exp.IsNotOp: []byte("IS NOT"),
+ exp.LikeOp: []byte("LIKE"),
+ exp.NotLikeOp: []byte("NOT LIKE"),
+ exp.ILikeOp: []byte("LIKE"),
+ exp.NotILikeOp: []byte("NOT LIKE"),
+ exp.RegexpLikeOp: []byte("REGEXP"),
+ exp.RegexpNotLikeOp: []byte("NOT REGEXP"),
+ exp.RegexpILikeOp: []byte("REGEXP"),
+ exp.RegexpNotILikeOp: []byte("NOT REGEXP"),
+ }
+ opts.UseLiteralIsBools = false
+ opts.BitwiseOperatorLookup = map[exp.BitwiseOperation][]byte{
+ exp.BitwiseOrOp: []byte("|"),
+ exp.BitwiseAndOp: []byte("&"),
+ exp.BitwiseLeftShiftOp: []byte("<<"),
+ exp.BitwiseRightShiftOp: []byte(">>"),
+ }
+ opts.EscapedRunes = map[rune][]byte{
+ '\'': []byte("''"),
+ }
+ opts.InsertIgnoreClause = []byte("INSERT OR IGNORE INTO ")
+ opts.ConflictFragment = []byte(" ON CONFLICT ")
+ opts.ConflictDoUpdateFragment = []byte(" DO UPDATE SET ")
+ opts.ConflictDoNothingFragment = []byte(" DO NOTHING ")
+ opts.ForUpdateFragment = []byte("")
+ opts.OfFragment = []byte("")
+ opts.NowaitFragment = []byte("")
+ return opts
+}
+
+func init() {
+ goqu.RegisterDialect("sqlite3", DialectOptions())
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/docker-compose.yml b/vendor/github.com/doug-martin/goqu/v9/docker-compose.yml
new file mode 100644
index 000000000..3dd0c57dc
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/docker-compose.yml
@@ -0,0 +1,62 @@
+version: "2"
+
+services:
+ postgres:
+ image: "postgres:${POSTGRES_VERSION}"
+ environment:
+ - "POSTGRES_USER=postgres"
+ - "POSTGRES_DB=goqupostgres"
+ - "POSTGRES_HOST_AUTH_METHOD=trust"
+ expose:
+ - "5432"
+ ports:
+ - "5432:5432"
+
+ mysql:
+ image: "mysql:${MYSQL_VERSION}"
+ environment:
+ - "MYSQL_DATABASE=goqumysql"
+ - "MYSQL_ALLOW_EMPTY_PASSWORD=yes"
+ expose:
+ - "3306"
+ ports:
+ - "3306:3306"
+
+ sqlserver:
+ image: "mcr.microsoft.com/mssql/server:${SQLSERVER_VERSION}"
+ environment:
+ - "ACCEPT_EULA=Y"
+ - "SA_PASSWORD=qwe123QWE"
+ expose:
+ - "1433"
+ ports:
+ - "1433:1433"
+
+ goqu:
+ image: "golang:${GO_VERSION}"
+ command: ["./wait-for-it.sh", "postgres:5432", "--", "./wait-for-it.sh", "mysql:3306", "--", "go test -v -race ./..."]
+ working_dir: /go/src/github.com/doug-martin/goqu
+ volumes:
+ - "./:/go/src/github.com/doug-martin/goqu"
+ environment:
+ MYSQL_URI: 'root@tcp(mysql:3306)/goqumysql?parseTime=true'
+ PG_URI: 'postgres://postgres:@postgres:5432/goqupostgres?sslmode=disable'
+ SQLSERVER_URI: 'sqlserver://sa:qwe123QWE@sqlserver:1433?database=master&connection+timeout=30'
+ depends_on:
+ - postgres
+ - mysql
+ - sqlserver
+ goqu-coverage:
+ image: "golang:${GO_VERSION}"
+ command: ["./wait-for-it.sh", "postgres:5432", "--", "./wait-for-it.sh", "mysql:3306", "--", "./go.test.sh"]
+ working_dir: /go/src/github.com/doug-martin/goqu
+ volumes:
+ - "./:/go/src/github.com/doug-martin/goqu"
+ environment:
+ MYSQL_URI: 'root@tcp(mysql:3306)/goqumysql?parseTime=true'
+ PG_URI: 'postgres://postgres:@postgres:5432/goqupostgres?sslmode=disable'
+ SQLSERVER_URI: 'sqlserver://sa:qwe123QWE@sqlserver:1433?database=master&connection+timeout=30'
+ depends_on:
+ - postgres
+ - mysql
+ - sqlserver
diff --git a/vendor/github.com/doug-martin/goqu/v9/exec/query_executor.go b/vendor/github.com/doug-martin/goqu/v9/exec/query_executor.go
new file mode 100644
index 000000000..ce460dff2
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exec/query_executor.go
@@ -0,0 +1,247 @@
+package exec
+
+import (
+ "context"
+ gsql "database/sql"
+ "reflect"
+
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+type (
+ QueryExecutor struct {
+ de DbExecutor
+ err error
+ query string
+ args []interface{}
+ }
+)
+
+var (
+ errUnsupportedScanStructType = errors.New("type must be a pointer to a struct when scanning into a struct")
+ errUnsupportedScanStructsType = errors.New("type must be a pointer to a slice when scanning into structs")
+ errUnsupportedScanValsType = errors.New("type must be a pointer to a slice when scanning into vals")
+ errScanValPointer = errors.New("type must be a pointer when scanning into val")
+ errScanValNonSlice = errors.New("type cannot be a pointer to a slice when scanning into val")
+)
+
+func newQueryExecutor(de DbExecutor, err error, query string, args ...interface{}) QueryExecutor {
+ return QueryExecutor{de: de, err: err, query: query, args: args}
+}
+
+func (q QueryExecutor) ToSQL() (sql string, args []interface{}, err error) {
+ return q.query, q.args, q.err
+}
+
+func (q QueryExecutor) Exec() (gsql.Result, error) {
+ return q.ExecContext(context.Background())
+}
+
+func (q QueryExecutor) ExecContext(ctx context.Context) (gsql.Result, error) {
+ if q.err != nil {
+ return nil, q.err
+ }
+ return q.de.ExecContext(ctx, q.query, q.args...)
+}
+
+func (q QueryExecutor) Query() (*gsql.Rows, error) {
+ return q.QueryContext(context.Background())
+}
+
+func (q QueryExecutor) QueryContext(ctx context.Context) (*gsql.Rows, error) {
+ if q.err != nil {
+ return nil, q.err
+ }
+ return q.de.QueryContext(ctx, q.query, q.args...)
+}
+
+// This will execute the SQL and append results to the slice
+// var myStructs []MyStruct
+// if err := db.From("test").ScanStructs(&myStructs); err != nil{
+// panic(err.Error()
+// }
+// //use your structs
+//
+//
+// i: A pointer to a slice of structs.
+func (q QueryExecutor) ScanStructs(i interface{}) error {
+ return q.ScanStructsContext(context.Background(), i)
+}
+
+// This will execute the SQL and append results to the slice
+// var myStructs []MyStruct
+// if err := db.From("test").ScanStructsContext(ctx, &myStructs); err != nil{
+// panic(err.Error()
+// }
+// //use your structs
+//
+//
+// i: A pointer to a slice of structs.
+func (q QueryExecutor) ScanStructsContext(ctx context.Context, i interface{}) error {
+ scanner, err := q.ScannerContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer func() { _ = scanner.Close() }()
+ return scanner.ScanStructs(i)
+}
+
+// This will execute the SQL and fill out the struct with the fields returned.
+// This method returns a boolean value that is false if no record was found
+// var myStruct MyStruct
+// found, err := db.From("test").Limit(1).ScanStruct(&myStruct)
+// if err != nil{
+// panic(err.Error()
+// }
+// if !found{
+// fmt.Println("NOT FOUND")
+// }
+//
+// i: A pointer to a struct
+func (q QueryExecutor) ScanStruct(i interface{}) (bool, error) {
+ return q.ScanStructContext(context.Background(), i)
+}
+
+// This will execute the SQL and fill out the struct with the fields returned.
+// This method returns a boolean value that is false if no record was found
+// var myStruct MyStruct
+// found, err := db.From("test").Limit(1).ScanStructContext(ctx, &myStruct)
+// if err != nil{
+// panic(err.Error()
+// }
+// if !found{
+// fmt.Println("NOT FOUND")
+// }
+//
+// i: A pointer to a struct
+func (q QueryExecutor) ScanStructContext(ctx context.Context, i interface{}) (bool, error) {
+ val := reflect.ValueOf(i)
+ if !util.IsPointer(val.Kind()) {
+ return false, errUnsupportedScanStructType
+ }
+ val = reflect.Indirect(val)
+ if !util.IsStruct(val.Kind()) {
+ return false, errUnsupportedScanStructType
+ }
+
+ scanner, err := q.ScannerContext(ctx)
+ if err != nil {
+ return false, err
+ }
+
+ defer func() { _ = scanner.Close() }()
+
+ if scanner.Next() {
+ err = scanner.ScanStruct(i)
+ if err != nil {
+ return false, err
+ }
+
+ return true, scanner.Err()
+ }
+
+ return false, scanner.Err()
+}
+
+// This will execute the SQL and append results to the slice.
+// var ids []uint32
+// if err := db.From("test").Select("id").ScanVals(&ids); err != nil{
+// panic(err.Error()
+// }
+//
+// i: Takes a pointer to a slice of primitive values.
+func (q QueryExecutor) ScanVals(i interface{}) error {
+ return q.ScanValsContext(context.Background(), i)
+}
+
+// This will execute the SQL and append results to the slice.
+// var ids []uint32
+// if err := db.From("test").Select("id").ScanValsContext(ctx, &ids); err != nil{
+// panic(err.Error()
+// }
+//
+// i: Takes a pointer to a slice of primitive values.
+func (q QueryExecutor) ScanValsContext(ctx context.Context, i interface{}) error {
+ scanner, err := q.ScannerContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer func() { _ = scanner.Close() }()
+ return scanner.ScanVals(i)
+}
+
+// This will execute the SQL and set the value of the primitive. This method will return false if no record is found.
+// var id uint32
+// found, err := db.From("test").Select("id").Limit(1).ScanVal(&id)
+// if err != nil{
+// panic(err.Error()
+// }
+// if !found{
+// fmt.Println("NOT FOUND")
+// }
+//
+// i: Takes a pointer to a primitive value.
+func (q QueryExecutor) ScanVal(i interface{}) (bool, error) {
+ return q.ScanValContext(context.Background(), i)
+}
+
+// This will execute the SQL and set the value of the primitive. This method will return false if no record is found.
+// var id uint32
+// found, err := db.From("test").Select("id").Limit(1).ScanValContext(ctx, &id)
+// if err != nil{
+// panic(err.Error()
+// }
+// if !found{
+// fmt.Println("NOT FOUND")
+// }
+//
+// i: Takes a pointer to a primitive value.
+func (q QueryExecutor) ScanValContext(ctx context.Context, i interface{}) (bool, error) {
+ val := reflect.ValueOf(i)
+ if !util.IsPointer(val.Kind()) {
+ return false, errScanValPointer
+ }
+ val = reflect.Indirect(val)
+ if util.IsSlice(val.Kind()) {
+ switch i.(type) {
+ case *gsql.RawBytes: // do nothing
+ case *[]byte: // do nothing
+ case gsql.Scanner: // do nothing
+ default:
+ return false, errScanValNonSlice
+ }
+ }
+
+ scanner, err := q.ScannerContext(ctx)
+ if err != nil {
+ return false, err
+ }
+
+ defer func() { _ = scanner.Close() }()
+
+ if scanner.Next() {
+ err = scanner.ScanVal(i)
+ if err != nil {
+ return false, err
+ }
+
+ return true, scanner.Err()
+ }
+
+ return false, scanner.Err()
+}
+
+// Scanner will return a Scanner that can be used for manually scanning rows.
+func (q QueryExecutor) Scanner() (Scanner, error) {
+ return q.ScannerContext(context.Background())
+}
+
+// ScannerContext will return a Scanner that can be used for manually scanning rows.
+func (q QueryExecutor) ScannerContext(ctx context.Context) (Scanner, error) {
+ rows, err := q.QueryContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+ return NewScanner(rows), nil
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exec/query_factory.go b/vendor/github.com/doug-martin/goqu/v9/exec/query_factory.go
new file mode 100644
index 000000000..6ae517d6a
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exec/query_factory.go
@@ -0,0 +1,36 @@
+package exec
+
+import (
+ "context"
+ "database/sql"
+
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type (
+ // nolint:stylecheck // keep name for backwards compatibility
+ DbExecutor interface {
+ ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
+ QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
+ }
+ QueryFactory interface {
+ FromSQL(sql string, args ...interface{}) QueryExecutor
+ FromSQLBuilder(b sb.SQLBuilder) QueryExecutor
+ }
+ querySupport struct {
+ de DbExecutor
+ }
+)
+
+func NewQueryFactory(de DbExecutor) QueryFactory {
+ return &querySupport{de}
+}
+
+func (qs *querySupport) FromSQL(query string, args ...interface{}) QueryExecutor {
+ return newQueryExecutor(qs.de, nil, query, args...)
+}
+
+func (qs *querySupport) FromSQLBuilder(b sb.SQLBuilder) QueryExecutor {
+ query, args, err := b.ToSQL()
+ return newQueryExecutor(qs.de, err, query, args...)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exec/scanner.go b/vendor/github.com/doug-martin/goqu/v9/exec/scanner.go
new file mode 100644
index 000000000..c05411b9f
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exec/scanner.go
@@ -0,0 +1,168 @@
+package exec
+
+import (
+ "database/sql"
+ "reflect"
+
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+type (
+ // Scanner knows how to scan sql.Rows into structs.
+ Scanner interface {
+ Next() bool
+ ScanStruct(i interface{}) error
+ ScanStructs(i interface{}) error
+ ScanVal(i interface{}) error
+ ScanVals(i interface{}) error
+ Close() error
+ Err() error
+ }
+
+ scanner struct {
+ rows *sql.Rows
+ columnMap util.ColumnMap
+ columns []string
+ }
+)
+
+func unableToFindFieldError(col string) error {
+ return errors.New(`unable to find corresponding field to column "%s" returned by query`, col)
+}
+
+// NewScanner returns a scanner that can be used for scanning rows into structs.
+func NewScanner(rows *sql.Rows) Scanner {
+ return &scanner{rows: rows}
+}
+
+// Next prepares the next row for Scanning. See sql.Rows#Next for more
+// information.
+func (s *scanner) Next() bool {
+ return s.rows.Next()
+}
+
+// Err returns the error, if any that was encountered during iteration. See
+// sql.Rows#Err for more information.
+func (s *scanner) Err() error {
+ return s.rows.Err()
+}
+
+// ScanStruct will scan the current row into i.
+func (s *scanner) ScanStruct(i interface{}) error {
+ // Setup columnMap and columns, but only once.
+ if s.columnMap == nil || s.columns == nil {
+ cm, err := util.GetColumnMap(i)
+ if err != nil {
+ return err
+ }
+
+ cols, err := s.rows.Columns()
+ if err != nil {
+ return err
+ }
+
+ s.columnMap = cm
+ s.columns = cols
+ }
+
+ scans := make([]interface{}, 0, len(s.columns))
+ for _, col := range s.columns {
+ data, ok := s.columnMap[col]
+ switch {
+ case !ok:
+ return unableToFindFieldError(col)
+ default:
+ scans = append(scans, reflect.New(data.GoType).Interface())
+ }
+ }
+
+ if err := s.rows.Scan(scans...); err != nil {
+ return err
+ }
+
+ record := exp.Record{}
+ for index, col := range s.columns {
+ record[col] = scans[index]
+ }
+
+ util.AssignStructVals(i, record, s.columnMap)
+
+ return s.Err()
+}
+
+// ScanStructs scans results in slice of structs
+func (s *scanner) ScanStructs(i interface{}) error {
+ val, err := checkScanStructsTarget(i)
+ if err != nil {
+ return err
+ }
+ return s.scanIntoSlice(val, func(i interface{}) error {
+ return s.ScanStruct(i)
+ })
+}
+
+// ScanVal will scan the current row and column into i.
+func (s *scanner) ScanVal(i interface{}) error {
+ if err := s.rows.Scan(i); err != nil {
+ return err
+ }
+
+ return s.Err()
+}
+
+// ScanStructs scans results in slice of values
+func (s *scanner) ScanVals(i interface{}) error {
+ val, err := checkScanValsTarget(i)
+ if err != nil {
+ return err
+ }
+ return s.scanIntoSlice(val, func(i interface{}) error {
+ return s.ScanVal(i)
+ })
+}
+
+// Close closes the Rows, preventing further enumeration. See sql.Rows#Close
+// for more info.
+func (s *scanner) Close() error {
+ return s.rows.Close()
+}
+
+func (s *scanner) scanIntoSlice(val reflect.Value, it func(i interface{}) error) error {
+ elemType := util.GetSliceElementType(val)
+
+ for s.Next() {
+ row := reflect.New(elemType)
+ if rowErr := it(row.Interface()); rowErr != nil {
+ return rowErr
+ }
+ util.AppendSliceElement(val, row)
+ }
+
+ return s.Err()
+}
+
+func checkScanStructsTarget(i interface{}) (reflect.Value, error) {
+ val := reflect.ValueOf(i)
+ if !util.IsPointer(val.Kind()) {
+ return val, errUnsupportedScanStructsType
+ }
+ val = reflect.Indirect(val)
+ if !util.IsSlice(val.Kind()) {
+ return val, errUnsupportedScanStructsType
+ }
+ return val, nil
+}
+
+func checkScanValsTarget(i interface{}) (reflect.Value, error) {
+ val := reflect.ValueOf(i)
+ if !util.IsPointer(val.Kind()) {
+ return val, errUnsupportedScanValsType
+ }
+ val = reflect.Indirect(val)
+ if !util.IsSlice(val.Kind()) {
+ return val, errUnsupportedScanValsType
+ }
+ return val, nil
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/alias.go b/vendor/github.com/doug-martin/goqu/v9/exp/alias.go
new file mode 100644
index 000000000..2640627b8
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/alias.go
@@ -0,0 +1,59 @@
+package exp
+
+import "fmt"
+
+type (
+ aliasExpression struct {
+ aliased Expression
+ alias IdentifierExpression
+ }
+)
+
+// Creates a new AliasedExpression for the Expression and alias
+func NewAliasExpression(exp Expression, alias interface{}) AliasedExpression {
+ switch v := alias.(type) {
+ case string:
+ return aliasExpression{aliased: exp, alias: ParseIdentifier(v)}
+ case IdentifierExpression:
+ return aliasExpression{aliased: exp, alias: v}
+ default:
+ panic(fmt.Sprintf("Cannot create alias from %+v", v))
+ }
+}
+
+func (ae aliasExpression) Clone() Expression {
+ return NewAliasExpression(ae.aliased, ae.alias.Clone())
+}
+
+func (ae aliasExpression) Expression() Expression {
+ return ae
+}
+
+func (ae aliasExpression) Aliased() Expression {
+ return ae.aliased
+}
+
+func (ae aliasExpression) GetAs() IdentifierExpression {
+ return ae.alias
+}
+
+// Returns a new IdentifierExpression with the specified schema
+func (ae aliasExpression) Schema(schema string) IdentifierExpression {
+ return ae.alias.Schema(schema)
+}
+
+// Returns a new IdentifierExpression with the specified table
+func (ae aliasExpression) Table(table string) IdentifierExpression {
+ return ae.alias.Table(table)
+}
+
+// Returns a new IdentifierExpression with the specified column
+func (ae aliasExpression) Col(col interface{}) IdentifierExpression {
+ return ae.alias.Col(col)
+}
+
+// Returns a new IdentifierExpression with the column set to *
+// I("my_table").As("t").All() //"t".*
+func (ae aliasExpression) All() IdentifierExpression {
+ return ae.alias.All()
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/bitwise.go b/vendor/github.com/doug-martin/goqu/v9/exp/bitwise.go
new file mode 100644
index 000000000..eede5a2f9
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/bitwise.go
@@ -0,0 +1,89 @@
+package exp
+
+type bitwise struct {
+ lhs Expression
+ rhs interface{}
+ op BitwiseOperation
+}
+
+func NewBitwiseExpression(op BitwiseOperation, lhs Expression, rhs interface{}) BitwiseExpression {
+ return bitwise{op: op, lhs: lhs, rhs: rhs}
+}
+
+func (b bitwise) Clone() Expression {
+ return NewBitwiseExpression(b.op, b.lhs.Clone(), b.rhs)
+}
+
+func (b bitwise) RHS() interface{} {
+ return b.rhs
+}
+
+func (b bitwise) LHS() Expression {
+ return b.lhs
+}
+
+func (b bitwise) Op() BitwiseOperation {
+ return b.op
+}
+
+func (b bitwise) Expression() Expression { return b }
+func (b bitwise) As(val interface{}) AliasedExpression { return NewAliasExpression(b, val) }
+func (b bitwise) Eq(val interface{}) BooleanExpression { return eq(b, val) }
+func (b bitwise) Neq(val interface{}) BooleanExpression { return neq(b, val) }
+func (b bitwise) Gt(val interface{}) BooleanExpression { return gt(b, val) }
+func (b bitwise) Gte(val interface{}) BooleanExpression { return gte(b, val) }
+func (b bitwise) Lt(val interface{}) BooleanExpression { return lt(b, val) }
+func (b bitwise) Lte(val interface{}) BooleanExpression { return lte(b, val) }
+func (b bitwise) Asc() OrderedExpression { return asc(b) }
+func (b bitwise) Desc() OrderedExpression { return desc(b) }
+func (b bitwise) Like(i interface{}) BooleanExpression { return like(b, i) }
+func (b bitwise) NotLike(i interface{}) BooleanExpression { return notLike(b, i) }
+func (b bitwise) ILike(i interface{}) BooleanExpression { return iLike(b, i) }
+func (b bitwise) NotILike(i interface{}) BooleanExpression { return notILike(b, i) }
+func (b bitwise) RegexpLike(val interface{}) BooleanExpression { return regexpLike(b, val) }
+func (b bitwise) RegexpNotLike(val interface{}) BooleanExpression { return regexpNotLike(b, val) }
+func (b bitwise) RegexpILike(val interface{}) BooleanExpression { return regexpILike(b, val) }
+func (b bitwise) RegexpNotILike(val interface{}) BooleanExpression { return regexpNotILike(b, val) }
+func (b bitwise) In(i ...interface{}) BooleanExpression { return in(b, i...) }
+func (b bitwise) NotIn(i ...interface{}) BooleanExpression { return notIn(b, i...) }
+func (b bitwise) Is(i interface{}) BooleanExpression { return is(b, i) }
+func (b bitwise) IsNot(i interface{}) BooleanExpression { return isNot(b, i) }
+func (b bitwise) IsNull() BooleanExpression { return is(b, nil) }
+func (b bitwise) IsNotNull() BooleanExpression { return isNot(b, nil) }
+func (b bitwise) IsTrue() BooleanExpression { return is(b, true) }
+func (b bitwise) IsNotTrue() BooleanExpression { return isNot(b, true) }
+func (b bitwise) IsFalse() BooleanExpression { return is(b, false) }
+func (b bitwise) IsNotFalse() BooleanExpression { return isNot(b, false) }
+func (b bitwise) Distinct() SQLFunctionExpression { return NewSQLFunctionExpression("DISTINCT", b) }
+func (b bitwise) Between(val RangeVal) RangeExpression { return between(b, val) }
+func (b bitwise) NotBetween(val RangeVal) RangeExpression { return notBetween(b, val) }
+
+// used internally to create a Bitwise Inversion BitwiseExpression
+func bitwiseInversion(rhs Expression) BitwiseExpression {
+ return NewBitwiseExpression(BitwiseInversionOp, nil, rhs)
+}
+
+// used internally to create a Bitwise OR BitwiseExpression
+func bitwiseOr(lhs Expression, rhs interface{}) BitwiseExpression {
+ return NewBitwiseExpression(BitwiseOrOp, lhs, rhs)
+}
+
+// used internally to create a Bitwise AND BitwiseExpression
+func bitwiseAnd(lhs Expression, rhs interface{}) BitwiseExpression {
+ return NewBitwiseExpression(BitwiseAndOp, lhs, rhs)
+}
+
+// used internally to create a Bitwise XOR BitwiseExpression
+func bitwiseXor(lhs Expression, rhs interface{}) BitwiseExpression {
+ return NewBitwiseExpression(BitwiseXorOp, lhs, rhs)
+}
+
+// used internally to create a Bitwise LEFT SHIFT BitwiseExpression
+func bitwiseLeftShift(lhs Expression, rhs interface{}) BitwiseExpression {
+ return NewBitwiseExpression(BitwiseLeftShiftOp, lhs, rhs)
+}
+
+// used internally to create a Bitwise RIGHT SHIFT BitwiseExpression
+func bitwiseRightShift(lhs Expression, rhs interface{}) BitwiseExpression {
+ return NewBitwiseExpression(BitwiseRightShiftOp, lhs, rhs)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/bool.go b/vendor/github.com/doug-martin/goqu/v9/exp/bool.go
new file mode 100644
index 000000000..a38f356ff
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/bool.go
@@ -0,0 +1,185 @@
+package exp
+
+import (
+ "reflect"
+ "regexp"
+)
+
+type boolean struct {
+ lhs Expression
+ rhs interface{}
+ op BooleanOperation
+}
+
+func NewBooleanExpression(op BooleanOperation, lhs Expression, rhs interface{}) BooleanExpression {
+ return boolean{op: op, lhs: lhs, rhs: rhs}
+}
+
+func (b boolean) Clone() Expression {
+ return NewBooleanExpression(b.op, b.lhs.Clone(), b.rhs)
+}
+
+func (b boolean) Expression() Expression {
+ return b
+}
+
+func (b boolean) RHS() interface{} {
+ return b.rhs
+}
+
+func (b boolean) LHS() Expression {
+ return b.lhs
+}
+
+func (b boolean) Op() BooleanOperation {
+ return b.op
+}
+
+func (b boolean) As(val interface{}) AliasedExpression {
+ return NewAliasExpression(b, val)
+}
+
+// used internally to create an equality BooleanExpression
+func eq(lhs Expression, rhs interface{}) BooleanExpression {
+ return checkBoolExpType(EqOp, lhs, rhs, false)
+}
+
+// used internally to create an in-equality BooleanExpression
+func neq(lhs Expression, rhs interface{}) BooleanExpression {
+ return checkBoolExpType(EqOp, lhs, rhs, true)
+}
+
+// used internally to create an gt comparison BooleanExpression
+func gt(lhs Expression, rhs interface{}) BooleanExpression {
+ return NewBooleanExpression(GtOp, lhs, rhs)
+}
+
+// used internally to create an gte comparison BooleanExpression
+func gte(lhs Expression, rhs interface{}) BooleanExpression {
+ return NewBooleanExpression(GteOp, lhs, rhs)
+}
+
+// used internally to create an lt comparison BooleanExpression
+func lt(lhs Expression, rhs interface{}) BooleanExpression {
+ return NewBooleanExpression(LtOp, lhs, rhs)
+}
+
+// used internally to create an lte comparison BooleanExpression
+func lte(lhs Expression, rhs interface{}) BooleanExpression {
+ return NewBooleanExpression(LteOp, lhs, rhs)
+}
+
+// used internally to create an IN BooleanExpression
+func in(lhs Expression, vals ...interface{}) BooleanExpression {
+ if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
+ return NewBooleanExpression(InOp, lhs, vals[0])
+ }
+ return NewBooleanExpression(InOp, lhs, vals)
+}
+
+// used internally to create a NOT IN BooleanExpression
+func notIn(lhs Expression, vals ...interface{}) BooleanExpression {
+ if len(vals) == 1 && reflect.Indirect(reflect.ValueOf(vals[0])).Kind() == reflect.Slice {
+ return NewBooleanExpression(NotInOp, lhs, vals[0])
+ }
+ return NewBooleanExpression(NotInOp, lhs, vals)
+}
+
+// used internally to create an IS BooleanExpression
+func is(lhs Expression, val interface{}) BooleanExpression {
+ return checkBoolExpType(IsOp, lhs, val, false)
+}
+
+// used internally to create an IS NOT BooleanExpression
+func isNot(lhs Expression, val interface{}) BooleanExpression {
+ return checkBoolExpType(IsOp, lhs, val, true)
+}
+
+// used internally to create a LIKE BooleanExpression
+func like(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(LikeOp, lhs, val, false)
+}
+
+// used internally to create an ILIKE BooleanExpression
+func iLike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(ILikeOp, lhs, val, false)
+}
+
+// used internally to create a NOT LIKE BooleanExpression
+func notLike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(LikeOp, lhs, val, true)
+}
+
+// used internally to create a NOT ILIKE BooleanExpression
+func notILike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(ILikeOp, lhs, val, true)
+}
+
+// used internally to create a LIKE BooleanExpression
+func regexpLike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(RegexpLikeOp, lhs, val, false)
+}
+
+// used internally to create an ILIKE BooleanExpression
+func regexpILike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(RegexpILikeOp, lhs, val, false)
+}
+
+// used internally to create a NOT LIKE BooleanExpression
+func regexpNotLike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(RegexpLikeOp, lhs, val, true)
+}
+
+// used internally to create a NOT ILIKE BooleanExpression
+func regexpNotILike(lhs Expression, val interface{}) BooleanExpression {
+ return checkLikeExp(RegexpILikeOp, lhs, val, true)
+}
+
+// checks an like rhs to create the proper like expression for strings or regexps
+func checkLikeExp(op BooleanOperation, lhs Expression, val interface{}, invert bool) BooleanExpression {
+ rhs := val
+
+ if t, ok := val.(*regexp.Regexp); ok {
+ if op == LikeOp {
+ op = RegexpLikeOp
+ } else if op == ILikeOp {
+ op = RegexpILikeOp
+ }
+ rhs = t.String()
+ }
+ if invert {
+ op = operatorInversions[op]
+ }
+ return NewBooleanExpression(op, lhs, rhs)
+}
+
+// checks a boolean operation normalizing the operation based on the RHS (e.g. "a" = true vs "a" IS TRUE
+func checkBoolExpType(op BooleanOperation, lhs Expression, rhs interface{}, invert bool) BooleanExpression {
+ if rhs == nil {
+ op = IsOp
+ } else {
+ switch reflect.Indirect(reflect.ValueOf(rhs)).Kind() {
+ case reflect.Bool:
+ op = IsOp
+ case reflect.Slice:
+ // if its a slice of bytes dont treat as an IN
+ if _, ok := rhs.([]byte); !ok {
+ op = InOp
+ }
+ case reflect.Struct:
+ switch rhs.(type) {
+ case SQLExpression:
+ op = InOp
+ case AppendableExpression:
+ op = InOp
+ case *regexp.Regexp:
+ return checkLikeExp(LikeOp, lhs, rhs, invert)
+ }
+ default:
+ }
+ }
+ if invert {
+ op = operatorInversions[op]
+ }
+ return NewBooleanExpression(op, lhs, rhs)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/case.go b/vendor/github.com/doug-martin/goqu/v9/exp/case.go
new file mode 100644
index 000000000..d20800a38
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/case.go
@@ -0,0 +1,78 @@
+package exp
+
+type (
+ caseElse struct {
+ result interface{}
+ }
+ caseWhen struct {
+ caseElse
+ condition interface{}
+ }
+ caseExpression struct {
+ value interface{}
+ whens []CaseWhen
+ elseCondition CaseElse
+ }
+)
+
+func NewCaseElse(result interface{}) CaseElse {
+ return caseElse{result: result}
+}
+
+func (ce caseElse) Result() interface{} {
+ return ce.result
+}
+
+func NewCaseWhen(condition, result interface{}) CaseWhen {
+ return caseWhen{caseElse: caseElse{result: result}, condition: condition}
+}
+
+func (cw caseWhen) Condition() interface{} {
+ return cw.condition
+}
+
+func NewCaseExpression() CaseExpression {
+ return caseExpression{value: nil, whens: []CaseWhen{}, elseCondition: nil}
+}
+
+func (c caseExpression) Expression() Expression {
+ return c
+}
+
+func (c caseExpression) Clone() Expression {
+ return caseExpression{value: c.value, whens: c.whens, elseCondition: c.elseCondition}
+}
+
+func (c caseExpression) As(alias interface{}) AliasedExpression {
+ return NewAliasExpression(c, alias)
+}
+
+func (c caseExpression) GetValue() interface{} {
+ return c.value
+}
+
+func (c caseExpression) GetWhens() []CaseWhen {
+ return c.whens
+}
+
+func (c caseExpression) GetElse() CaseElse {
+ return c.elseCondition
+}
+
+func (c caseExpression) Value(value interface{}) CaseExpression {
+ c.value = value
+ return c
+}
+
+func (c caseExpression) When(condition, result interface{}) CaseExpression {
+ c.whens = append(c.whens, NewCaseWhen(condition, result))
+ return c
+}
+
+func (c caseExpression) Else(result interface{}) CaseExpression {
+ c.elseCondition = NewCaseElse(result)
+ return c
+}
+
+func (c caseExpression) Asc() OrderedExpression { return asc(c) }
+func (c caseExpression) Desc() OrderedExpression { return desc(c) }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/cast.go b/vendor/github.com/doug-martin/goqu/v9/exp/cast.go
new file mode 100644
index 000000000..d881e26b2
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/cast.go
@@ -0,0 +1,56 @@
+package exp
+
+type cast struct {
+ casted Expression
+ t LiteralExpression
+}
+
+// Creates a new Casted expression
+// Cast(I("a"), "NUMERIC") -> CAST("a" AS NUMERIC)
+func NewCastExpression(e Expression, t string) CastExpression {
+ return cast{casted: e, t: NewLiteralExpression(t)}
+}
+
+func (c cast) Casted() Expression {
+ return c.casted
+}
+
+func (c cast) Type() LiteralExpression {
+ return c.t
+}
+
+func (c cast) Clone() Expression {
+ return cast{casted: c.casted.Clone(), t: c.t}
+}
+
+func (c cast) Expression() Expression { return c }
+func (c cast) As(val interface{}) AliasedExpression { return NewAliasExpression(c, val) }
+func (c cast) Eq(val interface{}) BooleanExpression { return eq(c, val) }
+func (c cast) Neq(val interface{}) BooleanExpression { return neq(c, val) }
+func (c cast) Gt(val interface{}) BooleanExpression { return gt(c, val) }
+func (c cast) Gte(val interface{}) BooleanExpression { return gte(c, val) }
+func (c cast) Lt(val interface{}) BooleanExpression { return lt(c, val) }
+func (c cast) Lte(val interface{}) BooleanExpression { return lte(c, val) }
+func (c cast) Asc() OrderedExpression { return asc(c) }
+func (c cast) Desc() OrderedExpression { return desc(c) }
+func (c cast) Like(i interface{}) BooleanExpression { return like(c, i) }
+func (c cast) NotLike(i interface{}) BooleanExpression { return notLike(c, i) }
+func (c cast) ILike(i interface{}) BooleanExpression { return iLike(c, i) }
+func (c cast) NotILike(i interface{}) BooleanExpression { return notILike(c, i) }
+func (c cast) RegexpLike(val interface{}) BooleanExpression { return regexpLike(c, val) }
+func (c cast) RegexpNotLike(val interface{}) BooleanExpression { return regexpNotLike(c, val) }
+func (c cast) RegexpILike(val interface{}) BooleanExpression { return regexpILike(c, val) }
+func (c cast) RegexpNotILike(val interface{}) BooleanExpression { return regexpNotILike(c, val) }
+func (c cast) In(i ...interface{}) BooleanExpression { return in(c, i...) }
+func (c cast) NotIn(i ...interface{}) BooleanExpression { return notIn(c, i...) }
+func (c cast) Is(i interface{}) BooleanExpression { return is(c, i) }
+func (c cast) IsNot(i interface{}) BooleanExpression { return isNot(c, i) }
+func (c cast) IsNull() BooleanExpression { return is(c, nil) }
+func (c cast) IsNotNull() BooleanExpression { return isNot(c, nil) }
+func (c cast) IsTrue() BooleanExpression { return is(c, true) }
+func (c cast) IsNotTrue() BooleanExpression { return isNot(c, true) }
+func (c cast) IsFalse() BooleanExpression { return is(c, false) }
+func (c cast) IsNotFalse() BooleanExpression { return isNot(c, false) }
+func (c cast) Distinct() SQLFunctionExpression { return NewSQLFunctionExpression("DISTINCT", c) }
+func (c cast) Between(val RangeVal) RangeExpression { return between(c, val) }
+func (c cast) NotBetween(val RangeVal) RangeExpression { return notBetween(c, val) }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/col.go b/vendor/github.com/doug-martin/goqu/v9/exp/col.go
new file mode 100644
index 000000000..042969177
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/col.go
@@ -0,0 +1,84 @@
+package exp
+
+import (
+ "fmt"
+ "reflect"
+
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+type columnList struct {
+ columns []Expression
+}
+
+func NewColumnListExpression(vals ...interface{}) ColumnListExpression {
+ cols := []Expression{}
+ for _, val := range vals {
+ switch t := val.(type) {
+ case nil: // do nothing
+ case string:
+ cols = append(cols, ParseIdentifier(t))
+ case ColumnListExpression:
+ cols = append(cols, t.Columns()...)
+ case Expression:
+ cols = append(cols, t)
+ default:
+ _, valKind := util.GetTypeInfo(val, reflect.Indirect(reflect.ValueOf(val)))
+
+ if valKind == reflect.Struct {
+ cm, err := util.GetColumnMap(val)
+ if err != nil {
+ panic(err.Error())
+ }
+ structCols := cm.Cols()
+ for _, col := range structCols {
+ i := ParseIdentifier(col)
+ var sc Expression = i
+ if i.IsQualified() {
+ sc = i.As(NewIdentifierExpression("", "", col))
+ }
+ cols = append(cols, sc)
+ }
+ } else {
+ panic(fmt.Sprintf("Cannot created expression from %+v", val))
+ }
+ }
+ }
+ return columnList{columns: cols}
+}
+
+func NewOrderedColumnList(vals ...OrderedExpression) ColumnListExpression {
+ exps := make([]interface{}, 0, len(vals))
+ for _, col := range vals {
+ exps = append(exps, col.Expression())
+ }
+ return NewColumnListExpression(exps...)
+}
+
+func (cl columnList) Clone() Expression {
+ newExps := make([]Expression, 0, len(cl.columns))
+ for _, exp := range cl.columns {
+ newExps = append(newExps, exp.Clone())
+ }
+ return columnList{columns: newExps}
+}
+
+func (cl columnList) Expression() Expression {
+ return cl
+}
+
+func (cl columnList) IsEmpty() bool {
+ return len(cl.columns) == 0
+}
+
+func (cl columnList) Columns() []Expression {
+ return cl.columns
+}
+
+func (cl columnList) Append(cols ...Expression) ColumnListExpression {
+ ret := columnList{}
+ exps := append(ret.columns, cl.columns...)
+ exps = append(exps, cols...)
+ ret.columns = exps
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/compound.go b/vendor/github.com/doug-martin/goqu/v9/exp/compound.go
new file mode 100644
index 000000000..d631991f0
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/compound.go
@@ -0,0 +1,19 @@
+package exp
+
+type compound struct {
+ t CompoundType
+ rhs AppendableExpression
+}
+
+func NewCompoundExpression(ct CompoundType, rhs AppendableExpression) CompoundExpression {
+ return compound{t: ct, rhs: rhs}
+}
+
+func (c compound) Expression() Expression { return c }
+
+func (c compound) Clone() Expression {
+ return compound{t: c.t, rhs: c.rhs.Clone().(AppendableExpression)}
+}
+
+func (c compound) Type() CompoundType { return c.t }
+func (c compound) RHS() AppendableExpression { return c.rhs }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/conflict.go b/vendor/github.com/doug-martin/goqu/v9/exp/conflict.go
new file mode 100644
index 000000000..4c7c5ead0
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/conflict.go
@@ -0,0 +1,86 @@
+package exp
+
+type (
+ doNothingConflict struct{}
+ // ConflictUpdate is the struct that represents the UPDATE fragment of an
+ // INSERT ... ON CONFLICT/ON DUPLICATE KEY DO UPDATE statement
+ conflictUpdate struct {
+ target string
+ update interface{}
+ whereClause ExpressionList
+ }
+)
+
+// Creates a conflict struct to be passed to InsertConflict to ignore constraint errors
+// InsertConflict(DoNothing(),...) -> INSERT INTO ... ON CONFLICT DO NOTHING
+func NewDoNothingConflictExpression() ConflictExpression {
+ return &doNothingConflict{}
+}
+
+func (c doNothingConflict) Expression() Expression {
+ return c
+}
+
+func (c doNothingConflict) Clone() Expression {
+ return c
+}
+
+func (c doNothingConflict) Action() ConflictAction {
+ return DoNothingConflictAction
+}
+
+// Creates a ConflictUpdate struct to be passed to InsertConflict
+// Represents a ON CONFLICT DO UPDATE portion of an INSERT statement (ON DUPLICATE KEY UPDATE for mysql)
+//
+// InsertConflict(DoUpdate("target_column", update),...) ->
+// INSERT INTO ... ON CONFLICT DO UPDATE SET a=b
+// InsertConflict(DoUpdate("target_column", update).Where(Ex{"a": 1},...) ->
+// INSERT INTO ... ON CONFLICT DO UPDATE SET a=b WHERE a=1
+func NewDoUpdateConflictExpression(target string, update interface{}) ConflictUpdateExpression {
+ return &conflictUpdate{target: target, update: update}
+}
+
+func (c conflictUpdate) Expression() Expression {
+ return c
+}
+
+func (c conflictUpdate) Clone() Expression {
+ return &conflictUpdate{
+ target: c.target,
+ update: c.update,
+ whereClause: c.whereClause.Clone().(ExpressionList),
+ }
+}
+
+func (c conflictUpdate) Action() ConflictAction {
+ return DoUpdateConflictAction
+}
+
+// Returns the target conflict column. Only necessary for Postgres.
+// Will return an error for mysql/sqlite. Will also return an error if missing from a postgres ConflictUpdate.
+func (c conflictUpdate) TargetColumn() string {
+ return c.target
+}
+
+// Returns the Updates which represent the ON CONFLICT DO UPDATE portion of an insert statement. If nil,
+// there are no updates.
+func (c conflictUpdate) Update() interface{} {
+ return c.update
+}
+
+// Append to the existing Where clause for an ON CONFLICT DO UPDATE ... WHERE ...
+// InsertConflict(DoNothing(),...) -> INSERT INTO ... ON CONFLICT DO NOTHING
+func (c *conflictUpdate) Where(expressions ...Expression) ConflictUpdateExpression {
+ if c.whereClause == nil {
+ c.whereClause = NewExpressionList(AndType, expressions...)
+ } else {
+ c.whereClause = c.whereClause.Append(expressions...)
+ }
+ return c
+}
+
+// Append to the existing Where clause for an ON CONFLICT DO UPDATE ... WHERE ...
+// InsertConflict(DoNothing(),...) -> INSERT INTO ... ON CONFLICT DO NOTHING
+func (c *conflictUpdate) WhereClause() ExpressionList {
+ return c.whereClause
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/cte.go b/vendor/github.com/doug-martin/goqu/v9/exp/cte.go
new file mode 100644
index 000000000..4282d0b6b
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/cte.go
@@ -0,0 +1,23 @@
+package exp
+
+type commonExpr struct {
+ recursive bool
+ name LiteralExpression
+ subQuery Expression
+}
+
+// Creates a new WITH common table expression for a SQLExpression, typically Datasets'. This function is used
+// internally by Dataset when a CTE is added to another Dataset
+func NewCommonTableExpression(recursive bool, name string, subQuery Expression) CommonTableExpression {
+ return commonExpr{recursive: recursive, name: NewLiteralExpression(name), subQuery: subQuery}
+}
+
+func (ce commonExpr) Expression() Expression { return ce }
+
+func (ce commonExpr) Clone() Expression {
+ return commonExpr{recursive: ce.recursive, name: ce.name, subQuery: ce.subQuery.Clone().(SQLExpression)}
+}
+
+func (ce commonExpr) IsRecursive() bool { return ce.recursive }
+func (ce commonExpr) Name() LiteralExpression { return ce.name }
+func (ce commonExpr) SubQuery() Expression { return ce.subQuery }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/delete_clauses.go b/vendor/github.com/doug-martin/goqu/v9/exp/delete_clauses.go
new file mode 100644
index 000000000..25af851f3
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/delete_clauses.go
@@ -0,0 +1,177 @@
+package exp
+
+type (
+ DeleteClauses interface {
+ HasFrom() bool
+ clone() *deleteClauses
+
+ CommonTables() []CommonTableExpression
+ CommonTablesAppend(cte CommonTableExpression) DeleteClauses
+
+ From() IdentifierExpression
+ SetFrom(table IdentifierExpression) DeleteClauses
+
+ Where() ExpressionList
+ ClearWhere() DeleteClauses
+ WhereAppend(expressions ...Expression) DeleteClauses
+
+ Order() ColumnListExpression
+ HasOrder() bool
+ ClearOrder() DeleteClauses
+ SetOrder(oes ...OrderedExpression) DeleteClauses
+ OrderAppend(...OrderedExpression) DeleteClauses
+ OrderPrepend(...OrderedExpression) DeleteClauses
+
+ Limit() interface{}
+ HasLimit() bool
+ ClearLimit() DeleteClauses
+ SetLimit(limit interface{}) DeleteClauses
+
+ Returning() ColumnListExpression
+ HasReturning() bool
+ SetReturning(cl ColumnListExpression) DeleteClauses
+ }
+ deleteClauses struct {
+ commonTables []CommonTableExpression
+ from IdentifierExpression
+ where ExpressionList
+ order ColumnListExpression
+ limit interface{}
+ returning ColumnListExpression
+ }
+)
+
+func NewDeleteClauses() DeleteClauses {
+ return &deleteClauses{}
+}
+
+func (dc *deleteClauses) HasFrom() bool {
+ return dc.from != nil
+}
+
+func (dc *deleteClauses) clone() *deleteClauses {
+ return &deleteClauses{
+ commonTables: dc.commonTables,
+ from: dc.from,
+
+ where: dc.where,
+ order: dc.order,
+ limit: dc.limit,
+ returning: dc.returning,
+ }
+}
+
+func (dc *deleteClauses) CommonTables() []CommonTableExpression {
+ return dc.commonTables
+}
+
+func (dc *deleteClauses) CommonTablesAppend(cte CommonTableExpression) DeleteClauses {
+ ret := dc.clone()
+ ret.commonTables = append(ret.commonTables, cte)
+ return ret
+}
+
+func (dc *deleteClauses) From() IdentifierExpression {
+ return dc.from
+}
+
+func (dc *deleteClauses) SetFrom(table IdentifierExpression) DeleteClauses {
+ ret := dc.clone()
+ ret.from = table
+ return ret
+}
+
+func (dc *deleteClauses) Where() ExpressionList {
+ return dc.where
+}
+
+func (dc *deleteClauses) ClearWhere() DeleteClauses {
+ ret := dc.clone()
+ ret.where = nil
+ return ret
+}
+
+func (dc *deleteClauses) WhereAppend(expressions ...Expression) DeleteClauses {
+ if len(expressions) == 0 {
+ return dc
+ }
+ ret := dc.clone()
+ if ret.where == nil {
+ ret.where = NewExpressionList(AndType, expressions...)
+ } else {
+ ret.where = ret.where.Append(expressions...)
+ }
+ return ret
+}
+
+func (dc *deleteClauses) Order() ColumnListExpression {
+ return dc.order
+}
+
+func (dc *deleteClauses) HasOrder() bool {
+ return dc.order != nil
+}
+
+func (dc *deleteClauses) ClearOrder() DeleteClauses {
+ ret := dc.clone()
+ ret.order = nil
+ return ret
+}
+
+func (dc *deleteClauses) SetOrder(oes ...OrderedExpression) DeleteClauses {
+ ret := dc.clone()
+ ret.order = NewOrderedColumnList(oes...)
+ return ret
+}
+
+func (dc *deleteClauses) OrderAppend(oes ...OrderedExpression) DeleteClauses {
+ if dc.order == nil {
+ return dc.SetOrder(oes...)
+ }
+ ret := dc.clone()
+ ret.order = ret.order.Append(NewOrderedColumnList(oes...).Columns()...)
+ return ret
+}
+
+func (dc *deleteClauses) OrderPrepend(oes ...OrderedExpression) DeleteClauses {
+ if dc.order == nil {
+ return dc.SetOrder(oes...)
+ }
+ ret := dc.clone()
+ ret.order = NewOrderedColumnList(oes...).Append(ret.order.Columns()...)
+ return ret
+}
+
+func (dc *deleteClauses) Limit() interface{} {
+ return dc.limit
+}
+
+func (dc *deleteClauses) HasLimit() bool {
+ return dc.limit != nil
+}
+
+func (dc *deleteClauses) ClearLimit() DeleteClauses {
+ ret := dc.clone()
+ ret.limit = nil
+ return ret
+}
+
+func (dc *deleteClauses) SetLimit(limit interface{}) DeleteClauses {
+ ret := dc.clone()
+ ret.limit = limit
+ return ret
+}
+
+func (dc *deleteClauses) Returning() ColumnListExpression {
+ return dc.returning
+}
+
+func (dc *deleteClauses) HasReturning() bool {
+ return dc.returning != nil && !dc.returning.IsEmpty()
+}
+
+func (dc *deleteClauses) SetReturning(cl ColumnListExpression) DeleteClauses {
+ ret := dc.clone()
+ ret.returning = cl
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/exp.go b/vendor/github.com/doug-martin/goqu/v9/exp/exp.go
new file mode 100644
index 000000000..240a96a62
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/exp.go
@@ -0,0 +1,734 @@
+package exp
+
+import (
+ "fmt"
+
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+// Behaviors
+type (
+
+ // Interface that an expression should implement if it can be aliased.
+ Aliaseable interface {
+ // Returns an AliasedExpression
+ // I("col").As("other_col") //"col" AS "other_col"
+ // I("col").As(I("other_col")) //"col" AS "other_col"
+ As(interface{}) AliasedExpression
+ }
+
+ // Interface that an expression should implement if it can be casted to another SQL type .
+ Castable interface {
+ // Casts an expression to the specified type
+ // I("a").Cast("numeric")//CAST("a" AS numeric)
+ Cast(val string) CastExpression
+ }
+
+ Inable interface {
+ // Creates a Boolean expression for IN clauses
+ // I("col").In([]string{"a", "b", "c"}) //("col" IN ('a', 'b', 'c'))
+ In(...interface{}) BooleanExpression
+ // Creates a Boolean expression for NOT IN clauses
+ // I("col").NotIn([]string{"a", "b", "c"}) //("col" NOT IN ('a', 'b', 'c'))
+ NotIn(...interface{}) BooleanExpression
+ }
+
+ Isable interface {
+ // Creates an Boolean expression IS clauses
+ // ds.Where(I("a").Is(nil)) //("a" IS NULL)
+ // ds.Where(I("a").Is(true)) //("a" IS TRUE)
+ // ds.Where(I("a").Is(false)) //("a" IS FALSE)
+ Is(interface{}) BooleanExpression
+ // Creates an Boolean expression IS NOT clauses
+ // ds.Where(I("a").IsNot(nil)) //("a" IS NOT NULL)
+ // ds.Where(I("a").IsNot(true)) //("a" IS NOT TRUE)
+ // ds.Where(I("a").IsNot(false)) //("a" IS NOT FALSE)
+ IsNot(interface{}) BooleanExpression
+ // Shortcut for Is(nil)
+ IsNull() BooleanExpression
+ // Shortcut for IsNot(nil)
+ IsNotNull() BooleanExpression
+ // Shortcut for Is(true)
+ IsTrue() BooleanExpression
+ // Shortcut for IsNot(true)
+ IsNotTrue() BooleanExpression
+ // Shortcut for Is(false)
+ IsFalse() BooleanExpression
+ // Shortcut for IsNot(false)
+ IsNotFalse() BooleanExpression
+ }
+
+ Likeable interface {
+ // Creates an Boolean expression for LIKE clauses
+ // ds.Where(I("a").Like("a%")) //("a" LIKE 'a%')
+ Like(interface{}) BooleanExpression
+ // Creates an Boolean expression for NOT LIKE clauses
+ // ds.Where(I("a").NotLike("a%")) //("a" NOT LIKE 'a%')
+ NotLike(interface{}) BooleanExpression
+ // Creates an Boolean expression for case insensitive LIKE clauses
+ // ds.Where(I("a").ILike("a%")) //("a" ILIKE 'a%')
+ ILike(interface{}) BooleanExpression
+ // Creates an Boolean expression for case insensitive NOT LIKE clauses
+ // ds.Where(I("a").NotILike("a%")) //("a" NOT ILIKE 'a%')
+ NotILike(interface{}) BooleanExpression
+
+ // Creates an Boolean expression for REGEXP LIKE clauses
+ // ds.Where(I("a").RegexpLike("a%")) //("a" ~ 'a%')
+ RegexpLike(interface{}) BooleanExpression
+ // Creates an Boolean expression for REGEXP NOT LIKE clauses
+ // ds.Where(I("a").RegexpNotLike("a%")) //("a" !~ 'a%')
+ RegexpNotLike(interface{}) BooleanExpression
+ // Creates an Boolean expression for case insensitive REGEXP ILIKE clauses
+ // ds.Where(I("a").RegexpILike("a%")) //("a" ~* 'a%')
+ RegexpILike(interface{}) BooleanExpression
+ // Creates an Boolean expression for case insensitive REGEXP NOT ILIKE clauses
+ // ds.Where(I("a").RegexpNotILike("a%")) //("a" !~* 'a%')
+ RegexpNotILike(interface{}) BooleanExpression
+ }
+
+ // Interface that an expression should implement if it can be compared with other values.
+ Comparable interface {
+ // Creates a Boolean expression comparing equality
+ // I("col").Eq(1) //("col" = 1)
+ Eq(interface{}) BooleanExpression
+ // Creates a Boolean expression comparing in-equality
+ // I("col").Neq(1) //("col" != 1)
+ Neq(interface{}) BooleanExpression
+ // Creates a Boolean expression for greater than comparisons
+ // I("col").Gt(1) //("col" > 1)
+ Gt(interface{}) BooleanExpression
+ // Creates a Boolean expression for greater than or equal to than comparisons
+ // I("col").Gte(1) //("col" >= 1)
+ Gte(interface{}) BooleanExpression
+ // Creates a Boolean expression for less than comparisons
+ // I("col").Lt(1) //("col" < 1)
+ Lt(interface{}) BooleanExpression
+ // Creates a Boolean expression for less than or equal to comparisons
+ // I("col").Lte(1) //("col" <= 1)
+ Lte(interface{}) BooleanExpression
+ }
+
+ // Interface that an expression should implement if it can be used in a DISTINCT epxression.
+ Distinctable interface {
+ // Creates a DISTINCT clause
+ // I("a").Distinct() //DISTINCT("a")
+ Distinct() SQLFunctionExpression
+ }
+
+ // Interface that an expression should implement if it can be ORDERED.
+ Orderable interface {
+ // Creates an Ordered Expression for sql ASC order
+ // ds.Order(I("a").Asc()) //ORDER BY "a" ASC
+ Asc() OrderedExpression
+ // Creates an Ordered Expression for sql DESC order
+ // ds.Order(I("a").Desc()) //ORDER BY "a" DESC
+ Desc() OrderedExpression
+ }
+
+ Rangeable interface {
+ // Creates a Range expression for between comparisons
+ // I("col").Between(RangeVal{Start:1, End:10}) //("col" BETWEEN 1 AND 10)
+ Between(RangeVal) RangeExpression
+ // Creates a Range expression for between comparisons
+ // I("col").NotBetween(RangeVal{Start:1, End:10}) //("col" NOT BETWEEN 1 AND 10)
+ NotBetween(RangeVal) RangeExpression
+ }
+
+ Updateable interface {
+ // Used internally by update sql
+ Set(interface{}) UpdateExpression
+ }
+
+ Bitwiseable interface {
+ // Creates a Bit Operation Expresion for sql ~
+ // I("col").BitiInversion() // (~ "col")
+ BitwiseInversion() BitwiseExpression
+ // Creates a Bit Operation Expresion for sql |
+ // I("col").BitOr(1) // ("col" | 1)
+ BitwiseOr(interface{}) BitwiseExpression
+ // Creates a Bit Operation Expresion for sql &
+ // I("col").BitAnd(1) // ("col" & 1)
+ BitwiseAnd(interface{}) BitwiseExpression
+ // Creates a Bit Operation Expresion for sql ^
+ // I("col").BitXor(1) // ("col" ^ 1)
+ BitwiseXor(interface{}) BitwiseExpression
+ // Creates a Bit Operation Expresion for sql <<
+ // I("col").BitLeftShift(1) // ("col" << 1)
+ BitwiseLeftShift(interface{}) BitwiseExpression
+ // Creates a Bit Operation Expresion for sql >>
+ // I("col").BitRighttShift(1) // ("col" >> 1)
+ BitwiseRightShift(interface{}) BitwiseExpression
+ }
+)
+
+type (
+ Vals []interface{}
+ // Parent of all expression types
+ Expression interface {
+ Clone() Expression
+ Expression() Expression
+ }
+ // An Expression that generates its own sql (e.g Dataset)
+ SQLExpression interface {
+ Expression
+ ToSQL() (string, []interface{}, error)
+ IsPrepared() bool
+ }
+
+ AppendableExpression interface {
+ Expression
+ AppendSQL(b sb.SQLBuilder)
+ // Returns the alias value as an identiier expression
+ GetAs() IdentifierExpression
+
+ // Returns true if this expression returns columns.
+ // Used to determine if a Select, Update, Insert, or Delete query returns columns
+ ReturnsColumns() bool
+ }
+ // Expression for Aliased expressions
+ // I("a").As("b") -> "a" AS "b"
+ // SUM("a").As(I("a_sum")) -> SUM("a") AS "a_sum"
+ AliasedExpression interface {
+ Expression
+ // Returns the Epxression being aliased
+ Aliased() Expression
+ // Returns the alias value as an identiier expression
+ GetAs() IdentifierExpression
+
+ // Returns a new IdentifierExpression with the specified schema
+ Schema(string) IdentifierExpression
+ // Returns a new IdentifierExpression with the specified table
+ Table(string) IdentifierExpression
+ // Returns a new IdentifierExpression with the specified column
+ Col(interface{}) IdentifierExpression
+ // Returns a new IdentifierExpression with the column set to *
+ // I("my_table").All() //"my_table".*
+ All() IdentifierExpression
+ }
+
+ BooleanOperation int
+ BooleanExpression interface {
+ Expression
+ Aliaseable
+ // Returns the operator for the expression
+ Op() BooleanOperation
+ // The left hand side of the expression (e.g. I("a")
+ LHS() Expression
+ // The right hand side of the expression could be a primitive value, dataset, or expression
+ RHS() interface{}
+ }
+
+ BitwiseOperation int
+ BitwiseExpression interface {
+ Expression
+ Aliaseable
+ Comparable
+ Isable
+ Inable
+ Likeable
+ Rangeable
+ Orderable
+ Distinctable
+ // Returns the operator for the expression
+ Op() BitwiseOperation
+ // The left hand side of the expression (e.g. I("a")
+ LHS() Expression
+ // The right hand side of the expression could be a primitive value, dataset, or expression
+ RHS() interface{}
+ }
+
+ // An Expression that represents another Expression casted to a SQL type
+ CastExpression interface {
+ Expression
+ Aliaseable
+ Comparable
+ Inable
+ Isable
+ Likeable
+ Orderable
+ Distinctable
+ Rangeable
+ // The exression being casted
+ Casted() Expression
+ // The the SQL type to cast the expression to
+ Type() LiteralExpression
+ }
+ // A list of columns. Typically used internally by Select, Order, From
+ ColumnListExpression interface {
+ Expression
+ // Returns the list of columns
+ Columns() []Expression
+ // Returns true if the column list is empty
+ IsEmpty() bool
+ // Returns a new ColumnListExpression with the columns appended.
+ Append(...Expression) ColumnListExpression
+ }
+ CompoundType int
+ CompoundExpression interface {
+ Expression
+ Type() CompoundType
+ RHS() AppendableExpression
+ }
+ // An Expression that the ON CONFLICT/ON DUPLICATE KEY portion of an INSERT statement
+ ConflictAction int
+ ConflictExpression interface {
+ Expression
+ Action() ConflictAction
+ }
+ ConflictUpdateExpression interface {
+ ConflictExpression
+ TargetColumn() string
+ Where(expressions ...Expression) ConflictUpdateExpression
+ WhereClause() ExpressionList
+ Update() interface{}
+ }
+ CommonTableExpression interface {
+ Expression
+ IsRecursive() bool
+ // Returns the alias name for the extracted expression
+ Name() LiteralExpression
+ // Returns the Expression being extracted
+ SubQuery() Expression
+ }
+ ExpressionListType int
+ // A list of expressions that should be joined together
+ // And(I("a").Eq(10), I("b").Eq(11)) //(("a" = 10) AND ("b" = 11))
+ // Or(I("a").Eq(10), I("b").Eq(11)) //(("a" = 10) OR ("b" = 11))
+ ExpressionList interface {
+ Expression
+ // Returns type (e.g. OR, AND)
+ Type() ExpressionListType
+ // Slice of expressions that should be joined together
+ Expressions() []Expression
+ // Returns a new expression list with the given expressions appended to the current Expressions list
+ Append(...Expression) ExpressionList
+
+ IsEmpty() bool
+ }
+ // An Identifier that can contain schema, table and column identifiers
+ IdentifierExpression interface {
+ Expression
+ Aliaseable
+ Comparable
+ Inable
+ Isable
+ Likeable
+ Rangeable
+ Orderable
+ Updateable
+ Distinctable
+ Castable
+ Bitwiseable
+ // returns true if this identifier has more more than on part (Schema, Table or Col)
+ // "schema" -> true //cant qualify anymore
+ // "schema.table" -> true
+ // "table" -> false
+ // "schema"."table"."col" -> true
+ // "table"."col" -> true
+ // "col" -> false
+ IsQualified() bool
+ // Returns a new IdentifierExpression with the specified schema
+ Schema(string) IdentifierExpression
+ // Returns the current schema
+ GetSchema() string
+ // Returns a new IdentifierExpression with the specified table
+ Table(string) IdentifierExpression
+ // Returns the current table
+ GetTable() string
+ // Returns a new IdentifierExpression with the specified column
+ Col(interface{}) IdentifierExpression
+ // Returns the current column
+ GetCol() interface{}
+ // Returns a new IdentifierExpression with the column set to *
+ // I("my_table").All() //"my_table".*
+ All() IdentifierExpression
+
+ // Returns true if schema table and identifier are all zero values.
+ IsEmpty() bool
+ }
+ InsertExpression interface {
+ Expression
+ IsEmpty() bool
+ IsInsertFrom() bool
+ From() AppendableExpression
+ Cols() ColumnListExpression
+ SetCols(cols ColumnListExpression) InsertExpression
+ Vals() [][]interface{}
+ SetVals([][]interface{}) InsertExpression
+ }
+
+ JoinType int
+ JoinExpression interface {
+ Expression
+ JoinType() JoinType
+ IsConditioned() bool
+ Table() Expression
+ }
+ // Parent type for join expressions
+ ConditionedJoinExpression interface {
+ JoinExpression
+ Condition() JoinCondition
+ IsConditionEmpty() bool
+ }
+ LateralExpression interface {
+ Expression
+ Aliaseable
+ Table() AppendableExpression
+ }
+
+ // Expression for representing "literal" sql.
+ // L("col = 1") -> col = 1)
+ // L("? = ?", I("col"), 1) -> "col" = 1
+ LiteralExpression interface {
+ Expression
+ Aliaseable
+ Comparable
+ Isable
+ Inable
+ Likeable
+ Rangeable
+ Orderable
+ Bitwiseable
+ // Returns the literal sql
+ Literal() string
+ // Arguments to be replaced within the sql
+ Args() []interface{}
+ }
+
+ NullSortType int
+ SortDirection int
+ // An expression for specifying sort order and options
+ OrderedExpression interface {
+ Expression
+ // The expression being sorted
+ SortExpression() Expression
+ // Sort direction (e.g. ASC, DESC)
+ IsAsc() bool
+ // If the adapter supports it null sort type (e.g. NULLS FIRST, NULLS LAST)
+ NullSortType() NullSortType
+ // Returns a new OrderedExpression with NullSortType set to NULLS_FIRST
+ NullsFirst() OrderedExpression
+ // Returns a new OrderedExpression with NullSortType set to NULLS_LAST
+ NullsLast() OrderedExpression
+ }
+
+ RangeOperation int
+ RangeExpression interface {
+ Expression
+ // Returns the operator for the expression
+ Op() RangeOperation
+ // The left hand side of the expression (e.g. I("a")
+ LHS() Expression
+ // The right hand side of the expression could be a primitive value, dataset, or expression
+ RHS() RangeVal
+ }
+ RangeVal interface {
+ Start() interface{}
+ End() interface{}
+ }
+
+ Windowable interface {
+ Over(WindowExpression) SQLWindowFunctionExpression
+ OverName(IdentifierExpression) SQLWindowFunctionExpression
+ }
+
+ // Expression for representing a SQLFunction(e.g. COUNT, SUM, MIN, MAX...)
+ SQLFunctionExpression interface {
+ Expression
+ Aliaseable
+ Rangeable
+ Comparable
+ Orderable
+ Isable
+ Inable
+ Likeable
+ Windowable
+ // The function name
+ Name() string
+ // Arguments to be passed to the function
+ Args() []interface{}
+ }
+
+ UpdateExpression interface {
+ Col() IdentifierExpression
+ Val() interface{}
+ }
+
+ SQLWindowFunctionExpression interface {
+ Expression
+ Aliaseable
+ Rangeable
+ Comparable
+ Orderable
+ Isable
+ Inable
+ Likeable
+ Func() SQLFunctionExpression
+
+ Window() WindowExpression
+ WindowName() IdentifierExpression
+
+ HasWindow() bool
+ HasWindowName() bool
+ }
+
+ WindowExpression interface {
+ Expression
+
+ Name() IdentifierExpression
+ HasName() bool
+
+ Parent() IdentifierExpression
+ HasParent() bool
+ PartitionCols() ColumnListExpression
+ HasPartitionBy() bool
+ OrderCols() ColumnListExpression
+ HasOrder() bool
+
+ Inherit(parent string) WindowExpression
+ PartitionBy(cols ...interface{}) WindowExpression
+ OrderBy(cols ...interface{}) WindowExpression
+ }
+ CaseElse interface {
+ Result() interface{}
+ }
+ CaseWhen interface {
+ Condition() interface{}
+ Result() interface{}
+ }
+ CaseExpression interface {
+ Expression
+ Aliaseable
+ Orderable
+ GetValue() interface{}
+ GetWhens() []CaseWhen
+ GetElse() CaseElse
+ Value(val interface{}) CaseExpression
+ When(condition, result interface{}) CaseExpression
+ Else(result interface{}) CaseExpression
+ }
+)
+
+const (
+ UnionCompoundType CompoundType = iota
+ UnionAllCompoundType
+ IntersectCompoundType
+ IntersectAllCompoundType
+
+ DoNothingConflictAction ConflictAction = iota
+ DoUpdateConflictAction
+
+ AndType ExpressionListType = iota
+ OrType
+
+ InnerJoinType JoinType = iota
+ FullOuterJoinType
+ RightOuterJoinType
+ LeftOuterJoinType
+ FullJoinType
+ RightJoinType
+ LeftJoinType
+ NaturalJoinType
+ NaturalLeftJoinType
+ NaturalRightJoinType
+ NaturalFullJoinType
+ CrossJoinType
+
+ UsingJoinCondType JoinConditionType = iota
+ OnJoinCondType
+
+ // Default null sort type with no null sort order
+ NoNullsSortType NullSortType = iota
+ // NULLS FIRST
+ NullsFirstSortType
+ // NULLS LAST
+ NullsLastSortType
+ // ASC
+ AscDir SortDirection = iota
+ // DESC
+ DescSortDir
+
+ // BETWEEN
+ BetweenOp RangeOperation = iota
+ // NOT BETWEEN
+ NotBetweenOp
+
+ // =
+ EqOp BooleanOperation = iota
+ // != or <>
+ NeqOp
+ // IS
+ IsOp
+ // IS NOT
+ IsNotOp
+ // >
+ GtOp
+ // >=
+ GteOp
+ // <
+ LtOp
+ // <=
+ LteOp
+ // IN
+ InOp
+ // NOT IN
+ NotInOp
+ // LIKE, LIKE BINARY...
+ LikeOp
+ // NOT LIKE, NOT LIKE BINARY...
+ NotLikeOp
+ // ILIKE, LIKE
+ ILikeOp
+ // NOT ILIKE, NOT LIKE
+ NotILikeOp
+ // ~, REGEXP BINARY
+ RegexpLikeOp
+ // !~, NOT REGEXP BINARY
+ RegexpNotLikeOp
+ // ~*, REGEXP
+ RegexpILikeOp
+ // !~*, NOT REGEXP
+ RegexpNotILikeOp
+
+ betweenStr = "between"
+
+ BitwiseInversionOp BitwiseOperation = iota
+ BitwiseOrOp
+ BitwiseAndOp
+ BitwiseXorOp
+ BitwiseLeftShiftOp
+ BitwiseRightShiftOp
+)
+
+var (
+ ConditionedJoinTypes = map[JoinType]bool{
+ InnerJoinType: true,
+ FullOuterJoinType: true,
+ RightOuterJoinType: true,
+ LeftOuterJoinType: true,
+ FullJoinType: true,
+ RightJoinType: true,
+ LeftJoinType: true,
+ }
+ // used internally for inverting operators
+ operatorInversions = map[BooleanOperation]BooleanOperation{
+ IsOp: IsNotOp,
+ EqOp: NeqOp,
+ GtOp: LteOp,
+ GteOp: LtOp,
+ LtOp: GteOp,
+ LteOp: GtOp,
+ InOp: NotInOp,
+ LikeOp: NotLikeOp,
+ ILikeOp: NotILikeOp,
+ RegexpLikeOp: RegexpNotLikeOp,
+ RegexpILikeOp: RegexpNotILikeOp,
+ IsNotOp: IsOp,
+ NeqOp: EqOp,
+ NotInOp: InOp,
+ NotLikeOp: LikeOp,
+ NotILikeOp: ILikeOp,
+ RegexpNotLikeOp: RegexpLikeOp,
+ RegexpNotILikeOp: RegexpILikeOp,
+ }
+)
+
+func (bo BooleanOperation) String() string {
+ switch bo {
+ case EqOp:
+ return "eq"
+ case NeqOp:
+ return "neq"
+ case IsOp:
+ return "is"
+ case IsNotOp:
+ return "isnot"
+ case GtOp:
+ return "gt"
+ case GteOp:
+ return "gte"
+ case LtOp:
+ return "lt"
+ case LteOp:
+ return "lte"
+ case InOp:
+ return "in"
+ case NotInOp:
+ return "notin"
+ case LikeOp:
+ return "like"
+ case NotLikeOp:
+ return "notlike"
+ case ILikeOp:
+ return "ilike"
+ case NotILikeOp:
+ return "notilike"
+ case RegexpLikeOp:
+ return "regexplike"
+ case RegexpNotLikeOp:
+ return "regexpnotlike"
+ case RegexpILikeOp:
+ return "regexpilike"
+ case RegexpNotILikeOp:
+ return "regexpnotilike"
+ }
+ return fmt.Sprintf("%d", bo)
+}
+
+func (bi BitwiseOperation) String() string {
+ switch bi {
+ case BitwiseInversionOp:
+ return "Inversion"
+ case BitwiseOrOp:
+ return "OR"
+ case BitwiseAndOp:
+ return "AND"
+ case BitwiseXorOp:
+ return "XOR"
+ case BitwiseLeftShiftOp:
+ return "Left Shift"
+ case BitwiseRightShiftOp:
+ return "Right Shift"
+ }
+ return fmt.Sprintf("%d", bi)
+}
+
+func (ro RangeOperation) String() string {
+ switch ro {
+ case BetweenOp:
+ return betweenStr
+ case NotBetweenOp:
+ return "not between"
+ }
+ return fmt.Sprintf("%d", ro)
+}
+
+func (jt JoinType) String() string {
+ switch jt {
+ case InnerJoinType:
+ return "InnerJoinType"
+ case FullOuterJoinType:
+ return "FullOuterJoinType"
+ case RightOuterJoinType:
+ return "RightOuterJoinType"
+ case LeftOuterJoinType:
+ return "LeftOuterJoinType"
+ case FullJoinType:
+ return "FullJoinType"
+ case RightJoinType:
+ return "RightJoinType"
+ case LeftJoinType:
+ return "LeftJoinType"
+ case NaturalJoinType:
+ return "NaturalJoinType"
+ case NaturalLeftJoinType:
+ return "NaturalLeftJoinType"
+ case NaturalRightJoinType:
+ return "NaturalRightJoinType"
+ case NaturalFullJoinType:
+ return "NaturalFullJoinType"
+ case CrossJoinType:
+ return "CrossJoinType"
+ }
+ return fmt.Sprintf("%d", jt)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/exp_list.go b/vendor/github.com/doug-martin/goqu/v9/exp/exp_list.go
new file mode 100644
index 000000000..ff2bbc967
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/exp_list.go
@@ -0,0 +1,66 @@
+package exp
+
+type (
+ expressionList struct {
+ operator ExpressionListType
+ expressions []Expression
+ }
+)
+
+// A list of expressions that should be ORed together
+// Or(I("a").Eq(10), I("b").Eq(11)) //(("a" = 10) OR ("b" = 11))
+func NewExpressionList(operator ExpressionListType, expressions ...Expression) ExpressionList {
+ el := expressionList{operator: operator}
+ exps := make([]Expression, 0, len(el.expressions))
+ for _, e := range expressions {
+ switch t := e.(type) {
+ case ExpressionList:
+ if !t.IsEmpty() {
+ exps = append(exps, e)
+ }
+ case Ex:
+ if len(t) > 0 {
+ exps = append(exps, e)
+ }
+ case ExOr:
+ if len(t) > 0 {
+ exps = append(exps, e)
+ }
+ default:
+ exps = append(exps, e)
+ }
+ }
+ el.expressions = exps
+ return el
+}
+
+func (el expressionList) Clone() Expression {
+ newExps := make([]Expression, 0, len(el.expressions))
+ for _, exp := range el.expressions {
+ newExps = append(newExps, exp.Clone())
+ }
+ return expressionList{operator: el.operator, expressions: newExps}
+}
+
+func (el expressionList) Expression() Expression {
+ return el
+}
+
+func (el expressionList) IsEmpty() bool {
+ return len(el.expressions) == 0
+}
+
+func (el expressionList) Type() ExpressionListType {
+ return el.operator
+}
+
+func (el expressionList) Expressions() []Expression {
+ return el.expressions
+}
+
+func (el expressionList) Append(expressions ...Expression) ExpressionList {
+ exps := make([]Expression, 0, len(el.expressions)+len(expressions))
+ exps = append(exps, el.expressions...)
+ exps = append(exps, expressions...)
+ return NewExpressionList(el.operator, exps...)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/exp_map.go b/vendor/github.com/doug-martin/goqu/v9/exp/exp_map.go
new file mode 100644
index 000000000..3fea06b10
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/exp_map.go
@@ -0,0 +1,164 @@
+package exp
+
+import (
+ "sort"
+ "strings"
+
+ "github.com/doug-martin/goqu/v9/internal/errors"
+)
+
+type (
+ // A map of expressions to be ANDed together where the keys are string that will be used as Identifiers and values
+ // will be used in a boolean operation.
+ // The Ex map can be used in tandem with Op map to create more complex expression such as LIKE, GT, LT...
+ // See examples.
+ Ex map[string]interface{}
+ // A map of expressions to be ORed together where the keys are string that will be used as Identifiers and values
+ // will be used in a boolean operation.
+ // The Ex map can be used in tandem with Op map to create more complex expression such as LIKE, GT, LT...
+ // See examples.
+ ExOr map[string]interface{}
+ // Used in tandem with the Ex map to create complex comparisons such as LIKE, GT, LT... See examples
+ Op map[string]interface{}
+)
+
+func (e Ex) Expression() Expression {
+ return e
+}
+
+func (e Ex) Clone() Expression {
+ ret := Ex{}
+ for key, val := range e {
+ ret[key] = val
+ }
+ return ret
+}
+
+func (e Ex) IsEmpty() bool {
+ return len(e) == 0
+}
+
+func (e Ex) ToExpressions() (ExpressionList, error) {
+ return mapToExpressionList(e, AndType)
+}
+
+func (eo ExOr) Expression() Expression {
+ return eo
+}
+
+func (eo ExOr) Clone() Expression {
+ ret := ExOr{}
+ for key, val := range eo {
+ ret[key] = val
+ }
+ return ret
+}
+
+func (eo ExOr) IsEmpty() bool {
+ return len(eo) == 0
+}
+
+func (eo ExOr) ToExpressions() (ExpressionList, error) {
+ return mapToExpressionList(eo, OrType)
+}
+
+func getExMapKeys(ex map[string]interface{}) []string {
+ keys := make([]string, 0, len(ex))
+ for key := range ex {
+ keys = append(keys, key)
+ }
+ sort.Strings(keys)
+ return keys
+}
+
+func mapToExpressionList(ex map[string]interface{}, eType ExpressionListType) (ExpressionList, error) {
+ keys := getExMapKeys(ex)
+ ret := make([]Expression, 0, len(keys))
+ for _, key := range keys {
+ lhs := ParseIdentifier(key)
+ rhs := ex[key]
+ var exp Expression
+ if op, ok := rhs.(Op); ok {
+ ors, err := createOredExpressionFromMap(lhs, op)
+ if err != nil {
+ return nil, err
+ }
+ exp = NewExpressionList(OrType, ors...)
+ } else {
+ exp = lhs.Eq(rhs)
+ }
+ ret = append(ret, exp)
+ }
+ if eType == OrType {
+ return NewExpressionList(OrType, ret...), nil
+ }
+ return NewExpressionList(AndType, ret...), nil
+}
+
+func createOredExpressionFromMap(lhs IdentifierExpression, op Op) ([]Expression, error) {
+ opKeys := getExMapKeys(op)
+ ors := make([]Expression, 0, len(opKeys))
+ for _, opKey := range opKeys {
+ if exp, err := createExpressionFromOp(lhs, opKey, op); err != nil {
+ return nil, err
+ } else if exp != nil {
+ ors = append(ors, exp)
+ }
+ }
+ return ors, nil
+}
+
+// nolint:gocyclo // not complex just long
+func createExpressionFromOp(lhs IdentifierExpression, opKey string, op Op) (exp Expression, err error) {
+ switch strings.ToLower(opKey) {
+ case EqOp.String():
+ exp = lhs.Eq(op[opKey])
+ case NeqOp.String():
+ exp = lhs.Neq(op[opKey])
+ case IsOp.String():
+ exp = lhs.Is(op[opKey])
+ case IsNotOp.String():
+ exp = lhs.IsNot(op[opKey])
+ case GtOp.String():
+ exp = lhs.Gt(op[opKey])
+ case GteOp.String():
+ exp = lhs.Gte(op[opKey])
+ case LtOp.String():
+ exp = lhs.Lt(op[opKey])
+ case LteOp.String():
+ exp = lhs.Lte(op[opKey])
+ case InOp.String():
+ exp = lhs.In(op[opKey])
+ case NotInOp.String():
+ exp = lhs.NotIn(op[opKey])
+ case LikeOp.String():
+ exp = lhs.Like(op[opKey])
+ case NotLikeOp.String():
+ exp = lhs.NotLike(op[opKey])
+ case ILikeOp.String():
+ exp = lhs.ILike(op[opKey])
+ case NotILikeOp.String():
+ exp = lhs.NotILike(op[opKey])
+ case RegexpLikeOp.String():
+ exp = lhs.RegexpLike(op[opKey])
+ case RegexpNotLikeOp.String():
+ exp = lhs.RegexpNotLike(op[opKey])
+ case RegexpILikeOp.String():
+ exp = lhs.RegexpILike(op[opKey])
+ case RegexpNotILikeOp.String():
+ exp = lhs.RegexpNotILike(op[opKey])
+ case betweenStr:
+ rangeVal, ok := op[opKey].(RangeVal)
+ if ok {
+ exp = lhs.Between(rangeVal)
+ }
+ case "notbetween":
+ rangeVal, ok := op[opKey].(RangeVal)
+ if ok {
+ exp = lhs.NotBetween(rangeVal)
+ }
+ default:
+ err = errors.New("unsupported expression type %s", opKey)
+ }
+ return exp, err
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/func.go b/vendor/github.com/doug-martin/goqu/v9/exp/func.go
new file mode 100644
index 000000000..0ab8cfd94
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/func.go
@@ -0,0 +1,89 @@
+package exp
+
+type (
+ sqlFunctionExpression struct {
+ name string
+ args []interface{}
+ }
+)
+
+// Creates a new SQLFunctionExpression with the given name and arguments
+func NewSQLFunctionExpression(name string, args ...interface{}) SQLFunctionExpression {
+ return sqlFunctionExpression{name: name, args: args}
+}
+
+func (sfe sqlFunctionExpression) Clone() Expression {
+ return sqlFunctionExpression{name: sfe.name, args: sfe.args}
+}
+
+func (sfe sqlFunctionExpression) Expression() Expression { return sfe }
+
+func (sfe sqlFunctionExpression) Args() []interface{} { return sfe.args }
+
+func (sfe sqlFunctionExpression) Name() string { return sfe.name }
+
+func (sfe sqlFunctionExpression) As(val interface{}) AliasedExpression {
+ return NewAliasExpression(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) Eq(val interface{}) BooleanExpression { return eq(sfe, val) }
+func (sfe sqlFunctionExpression) Neq(val interface{}) BooleanExpression { return neq(sfe, val) }
+
+func (sfe sqlFunctionExpression) Gt(val interface{}) BooleanExpression { return gt(sfe, val) }
+func (sfe sqlFunctionExpression) Gte(val interface{}) BooleanExpression { return gte(sfe, val) }
+func (sfe sqlFunctionExpression) Lt(val interface{}) BooleanExpression { return lt(sfe, val) }
+func (sfe sqlFunctionExpression) Lte(val interface{}) BooleanExpression { return lte(sfe, val) }
+
+func (sfe sqlFunctionExpression) Between(val RangeVal) RangeExpression { return between(sfe, val) }
+
+func (sfe sqlFunctionExpression) NotBetween(val RangeVal) RangeExpression {
+ return notBetween(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) Like(val interface{}) BooleanExpression { return like(sfe, val) }
+func (sfe sqlFunctionExpression) NotLike(val interface{}) BooleanExpression { return notLike(sfe, val) }
+func (sfe sqlFunctionExpression) ILike(val interface{}) BooleanExpression { return iLike(sfe, val) }
+
+func (sfe sqlFunctionExpression) NotILike(val interface{}) BooleanExpression {
+ return notILike(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) RegexpLike(val interface{}) BooleanExpression {
+ return regexpLike(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) RegexpNotLike(val interface{}) BooleanExpression {
+ return regexpNotLike(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) RegexpILike(val interface{}) BooleanExpression {
+ return regexpILike(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) RegexpNotILike(val interface{}) BooleanExpression {
+ return regexpNotILike(sfe, val)
+}
+
+func (sfe sqlFunctionExpression) In(vals ...interface{}) BooleanExpression { return in(sfe, vals...) }
+func (sfe sqlFunctionExpression) NotIn(vals ...interface{}) BooleanExpression {
+ return notIn(sfe, vals...)
+}
+func (sfe sqlFunctionExpression) Is(val interface{}) BooleanExpression { return is(sfe, val) }
+func (sfe sqlFunctionExpression) IsNot(val interface{}) BooleanExpression { return isNot(sfe, val) }
+func (sfe sqlFunctionExpression) IsNull() BooleanExpression { return is(sfe, nil) }
+func (sfe sqlFunctionExpression) IsNotNull() BooleanExpression { return isNot(sfe, nil) }
+func (sfe sqlFunctionExpression) IsTrue() BooleanExpression { return is(sfe, true) }
+func (sfe sqlFunctionExpression) IsNotTrue() BooleanExpression { return isNot(sfe, true) }
+func (sfe sqlFunctionExpression) IsFalse() BooleanExpression { return is(sfe, false) }
+func (sfe sqlFunctionExpression) IsNotFalse() BooleanExpression { return isNot(sfe, false) }
+
+func (sfe sqlFunctionExpression) Over(we WindowExpression) SQLWindowFunctionExpression {
+ return NewSQLWindowFunctionExpression(sfe, nil, we)
+}
+
+func (sfe sqlFunctionExpression) OverName(windowName IdentifierExpression) SQLWindowFunctionExpression {
+ return NewSQLWindowFunctionExpression(sfe, windowName, nil)
+}
+
+func (sfe sqlFunctionExpression) Asc() OrderedExpression { return asc(sfe) }
+func (sfe sqlFunctionExpression) Desc() OrderedExpression { return desc(sfe) }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/ident.go b/vendor/github.com/doug-martin/goqu/v9/exp/ident.go
new file mode 100644
index 000000000..aebbbd5a9
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/ident.go
@@ -0,0 +1,213 @@
+package exp
+
+import (
+ "strings"
+)
+
+type (
+ identifier struct {
+ schema string
+ table string
+ col interface{}
+ }
+)
+
+var (
+ tableAndColumnParts = 2
+ schemaTableAndColumnIdentifierParts = 3
+)
+
+func ParseIdentifier(ident string) IdentifierExpression {
+ parts := strings.Split(ident, ".")
+ switch len(parts) {
+ case tableAndColumnParts:
+ return NewIdentifierExpression("", parts[0], parts[1])
+ case schemaTableAndColumnIdentifierParts:
+ return NewIdentifierExpression(parts[0], parts[1], parts[2])
+ }
+ return NewIdentifierExpression("", "", ident)
+}
+
+func NewIdentifierExpression(schema, table string, col interface{}) IdentifierExpression {
+ return identifier{}.Schema(schema).Table(table).Col(col)
+}
+
+func (i identifier) clone() identifier {
+ return identifier{schema: i.schema, table: i.table, col: i.col}
+}
+
+func (i identifier) Clone() Expression {
+ return i.clone()
+}
+
+func (i identifier) IsQualified() bool {
+ schema, table, col := i.schema, i.table, i.col
+ switch c := col.(type) {
+ case string:
+ if c != "" {
+ return len(table) > 0 || len(schema) > 0
+ }
+ default:
+ if c != nil {
+ return len(table) > 0 || len(schema) > 0
+ }
+ }
+ if len(table) > 0 {
+ return len(schema) > 0
+ }
+ return false
+}
+
+// Sets the table on the current identifier
+// I("col").Table("table") -> "table"."col" //postgres
+// I("col").Table("table") -> `table`.`col` //mysql
+// I("col").Table("table") -> `table`.`col` //sqlite3
+func (i identifier) Table(table string) IdentifierExpression {
+ i.table = table
+ return i
+}
+
+func (i identifier) GetTable() string {
+ return i.table
+}
+
+// Sets the table on the current identifier
+// I("table").Schema("schema") -> "schema"."table" //postgres
+// I("col").Schema("table") -> `schema`.`table` //mysql
+// I("col").Schema("table") -> `schema`.`table` //sqlite3
+func (i identifier) Schema(schema string) IdentifierExpression {
+ i.schema = schema
+ return i
+}
+
+func (i identifier) GetSchema() string {
+ return i.schema
+}
+
+// Sets the table on the current identifier
+// I("table").Col("col") -> "table"."col" //postgres
+// I("table").Schema("col") -> `table`.`col` //mysql
+// I("table").Schema("col") -> `table`.`col` //sqlite3
+func (i identifier) Col(col interface{}) IdentifierExpression {
+ if col == "*" {
+ i.col = Star()
+ } else {
+ i.col = col
+ }
+ return i
+}
+
+func (i identifier) Expression() Expression { return i }
+
+// Qualifies the epression with a * literal (e.g. "table".*)
+func (i identifier) All() IdentifierExpression { return i.Col("*") }
+
+func (i identifier) IsEmpty() bool {
+ isEmpty := i.schema == "" && i.table == ""
+ if isEmpty {
+ switch t := i.col.(type) {
+ case nil:
+ return true
+ case string:
+ return t == ""
+ default:
+ return false
+ }
+ }
+ return isEmpty
+}
+
+// Gets the column identifier
+func (i identifier) GetCol() interface{} { return i.col }
+
+// Used within updates to set a column value
+func (i identifier) Set(val interface{}) UpdateExpression { return set(i, val) }
+
+// Alias an identifier (e.g "my_col" AS "other_col")
+func (i identifier) As(val interface{}) AliasedExpression {
+ if v, ok := val.(string); ok {
+ ident := ParseIdentifier(v)
+ if i.col != nil && i.col != "" {
+ return NewAliasExpression(i, ident)
+ }
+ aliasCol := ident.GetCol()
+ if i.table != "" {
+ return NewAliasExpression(i, NewIdentifierExpression("", aliasCol.(string), nil))
+ } else if i.schema != "" {
+ return NewAliasExpression(i, NewIdentifierExpression(aliasCol.(string), "", nil))
+ }
+ }
+ return NewAliasExpression(i, val)
+}
+
+// Returns a BooleanExpression for equality (e.g "my_col" = 1)
+func (i identifier) Eq(val interface{}) BooleanExpression { return eq(i, val) }
+
+// Returns a BooleanExpression for in equality (e.g "my_col" != 1)
+func (i identifier) Neq(val interface{}) BooleanExpression { return neq(i, val) }
+
+// Returns a BooleanExpression for checking that a identifier is greater than another value (e.g "my_col" > 1)
+func (i identifier) Gt(val interface{}) BooleanExpression { return gt(i, val) }
+
+// Returns a BooleanExpression for checking that a identifier is greater than or equal to another value
+// (e.g "my_col" >= 1)
+func (i identifier) Gte(val interface{}) BooleanExpression { return gte(i, val) }
+
+// Returns a BooleanExpression for checking that a identifier is less than another value (e.g "my_col" < 1)
+func (i identifier) Lt(val interface{}) BooleanExpression { return lt(i, val) }
+
+// Returns a BooleanExpression for checking that a identifier is less than or equal to another value
+// (e.g "my_col" <= 1)
+func (i identifier) Lte(val interface{}) BooleanExpression { return lte(i, val) }
+
+// Returns a BooleanExpression for bit inversion (e.g ~ "my_col")
+func (i identifier) BitwiseInversion() BitwiseExpression { return bitwiseInversion(i) }
+
+// Returns a BooleanExpression for bit OR (e.g "my_col" | 1)
+func (i identifier) BitwiseOr(val interface{}) BitwiseExpression { return bitwiseOr(i, val) }
+
+// Returns a BooleanExpression for bit AND (e.g "my_col" & 1)
+func (i identifier) BitwiseAnd(val interface{}) BitwiseExpression { return bitwiseAnd(i, val) }
+
+// Returns a BooleanExpression for bit XOR (e.g "my_col" ^ 1)
+func (i identifier) BitwiseXor(val interface{}) BitwiseExpression { return bitwiseXor(i, val) }
+
+// Returns a BooleanExpression for bit LEFT shift (e.g "my_col" << 1)
+func (i identifier) BitwiseLeftShift(val interface{}) BitwiseExpression {
+ return bitwiseLeftShift(i, val)
+}
+
+// Returns a BooleanExpression for bit RIGHT shift (e.g "my_col" >> 1)
+func (i identifier) BitwiseRightShift(val interface{}) BitwiseExpression {
+ return bitwiseRightShift(i, val)
+}
+
+// Returns a BooleanExpression for checking that a identifier is in a list of values or (e.g "my_col" > 1)
+func (i identifier) In(vals ...interface{}) BooleanExpression { return in(i, vals...) }
+func (i identifier) NotIn(vals ...interface{}) BooleanExpression { return notIn(i, vals...) }
+func (i identifier) Like(val interface{}) BooleanExpression { return like(i, val) }
+func (i identifier) NotLike(val interface{}) BooleanExpression { return notLike(i, val) }
+func (i identifier) ILike(val interface{}) BooleanExpression { return iLike(i, val) }
+func (i identifier) NotILike(val interface{}) BooleanExpression { return notILike(i, val) }
+func (i identifier) RegexpLike(val interface{}) BooleanExpression { return regexpLike(i, val) }
+func (i identifier) RegexpNotLike(val interface{}) BooleanExpression { return regexpNotLike(i, val) }
+func (i identifier) RegexpILike(val interface{}) BooleanExpression { return regexpILike(i, val) }
+func (i identifier) RegexpNotILike(val interface{}) BooleanExpression { return regexpNotILike(i, val) }
+func (i identifier) Is(val interface{}) BooleanExpression { return is(i, val) }
+func (i identifier) IsNot(val interface{}) BooleanExpression { return isNot(i, val) }
+func (i identifier) IsNull() BooleanExpression { return is(i, nil) }
+func (i identifier) IsNotNull() BooleanExpression { return isNot(i, nil) }
+func (i identifier) IsTrue() BooleanExpression { return is(i, true) }
+func (i identifier) IsNotTrue() BooleanExpression { return isNot(i, true) }
+func (i identifier) IsFalse() BooleanExpression { return is(i, false) }
+func (i identifier) IsNotFalse() BooleanExpression { return isNot(i, false) }
+func (i identifier) Asc() OrderedExpression { return asc(i) }
+func (i identifier) Desc() OrderedExpression { return desc(i) }
+func (i identifier) Distinct() SQLFunctionExpression { return NewSQLFunctionExpression("DISTINCT", i) }
+func (i identifier) Cast(t string) CastExpression { return NewCastExpression(i, t) }
+
+// Returns a RangeExpression for checking that a identifier is between two values (e.g "my_col" BETWEEN 1 AND 10)
+func (i identifier) Between(val RangeVal) RangeExpression { return between(i, val) }
+
+// Returns a RangeExpression for checking that a identifier is between two values (e.g "my_col" BETWEEN 1 AND 10)
+func (i identifier) NotBetween(val RangeVal) RangeExpression { return notBetween(i, val) }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/insert.go b/vendor/github.com/doug-martin/goqu/v9/exp/insert.go
new file mode 100644
index 000000000..7f58b3cd0
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/insert.go
@@ -0,0 +1,163 @@
+package exp
+
+import (
+ "reflect"
+ "sort"
+
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+type (
+ insert struct {
+ from AppendableExpression
+ cols ColumnListExpression
+ vals [][]interface{}
+ }
+)
+
+func NewInsertExpression(rows ...interface{}) (insertExpression InsertExpression, err error) {
+ switch len(rows) {
+ case 0:
+ return new(insert), nil
+ case 1:
+ val := reflect.ValueOf(rows[0])
+ if val.Kind() == reflect.Slice {
+ vals := make([]interface{}, 0, val.Len())
+ for i := 0; i < val.Len(); i++ {
+ vals = append(vals, val.Index(i).Interface())
+ }
+ return NewInsertExpression(vals...)
+ }
+ if ae, ok := rows[0].(AppendableExpression); ok {
+ return &insert{from: ae}, nil
+ }
+ }
+ return newInsert(rows...)
+}
+
+func (i *insert) Expression() Expression {
+ return i
+}
+
+func (i *insert) Clone() Expression {
+ return i.clone()
+}
+
+func (i *insert) clone() *insert {
+ return &insert{from: i.from, cols: i.cols, vals: i.vals}
+}
+
+func (i *insert) IsEmpty() bool {
+ return i.from == nil && (i.cols == nil || i.cols.IsEmpty())
+}
+
+func (i *insert) IsInsertFrom() bool {
+ return i.from != nil
+}
+
+func (i *insert) From() AppendableExpression {
+ return i.from
+}
+
+func (i *insert) Cols() ColumnListExpression {
+ return i.cols
+}
+
+func (i *insert) SetCols(cols ColumnListExpression) InsertExpression {
+ ci := i.clone()
+ ci.cols = cols
+ return ci
+}
+
+func (i *insert) Vals() [][]interface{} {
+ return i.vals
+}
+
+func (i *insert) SetVals(vals [][]interface{}) InsertExpression {
+ ci := i.clone()
+ ci.vals = vals
+ return ci
+}
+
+// parses the rows gathering and sorting unique columns and values for each record
+func newInsert(rows ...interface{}) (insertExp InsertExpression, err error) {
+ var mapKeys util.ValueSlice
+ rowValue := reflect.Indirect(reflect.ValueOf(rows[0]))
+ rowType := rowValue.Type()
+ rowKind := rowValue.Kind()
+ if rowKind == reflect.Struct {
+ return createStructSliceInsert(rows...)
+ }
+ vals := make([][]interface{}, 0, len(rows))
+ var columns ColumnListExpression
+ for _, row := range rows {
+ if rowType != reflect.Indirect(reflect.ValueOf(row)).Type() {
+ return nil, errors.New(
+ "rows must be all the same type expected %+v got %+v",
+ rowType,
+ reflect.Indirect(reflect.ValueOf(row)).Type(),
+ )
+ }
+ newRowValue := reflect.Indirect(reflect.ValueOf(row))
+ switch rowKind {
+ case reflect.Map:
+ if columns == nil {
+ mapKeys = util.ValueSlice(newRowValue.MapKeys())
+ sort.Sort(mapKeys)
+ colKeys := make([]interface{}, 0, len(mapKeys))
+ for _, key := range mapKeys {
+ colKeys = append(colKeys, key.Interface())
+ }
+ columns = NewColumnListExpression(colKeys...)
+ }
+ newMapKeys := util.ValueSlice(newRowValue.MapKeys())
+ if len(newMapKeys) != len(mapKeys) {
+ return nil, errors.New("rows with different value length expected %d got %d", len(mapKeys), len(newMapKeys))
+ }
+ if !mapKeys.Equal(newMapKeys) {
+ return nil, errors.New("rows with different keys expected %s got %s", mapKeys.String(), newMapKeys.String())
+ }
+ rowVals := make([]interface{}, 0, len(mapKeys))
+ for _, key := range mapKeys {
+ rowVals = append(rowVals, newRowValue.MapIndex(key).Interface())
+ }
+ vals = append(vals, rowVals)
+ default:
+ return nil, errors.New(
+ "unsupported insert must be map, goqu.Record, or struct type got: %T",
+ row,
+ )
+ }
+ }
+ return &insert{cols: columns, vals: vals}, nil
+}
+
+func createStructSliceInsert(rows ...interface{}) (insertExp InsertExpression, err error) {
+ rowValue := reflect.Indirect(reflect.ValueOf(rows[0]))
+ rowType := rowValue.Type()
+ recordRows := make([]interface{}, 0, len(rows))
+ for _, row := range rows {
+ if rowType != reflect.Indirect(reflect.ValueOf(row)).Type() {
+ return nil, errors.New(
+ "rows must be all the same type expected %+v got %+v",
+ rowType,
+ reflect.Indirect(reflect.ValueOf(row)).Type(),
+ )
+ }
+ newRowValue := reflect.Indirect(reflect.ValueOf(row))
+ record, err := getFieldsValuesFromStruct(newRowValue)
+ if err != nil {
+ return nil, err
+ }
+ recordRows = append(recordRows, record)
+ }
+ return newInsert(recordRows...)
+}
+
+func getFieldsValuesFromStruct(value reflect.Value) (row Record, err error) {
+ if value.IsValid() {
+ return NewRecordFromStruct(value.Interface(), true, false)
+ }
+ return
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/insert_clauses.go b/vendor/github.com/doug-martin/goqu/v9/exp/insert_clauses.go
new file mode 100644
index 000000000..ac7a330d3
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/insert_clauses.go
@@ -0,0 +1,205 @@
+package exp
+
+type (
+ InsertClauses interface {
+ CommonTables() []CommonTableExpression
+ CommonTablesAppend(cte CommonTableExpression) InsertClauses
+
+ HasInto() bool
+ clone() *insertClauses
+
+ Cols() ColumnListExpression
+ HasCols() bool
+ ColsAppend(cols ColumnListExpression) InsertClauses
+ SetCols(cols ColumnListExpression) InsertClauses
+
+ Into() Expression
+ SetInto(cl Expression) InsertClauses
+
+ Returning() ColumnListExpression
+ HasReturning() bool
+ SetReturning(cl ColumnListExpression) InsertClauses
+
+ From() AppendableExpression
+ HasFrom() bool
+ SetFrom(ae AppendableExpression) InsertClauses
+
+ Rows() []interface{}
+ HasRows() bool
+ SetRows(rows []interface{}) InsertClauses
+
+ HasAlias() bool
+ Alias() IdentifierExpression
+ SetAlias(ie IdentifierExpression) InsertClauses
+
+ Vals() [][]interface{}
+ HasVals() bool
+ SetVals(vals [][]interface{}) InsertClauses
+ ValsAppend(vals [][]interface{}) InsertClauses
+
+ OnConflict() ConflictExpression
+ SetOnConflict(expression ConflictExpression) InsertClauses
+ }
+ insertClauses struct {
+ commonTables []CommonTableExpression
+ cols ColumnListExpression
+ into Expression
+ returning ColumnListExpression
+ alias IdentifierExpression
+ rows []interface{}
+ values [][]interface{}
+ from AppendableExpression
+ conflict ConflictExpression
+ }
+)
+
+func NewInsertClauses() InsertClauses {
+ return &insertClauses{}
+}
+
+func (ic *insertClauses) HasInto() bool {
+ return ic.into != nil
+}
+
+func (ic *insertClauses) clone() *insertClauses {
+ return &insertClauses{
+ commonTables: ic.commonTables,
+ cols: ic.cols,
+ into: ic.into,
+ returning: ic.returning,
+ alias: ic.alias,
+ rows: ic.rows,
+ values: ic.values,
+ from: ic.from,
+ conflict: ic.conflict,
+ }
+}
+
+func (ic *insertClauses) CommonTables() []CommonTableExpression {
+ return ic.commonTables
+}
+
+func (ic *insertClauses) CommonTablesAppend(cte CommonTableExpression) InsertClauses {
+ ret := ic.clone()
+ ret.commonTables = append(ret.commonTables, cte)
+ return ret
+}
+
+func (ic *insertClauses) Cols() ColumnListExpression {
+ return ic.cols
+}
+
+func (ic *insertClauses) HasCols() bool {
+ return ic.cols != nil && !ic.cols.IsEmpty()
+}
+
+func (ic *insertClauses) ColsAppend(cl ColumnListExpression) InsertClauses {
+ ret := ic.clone()
+ ret.cols = ret.cols.Append(cl.Columns()...)
+ return ret
+}
+
+func (ic *insertClauses) SetCols(cl ColumnListExpression) InsertClauses {
+ ret := ic.clone()
+ ret.cols = cl
+ return ret
+}
+
+func (ic *insertClauses) Into() Expression {
+ return ic.into
+}
+
+func (ic *insertClauses) SetInto(into Expression) InsertClauses {
+ ret := ic.clone()
+ ret.into = into
+ return ret
+}
+
+func (ic *insertClauses) Returning() ColumnListExpression {
+ return ic.returning
+}
+
+func (ic *insertClauses) HasReturning() bool {
+ return ic.returning != nil && !ic.returning.IsEmpty()
+}
+
+func (ic *insertClauses) HasAlias() bool {
+ return ic.alias != nil
+}
+
+func (ic *insertClauses) Alias() IdentifierExpression {
+ return ic.alias
+}
+
+func (ic *insertClauses) SetAlias(ie IdentifierExpression) InsertClauses {
+ ret := ic.clone()
+ ret.alias = ie
+ return ret
+}
+
+func (ic *insertClauses) SetReturning(cl ColumnListExpression) InsertClauses {
+ ret := ic.clone()
+ ret.returning = cl
+ return ret
+}
+
+func (ic *insertClauses) From() AppendableExpression {
+ return ic.from
+}
+
+func (ic *insertClauses) HasFrom() bool {
+ return ic.from != nil
+}
+
+func (ic *insertClauses) SetFrom(ae AppendableExpression) InsertClauses {
+ ret := ic.clone()
+ ret.from = ae
+ return ret
+}
+
+func (ic *insertClauses) Rows() []interface{} {
+ return ic.rows
+}
+
+func (ic *insertClauses) HasRows() bool {
+ return ic.rows != nil && len(ic.rows) > 0
+}
+
+func (ic *insertClauses) SetRows(rows []interface{}) InsertClauses {
+ ret := ic.clone()
+ ret.rows = rows
+ return ret
+}
+
+func (ic *insertClauses) Vals() [][]interface{} {
+ return ic.values
+}
+
+func (ic *insertClauses) HasVals() bool {
+ return ic.values != nil && len(ic.values) > 0
+}
+
+func (ic *insertClauses) SetVals(vals [][]interface{}) InsertClauses {
+ ret := ic.clone()
+ ret.values = vals
+ return ret
+}
+
+func (ic *insertClauses) ValsAppend(vals [][]interface{}) InsertClauses {
+ ret := ic.clone()
+ newVals := make([][]interface{}, 0, len(ic.values)+len(vals))
+ newVals = append(newVals, ic.values...)
+ newVals = append(newVals, vals...)
+ ret.values = newVals
+ return ret
+}
+
+func (ic *insertClauses) OnConflict() ConflictExpression {
+ return ic.conflict
+}
+
+func (ic *insertClauses) SetOnConflict(expression ConflictExpression) InsertClauses {
+ ret := ic.clone()
+ ret.conflict = expression
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/join.go b/vendor/github.com/doug-martin/goqu/v9/exp/join.go
new file mode 100644
index 000000000..722858ed7
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/join.go
@@ -0,0 +1,139 @@
+package exp
+
+type (
+ joinExpression struct {
+ isConditioned bool
+ // The JoinType
+ joinType JoinType
+ // The table expressions (e.g. LEFT JOIN "my_table", ON (....))
+ table Expression
+ }
+ // Container for all joins within a dataset
+ conditionedJoin struct {
+ joinExpression
+ // The condition to join (e.g. USING("a", "b"), ON("my_table"."fkey" = "other_table"."id")
+ condition JoinCondition
+ }
+ JoinExpressions []JoinExpression
+)
+
+func NewUnConditionedJoinExpression(joinType JoinType, table Expression) JoinExpression {
+ return joinExpression{
+ joinType: joinType,
+ table: table,
+ isConditioned: false,
+ }
+}
+
+func (je joinExpression) Clone() Expression {
+ return je
+}
+
+func (je joinExpression) Expression() Expression {
+ return je
+}
+
+func (je joinExpression) IsConditioned() bool {
+ return je.isConditioned
+}
+
+func (je joinExpression) JoinType() JoinType {
+ return je.joinType
+}
+
+func (je joinExpression) Table() Expression {
+ return je.table
+}
+
+func NewConditionedJoinExpression(joinType JoinType, table Expression, condition JoinCondition) ConditionedJoinExpression {
+ return conditionedJoin{
+ joinExpression: joinExpression{
+ joinType: joinType,
+ table: table,
+ isConditioned: true,
+ },
+ condition: condition,
+ }
+}
+
+func (je conditionedJoin) Clone() Expression {
+ return je
+}
+
+func (je conditionedJoin) Expression() Expression {
+ return je
+}
+
+func (je conditionedJoin) Condition() JoinCondition {
+ return je.condition
+}
+
+func (je conditionedJoin) IsConditionEmpty() bool {
+ return je.condition == nil || je.condition.IsEmpty()
+}
+
+func (jes JoinExpressions) Clone() JoinExpressions {
+ ret := make(JoinExpressions, 0, len(jes))
+ for _, jc := range jes {
+ ret = append(ret, jc.Clone().(JoinExpression))
+ }
+ return ret
+}
+
+type (
+ JoinConditionType int
+ JoinCondition interface {
+ Type() JoinConditionType
+ IsEmpty() bool
+ }
+ JoinOnCondition interface {
+ JoinCondition
+ On() ExpressionList
+ }
+ JoinUsingCondition interface {
+ JoinCondition
+ Using() ColumnListExpression
+ }
+ joinOnCondition struct {
+ on ExpressionList
+ }
+
+ joinUsingCondition struct {
+ using ColumnListExpression
+ }
+)
+
+// Creates a new ON clause to be used within a join
+// ds.Join(I("my_table"), On(I("my_table.fkey").Eq(I("other_table.id")))
+func NewJoinOnCondition(expressions ...Expression) JoinCondition {
+ return joinOnCondition{on: NewExpressionList(AndType, expressions...)}
+}
+
+func (joc joinOnCondition) Type() JoinConditionType {
+ return OnJoinCondType
+}
+
+func (joc joinOnCondition) On() ExpressionList {
+ return joc.on
+}
+
+func (joc joinOnCondition) IsEmpty() bool {
+ return len(joc.on.Expressions()) == 0
+}
+
+// Creates a new USING clause to be used within a join
+func NewJoinUsingCondition(expressions ...interface{}) JoinCondition {
+ return joinUsingCondition{using: NewColumnListExpression(expressions...)}
+}
+
+func (juc joinUsingCondition) Type() JoinConditionType {
+ return UsingJoinCondType
+}
+
+func (juc joinUsingCondition) Using() ColumnListExpression {
+ return juc.using
+}
+
+func (juc joinUsingCondition) IsEmpty() bool {
+ return len(juc.using.Columns()) == 0
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/lateral.go b/vendor/github.com/doug-martin/goqu/v9/exp/lateral.go
new file mode 100644
index 000000000..a3cd01314
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/lateral.go
@@ -0,0 +1,24 @@
+package exp
+
+type (
+ lateral struct {
+ table AppendableExpression
+ }
+)
+
+// Creates a new SQL lateral expression
+// L(From("test")) -> LATERAL (SELECT * FROM "tests")
+func NewLateralExpression(table AppendableExpression) LateralExpression {
+ return lateral{table: table}
+}
+
+func (l lateral) Clone() Expression {
+ return NewLateralExpression(l.table)
+}
+
+func (l lateral) Table() AppendableExpression {
+ return l.table
+}
+
+func (l lateral) Expression() Expression { return l }
+func (l lateral) As(val interface{}) AliasedExpression { return NewAliasExpression(l, val) }
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/literal.go b/vendor/github.com/doug-martin/goqu/v9/exp/literal.go
new file mode 100644
index 000000000..da087751b
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/literal.go
@@ -0,0 +1,80 @@
+package exp
+
+type (
+ literal struct {
+ literal string
+ args []interface{}
+ }
+)
+
+// Creates a new SQL literal with the provided arguments.
+// L("a = 1") -> a = 1
+// You can also you placeholders. All placeholders within a Literal are represented by '?'
+// L("a = ?", "b") -> a = 'b'
+// Literals can also contain placeholders for other expressions
+// L("(? AND ?) OR (?)", I("a").Eq(1), I("b").Eq("b"), I("c").In([]string{"a", "b", "c"}))
+func NewLiteralExpression(sql string, args ...interface{}) LiteralExpression {
+ return literal{literal: sql, args: args}
+}
+
+// Returns a literal for the '*' operator
+func Star() LiteralExpression {
+ return NewLiteralExpression("*")
+}
+
+// Returns a literal for the 'DEFAULT'
+func Default() LiteralExpression {
+ return NewLiteralExpression("DEFAULT")
+}
+
+func (l literal) Clone() Expression {
+ return NewLiteralExpression(l.literal, l.args...)
+}
+
+func (l literal) Literal() string {
+ return l.literal
+}
+
+func (l literal) Args() []interface{} {
+ return l.args
+}
+
+func (l literal) Expression() Expression { return l }
+func (l literal) As(val interface{}) AliasedExpression { return NewAliasExpression(l, val) }
+func (l literal) Eq(val interface{}) BooleanExpression { return eq(l, val) }
+func (l literal) Neq(val interface{}) BooleanExpression { return neq(l, val) }
+func (l literal) Gt(val interface{}) BooleanExpression { return gt(l, val) }
+func (l literal) Gte(val interface{}) BooleanExpression { return gte(l, val) }
+func (l literal) Lt(val interface{}) BooleanExpression { return lt(l, val) }
+func (l literal) Lte(val interface{}) BooleanExpression { return lte(l, val) }
+func (l literal) Asc() OrderedExpression { return asc(l) }
+func (l literal) Desc() OrderedExpression { return desc(l) }
+func (l literal) Between(val RangeVal) RangeExpression { return between(l, val) }
+func (l literal) NotBetween(val RangeVal) RangeExpression { return notBetween(l, val) }
+func (l literal) Like(val interface{}) BooleanExpression { return like(l, val) }
+func (l literal) NotLike(val interface{}) BooleanExpression { return notLike(l, val) }
+func (l literal) ILike(val interface{}) BooleanExpression { return iLike(l, val) }
+func (l literal) NotILike(val interface{}) BooleanExpression { return notILike(l, val) }
+func (l literal) RegexpLike(val interface{}) BooleanExpression { return regexpLike(l, val) }
+func (l literal) RegexpNotLike(val interface{}) BooleanExpression { return regexpNotLike(l, val) }
+func (l literal) RegexpILike(val interface{}) BooleanExpression { return regexpILike(l, val) }
+func (l literal) RegexpNotILike(val interface{}) BooleanExpression { return regexpNotILike(l, val) }
+func (l literal) In(vals ...interface{}) BooleanExpression { return in(l, vals...) }
+func (l literal) NotIn(vals ...interface{}) BooleanExpression { return notIn(l, vals...) }
+func (l literal) Is(val interface{}) BooleanExpression { return is(l, val) }
+func (l literal) IsNot(val interface{}) BooleanExpression { return isNot(l, val) }
+func (l literal) IsNull() BooleanExpression { return is(l, nil) }
+func (l literal) IsNotNull() BooleanExpression { return isNot(l, nil) }
+func (l literal) IsTrue() BooleanExpression { return is(l, true) }
+func (l literal) IsNotTrue() BooleanExpression { return isNot(l, true) }
+func (l literal) IsFalse() BooleanExpression { return is(l, false) }
+func (l literal) IsNotFalse() BooleanExpression { return isNot(l, false) }
+
+func (l literal) BitwiseInversion() BitwiseExpression { return bitwiseInversion(l) }
+func (l literal) BitwiseOr(val interface{}) BitwiseExpression { return bitwiseOr(l, val) }
+func (l literal) BitwiseAnd(val interface{}) BitwiseExpression { return bitwiseAnd(l, val) }
+func (l literal) BitwiseXor(val interface{}) BitwiseExpression { return bitwiseXor(l, val) }
+func (l literal) BitwiseLeftShift(val interface{}) BitwiseExpression { return bitwiseLeftShift(l, val) }
+func (l literal) BitwiseRightShift(val interface{}) BitwiseExpression {
+ return bitwiseRightShift(l, val)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/lock.go b/vendor/github.com/doug-martin/goqu/v9/exp/lock.go
new file mode 100644
index 000000000..9b8bf72e3
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/lock.go
@@ -0,0 +1,48 @@
+package exp
+
+type (
+ LockStrength int
+ WaitOption int
+ Lock interface {
+ Strength() LockStrength
+ WaitOption() WaitOption
+ Of() []IdentifierExpression
+ }
+ lock struct {
+ strength LockStrength
+ waitOption WaitOption
+ of []IdentifierExpression
+ }
+)
+
+const (
+ ForNolock LockStrength = iota
+ ForUpdate
+ ForNoKeyUpdate
+ ForShare
+ ForKeyShare
+
+ Wait WaitOption = iota
+ NoWait
+ SkipLocked
+)
+
+func NewLock(strength LockStrength, option WaitOption, of ...IdentifierExpression) Lock {
+ return lock{
+ strength: strength,
+ waitOption: option,
+ of: of,
+ }
+}
+
+func (l lock) Strength() LockStrength {
+ return l.strength
+}
+
+func (l lock) WaitOption() WaitOption {
+ return l.waitOption
+}
+
+func (l lock) Of() []IdentifierExpression {
+ return l.of
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/order.go b/vendor/github.com/doug-martin/goqu/v9/exp/order.go
new file mode 100644
index 000000000..640f1f665
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/order.go
@@ -0,0 +1,52 @@
+package exp
+
+type (
+ orderedExpression struct {
+ sortExpression Expression
+ direction SortDirection
+ nullSortType NullSortType
+ }
+)
+
+// used internally to create a new SORT_ASC OrderedExpression
+func asc(exp Expression) OrderedExpression {
+ return NewOrderedExpression(exp, AscDir, NoNullsSortType)
+}
+
+// used internally to create a new SORT_DESC OrderedExpression
+func desc(exp Expression) OrderedExpression {
+ return NewOrderedExpression(exp, DescSortDir, NoNullsSortType)
+}
+
+// used internally to create a new SORT_ASC OrderedExpression
+func NewOrderedExpression(exp Expression, direction SortDirection, sortType NullSortType) OrderedExpression {
+ return orderedExpression{sortExpression: exp, direction: direction, nullSortType: sortType}
+}
+
+func (oe orderedExpression) Clone() Expression {
+ return NewOrderedExpression(oe.sortExpression, oe.direction, oe.nullSortType)
+}
+
+func (oe orderedExpression) Expression() Expression {
+ return oe
+}
+
+func (oe orderedExpression) SortExpression() Expression {
+ return oe.sortExpression
+}
+
+func (oe orderedExpression) IsAsc() bool {
+ return oe.direction == AscDir
+}
+
+func (oe orderedExpression) NullSortType() NullSortType {
+ return oe.nullSortType
+}
+
+func (oe orderedExpression) NullsFirst() OrderedExpression {
+ return NewOrderedExpression(oe.sortExpression, oe.direction, NullsFirstSortType)
+}
+
+func (oe orderedExpression) NullsLast() OrderedExpression {
+ return NewOrderedExpression(oe.sortExpression, oe.direction, NullsLastSortType)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/range.go b/vendor/github.com/doug-martin/goqu/v9/exp/range.go
new file mode 100644
index 000000000..be167eed1
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/range.go
@@ -0,0 +1,61 @@
+package exp
+
+type (
+ ranged struct {
+ lhs Expression
+ rhs RangeVal
+ op RangeOperation
+ }
+ rangeVal struct {
+ start interface{}
+ end interface{}
+ }
+)
+
+// used internally to create an BETWEEN comparison RangeExpression
+func between(lhs Expression, rhs RangeVal) RangeExpression {
+ return NewRangeExpression(BetweenOp, lhs, rhs)
+}
+
+// used internally to create an NOT BETWEEN comparison RangeExpression
+func notBetween(lhs Expression, rhs RangeVal) RangeExpression {
+ return NewRangeExpression(NotBetweenOp, lhs, rhs)
+}
+
+func NewRangeExpression(op RangeOperation, lhs Expression, rhs RangeVal) RangeExpression {
+ return ranged{op: op, lhs: lhs, rhs: rhs}
+}
+
+func (r ranged) Clone() Expression {
+ return NewRangeExpression(r.op, r.lhs.Clone(), r.rhs)
+}
+
+func (r ranged) Expression() Expression {
+ return r
+}
+
+func (r ranged) RHS() RangeVal {
+ return r.rhs
+}
+
+func (r ranged) LHS() Expression {
+ return r.lhs
+}
+
+func (r ranged) Op() RangeOperation {
+ return r.op
+}
+
+// Creates a new Range to be used with a Between expression
+// exp.C("col").Between(exp.Range(1, 10))
+func NewRangeVal(start, end interface{}) RangeVal {
+ return rangeVal{start: start, end: end}
+}
+
+func (rv rangeVal) Start() interface{} {
+ return rv.start
+}
+
+func (rv rangeVal) End() interface{} {
+ return rv.end
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/record.go b/vendor/github.com/doug-martin/goqu/v9/exp/record.go
new file mode 100644
index 000000000..80b99ae03
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/record.go
@@ -0,0 +1,59 @@
+package exp
+
+import (
+ "reflect"
+ "sort"
+
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+// Alternative to writing map[string]interface{}. Can be used for Inserts, Updates or Deletes
+type Record map[string]interface{}
+
+func (r Record) Cols() []string {
+ cols := make([]string, 0, len(r))
+ for col := range r {
+ cols = append(cols, col)
+ }
+ sort.Strings(cols)
+ return cols
+}
+
+func NewRecordFromStruct(i interface{}, forInsert, forUpdate bool) (r Record, err error) {
+ value := reflect.ValueOf(i)
+ if value.IsValid() {
+ cm, err := util.GetColumnMap(value.Interface())
+ if err != nil {
+ return nil, err
+ }
+ cols := cm.Cols()
+ r = make(map[string]interface{}, len(cols))
+ for _, col := range cols {
+ f := cm[col]
+ if !shouldSkipField(f, forInsert, forUpdate) {
+ if ok, fieldVal := getFieldValue(value, f); ok {
+ r[f.ColumnName] = fieldVal
+ }
+ }
+ }
+ }
+ return
+}
+
+func shouldSkipField(f util.ColumnData, forInsert, forUpdate bool) bool {
+ shouldSkipInsert := forInsert && !f.ShouldInsert
+ shouldSkipUpdate := forUpdate && !f.ShouldUpdate
+ return shouldSkipInsert || shouldSkipUpdate
+}
+
+func getFieldValue(val reflect.Value, f util.ColumnData) (ok bool, fieldVal interface{}) {
+ if v, isAvailable := util.SafeGetFieldByIndex(val, f.FieldIndex); !isAvailable {
+ return false, nil
+ } else if f.DefaultIfEmpty && util.IsEmptyValue(v) {
+ return true, Default()
+ } else if v.IsValid() {
+ return true, v.Interface()
+ } else {
+ return true, reflect.Zero(f.GoType).Interface()
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/select_clauses.go b/vendor/github.com/doug-martin/goqu/v9/exp/select_clauses.go
new file mode 100644
index 000000000..f802a88b7
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/select_clauses.go
@@ -0,0 +1,379 @@
+package exp
+
+type (
+ SelectClauses interface {
+ HasSources() bool
+ IsDefaultSelect() bool
+ clone() *selectClauses
+
+ Select() ColumnListExpression
+ SelectAppend(cl ColumnListExpression) SelectClauses
+ SetSelect(cl ColumnListExpression) SelectClauses
+
+ Distinct() ColumnListExpression
+ SetDistinct(cle ColumnListExpression) SelectClauses
+
+ From() ColumnListExpression
+ SetFrom(cl ColumnListExpression) SelectClauses
+
+ HasAlias() bool
+ Alias() IdentifierExpression
+ SetAlias(ie IdentifierExpression) SelectClauses
+
+ Joins() JoinExpressions
+ JoinsAppend(jc JoinExpression) SelectClauses
+
+ Where() ExpressionList
+ ClearWhere() SelectClauses
+ WhereAppend(expressions ...Expression) SelectClauses
+
+ Having() ExpressionList
+ ClearHaving() SelectClauses
+ HavingAppend(expressions ...Expression) SelectClauses
+
+ Order() ColumnListExpression
+ HasOrder() bool
+ ClearOrder() SelectClauses
+ SetOrder(oes ...OrderedExpression) SelectClauses
+ OrderAppend(...OrderedExpression) SelectClauses
+ OrderPrepend(...OrderedExpression) SelectClauses
+
+ GroupBy() ColumnListExpression
+ SetGroupBy(cl ColumnListExpression) SelectClauses
+ GroupByAppend(cl ColumnListExpression) SelectClauses
+
+ Limit() interface{}
+ HasLimit() bool
+ ClearLimit() SelectClauses
+ SetLimit(limit interface{}) SelectClauses
+
+ Offset() uint
+ ClearOffset() SelectClauses
+ SetOffset(offset uint) SelectClauses
+
+ Compounds() []CompoundExpression
+ CompoundsAppend(ce CompoundExpression) SelectClauses
+
+ Lock() Lock
+ SetLock(l Lock) SelectClauses
+
+ CommonTables() []CommonTableExpression
+ CommonTablesAppend(cte CommonTableExpression) SelectClauses
+
+ Windows() []WindowExpression
+ SetWindows(ws []WindowExpression) SelectClauses
+ WindowsAppend(ws ...WindowExpression) SelectClauses
+ ClearWindows() SelectClauses
+ }
+ selectClauses struct {
+ commonTables []CommonTableExpression
+ selectColumns ColumnListExpression
+ distinct ColumnListExpression
+ from ColumnListExpression
+ joins JoinExpressions
+ where ExpressionList
+ alias IdentifierExpression
+ groupBy ColumnListExpression
+ having ExpressionList
+ order ColumnListExpression
+ limit interface{}
+ offset uint
+ compounds []CompoundExpression
+ lock Lock
+ windows []WindowExpression
+ }
+)
+
+func NewSelectClauses() SelectClauses {
+ return &selectClauses{
+ selectColumns: NewColumnListExpression(Star()),
+ }
+}
+
+func (c *selectClauses) HasSources() bool {
+ return c.from != nil && len(c.from.Columns()) > 0
+}
+
+func (c *selectClauses) IsDefaultSelect() bool {
+ ret := false
+ if c.selectColumns != nil {
+ selects := c.selectColumns.Columns()
+ if len(selects) == 1 {
+ if l, ok := selects[0].(LiteralExpression); ok && l.Literal() == "*" {
+ ret = true
+ }
+ }
+ }
+ return ret
+}
+
+func (c *selectClauses) clone() *selectClauses {
+ return &selectClauses{
+ commonTables: c.commonTables,
+ selectColumns: c.selectColumns,
+ distinct: c.distinct,
+ from: c.from,
+ joins: c.joins[0:len(c.joins):len(c.joins)],
+ where: c.where,
+ alias: c.alias,
+ groupBy: c.groupBy,
+ having: c.having,
+ order: c.order,
+ limit: c.limit,
+ offset: c.offset,
+ compounds: c.compounds,
+ lock: c.lock,
+ windows: c.windows,
+ }
+}
+
+func (c *selectClauses) CommonTables() []CommonTableExpression {
+ return c.commonTables
+}
+
+func (c *selectClauses) CommonTablesAppend(cte CommonTableExpression) SelectClauses {
+ ret := c.clone()
+ ret.commonTables = append(ret.commonTables, cte)
+ return ret
+}
+
+func (c *selectClauses) Select() ColumnListExpression {
+ return c.selectColumns
+}
+
+func (c *selectClauses) SelectAppend(cl ColumnListExpression) SelectClauses {
+ ret := c.clone()
+ ret.selectColumns = ret.selectColumns.Append(cl.Columns()...)
+ return ret
+}
+
+func (c *selectClauses) SetSelect(cl ColumnListExpression) SelectClauses {
+ ret := c.clone()
+ ret.selectColumns = cl
+ return ret
+}
+
+func (c *selectClauses) Distinct() ColumnListExpression {
+ return c.distinct
+}
+
+func (c *selectClauses) SetDistinct(cle ColumnListExpression) SelectClauses {
+ ret := c.clone()
+ ret.distinct = cle
+ return ret
+}
+
+func (c *selectClauses) From() ColumnListExpression {
+ return c.from
+}
+
+func (c *selectClauses) SetFrom(cl ColumnListExpression) SelectClauses {
+ ret := c.clone()
+ ret.from = cl
+ return ret
+}
+
+func (c *selectClauses) HasAlias() bool {
+ return c.alias != nil
+}
+
+func (c *selectClauses) Alias() IdentifierExpression {
+ return c.alias
+}
+
+func (c *selectClauses) SetAlias(ie IdentifierExpression) SelectClauses {
+ ret := c.clone()
+ ret.alias = ie
+ return ret
+}
+
+func (c *selectClauses) Joins() JoinExpressions {
+ return c.joins
+}
+
+func (c *selectClauses) JoinsAppend(jc JoinExpression) SelectClauses {
+ ret := c.clone()
+ ret.joins = append(ret.joins, jc)
+ return ret
+}
+
+func (c *selectClauses) Where() ExpressionList {
+ return c.where
+}
+
+func (c *selectClauses) ClearWhere() SelectClauses {
+ ret := c.clone()
+ ret.where = nil
+ return ret
+}
+
+func (c *selectClauses) WhereAppend(expressions ...Expression) SelectClauses {
+ if len(expressions) == 0 {
+ return c
+ }
+ ret := c.clone()
+ if ret.where == nil {
+ ret.where = NewExpressionList(AndType, expressions...)
+ } else {
+ ret.where = ret.where.Append(expressions...)
+ }
+ return ret
+}
+
+func (c *selectClauses) Having() ExpressionList {
+ return c.having
+}
+
+func (c *selectClauses) ClearHaving() SelectClauses {
+ ret := c.clone()
+ ret.having = nil
+ return ret
+}
+
+func (c *selectClauses) HavingAppend(expressions ...Expression) SelectClauses {
+ if len(expressions) == 0 {
+ return c
+ }
+ ret := c.clone()
+ if ret.having == nil {
+ ret.having = NewExpressionList(AndType, expressions...)
+ } else {
+ ret.having = ret.having.Append(expressions...)
+ }
+ return ret
+}
+
+func (c *selectClauses) Lock() Lock {
+ return c.lock
+}
+
+func (c *selectClauses) SetLock(l Lock) SelectClauses {
+ ret := c.clone()
+ ret.lock = l
+ return ret
+}
+
+func (c *selectClauses) Order() ColumnListExpression {
+ return c.order
+}
+
+func (c *selectClauses) HasOrder() bool {
+ return c.order != nil
+}
+
+func (c *selectClauses) ClearOrder() SelectClauses {
+ ret := c.clone()
+ ret.order = nil
+ return ret
+}
+
+func (c *selectClauses) SetOrder(oes ...OrderedExpression) SelectClauses {
+ ret := c.clone()
+ ret.order = NewOrderedColumnList(oes...)
+ return ret
+}
+
+func (c *selectClauses) OrderAppend(oes ...OrderedExpression) SelectClauses {
+ if c.order == nil {
+ return c.SetOrder(oes...)
+ }
+ ret := c.clone()
+ ret.order = ret.order.Append(NewOrderedColumnList(oes...).Columns()...)
+ return ret
+}
+
+func (c *selectClauses) OrderPrepend(oes ...OrderedExpression) SelectClauses {
+ if c.order == nil {
+ return c.SetOrder(oes...)
+ }
+ ret := c.clone()
+ ret.order = NewOrderedColumnList(oes...).Append(ret.order.Columns()...)
+ return ret
+}
+
+func (c *selectClauses) GroupBy() ColumnListExpression {
+ return c.groupBy
+}
+
+func (c *selectClauses) GroupByAppend(cl ColumnListExpression) SelectClauses {
+ if c.groupBy == nil {
+ return c.SetGroupBy(cl)
+ }
+ ret := c.clone()
+ ret.groupBy = ret.groupBy.Append(cl.Columns()...)
+ return ret
+}
+
+func (c *selectClauses) SetGroupBy(cl ColumnListExpression) SelectClauses {
+ ret := c.clone()
+ ret.groupBy = cl
+ return ret
+}
+
+func (c *selectClauses) Limit() interface{} {
+ return c.limit
+}
+
+func (c *selectClauses) HasLimit() bool {
+ return c.limit != nil
+}
+
+func (c *selectClauses) ClearLimit() SelectClauses {
+ ret := c.clone()
+ ret.limit = nil
+ return ret
+}
+
+func (c *selectClauses) SetLimit(limit interface{}) SelectClauses {
+ ret := c.clone()
+ ret.limit = limit
+ return ret
+}
+
+func (c *selectClauses) Offset() uint {
+ return c.offset
+}
+
+func (c *selectClauses) ClearOffset() SelectClauses {
+ ret := c.clone()
+ ret.offset = 0
+ return ret
+}
+
+func (c *selectClauses) SetOffset(offset uint) SelectClauses {
+ ret := c.clone()
+ ret.offset = offset
+ return ret
+}
+
+func (c *selectClauses) Compounds() []CompoundExpression {
+ return c.compounds
+}
+
+func (c *selectClauses) CompoundsAppend(ce CompoundExpression) SelectClauses {
+ ret := c.clone()
+ ret.compounds = append(ret.compounds, ce)
+ return ret
+}
+
+func (c *selectClauses) Windows() []WindowExpression {
+ return c.windows
+}
+
+func (c *selectClauses) SetWindows(ws []WindowExpression) SelectClauses {
+ ret := c.clone()
+ ret.windows = ws
+ return ret
+}
+
+func (c *selectClauses) WindowsAppend(ws ...WindowExpression) SelectClauses {
+ ret := c.clone()
+ ret.windows = append(ret.windows, ws...)
+ return ret
+}
+
+func (c *selectClauses) ClearWindows() SelectClauses {
+ ret := c.clone()
+ ret.windows = nil
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/truncate.go b/vendor/github.com/doug-martin/goqu/v9/exp/truncate.go
new file mode 100644
index 000000000..1486a0036
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/truncate.go
@@ -0,0 +1,11 @@
+package exp
+
+// Options to use when generating a TRUNCATE statement
+type TruncateOptions struct {
+ // Set to true to add CASCADE to the TRUNCATE statement
+ Cascade bool
+ // Set to true to add RESTRICT to the TRUNCATE statement
+ Restrict bool
+ // Set to true to specify IDENTITY options, (e.g. RESTART, CONTINUE) to the TRUNCATE statement
+ Identity string
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/truncate_clauses.go b/vendor/github.com/doug-martin/goqu/v9/exp/truncate_clauses.go
new file mode 100644
index 000000000..2b3bd8b59
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/truncate_clauses.go
@@ -0,0 +1,50 @@
+package exp
+
+type (
+ TruncateClauses interface {
+ HasTable() bool
+ clone() *truncateClauses
+
+ Table() ColumnListExpression
+ SetTable(tables ColumnListExpression) TruncateClauses
+
+ Options() TruncateOptions
+ SetOptions(opts TruncateOptions) TruncateClauses
+ }
+ truncateClauses struct {
+ tables ColumnListExpression
+ options TruncateOptions
+ }
+)
+
+func NewTruncateClauses() TruncateClauses {
+ return &truncateClauses{}
+}
+
+func (tc *truncateClauses) HasTable() bool {
+ return tc.tables != nil
+}
+
+func (tc *truncateClauses) clone() *truncateClauses {
+ return &truncateClauses{
+ tables: tc.tables,
+ }
+}
+
+func (tc *truncateClauses) Table() ColumnListExpression {
+ return tc.tables
+}
+func (tc *truncateClauses) SetTable(tables ColumnListExpression) TruncateClauses {
+ ret := tc.clone()
+ ret.tables = tables
+ return ret
+}
+
+func (tc *truncateClauses) Options() TruncateOptions {
+ return tc.options
+}
+func (tc *truncateClauses) SetOptions(opts TruncateOptions) TruncateClauses {
+ ret := tc.clone()
+ ret.options = opts
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/update.go b/vendor/github.com/doug-martin/goqu/v9/exp/update.go
new file mode 100644
index 000000000..da9b19877
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/update.go
@@ -0,0 +1,69 @@
+package exp
+
+import (
+ "reflect"
+ "sort"
+
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+type (
+ update struct {
+ col IdentifierExpression
+ val interface{}
+ }
+)
+
+func set(col IdentifierExpression, val interface{}) UpdateExpression {
+ return update{col: col, val: val}
+}
+
+func NewUpdateExpressions(update interface{}) (updates []UpdateExpression, err error) {
+ if u, ok := update.(UpdateExpression); ok {
+ updates = append(updates, u)
+ return updates, nil
+ }
+ updateValue := reflect.Indirect(reflect.ValueOf(update))
+ switch updateValue.Kind() {
+ case reflect.Map:
+ keys := util.ValueSlice(updateValue.MapKeys())
+ sort.Sort(keys)
+ for _, key := range keys {
+ updates = append(updates, ParseIdentifier(key.String()).Set(updateValue.MapIndex(key).Interface()))
+ }
+ case reflect.Struct:
+ return getUpdateExpressionsStruct(updateValue)
+ default:
+ return nil, errors.New("unsupported update interface type %+v", updateValue.Type())
+ }
+ return updates, nil
+}
+
+func getUpdateExpressionsStruct(value reflect.Value) (updates []UpdateExpression, err error) {
+ r, err := NewRecordFromStruct(value.Interface(), false, true)
+ if err != nil {
+ return updates, err
+ }
+ cols := r.Cols()
+ for _, col := range cols {
+ updates = append(updates, ParseIdentifier(col).Set(r[col]))
+ }
+ return updates, nil
+}
+
+func (u update) Expression() Expression {
+ return u
+}
+
+func (u update) Clone() Expression {
+ return update{col: u.col.Clone().(IdentifierExpression), val: u.val}
+}
+
+func (u update) Col() IdentifierExpression {
+ return u.col
+}
+
+func (u update) Val() interface{} {
+ return u.val
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/update_clauses.go b/vendor/github.com/doug-martin/goqu/v9/exp/update_clauses.go
new file mode 100644
index 000000000..562ca8dc1
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/update_clauses.go
@@ -0,0 +1,216 @@
+package exp
+
+type (
+ UpdateClauses interface {
+ HasTable() bool
+ clone() *updateClauses
+
+ CommonTables() []CommonTableExpression
+ CommonTablesAppend(cte CommonTableExpression) UpdateClauses
+
+ Table() Expression
+ SetTable(table Expression) UpdateClauses
+
+ SetValues() interface{}
+ HasSetValues() bool
+ SetSetValues(values interface{}) UpdateClauses
+
+ From() ColumnListExpression
+ HasFrom() bool
+ SetFrom(tables ColumnListExpression) UpdateClauses
+
+ Where() ExpressionList
+ ClearWhere() UpdateClauses
+ WhereAppend(expressions ...Expression) UpdateClauses
+
+ Order() ColumnListExpression
+ HasOrder() bool
+ ClearOrder() UpdateClauses
+ SetOrder(oes ...OrderedExpression) UpdateClauses
+ OrderAppend(...OrderedExpression) UpdateClauses
+ OrderPrepend(...OrderedExpression) UpdateClauses
+
+ Limit() interface{}
+ HasLimit() bool
+ ClearLimit() UpdateClauses
+ SetLimit(limit interface{}) UpdateClauses
+
+ Returning() ColumnListExpression
+ HasReturning() bool
+ SetReturning(cl ColumnListExpression) UpdateClauses
+ }
+ updateClauses struct {
+ commonTables []CommonTableExpression
+ table Expression
+ setValues interface{}
+ from ColumnListExpression
+ where ExpressionList
+ order ColumnListExpression
+ limit interface{}
+ returning ColumnListExpression
+ }
+)
+
+func NewUpdateClauses() UpdateClauses {
+ return &updateClauses{}
+}
+
+func (uc *updateClauses) HasTable() bool {
+ return uc.table != nil
+}
+
+func (uc *updateClauses) clone() *updateClauses {
+ return &updateClauses{
+ commonTables: uc.commonTables,
+ table: uc.table,
+ setValues: uc.setValues,
+ from: uc.from,
+ where: uc.where,
+ order: uc.order,
+ limit: uc.limit,
+ returning: uc.returning,
+ }
+}
+
+func (uc *updateClauses) CommonTables() []CommonTableExpression {
+ return uc.commonTables
+}
+
+func (uc *updateClauses) CommonTablesAppend(cte CommonTableExpression) UpdateClauses {
+ ret := uc.clone()
+ ret.commonTables = append(ret.commonTables, cte)
+ return ret
+}
+
+func (uc *updateClauses) Table() Expression {
+ return uc.table
+}
+
+func (uc *updateClauses) SetTable(table Expression) UpdateClauses {
+ ret := uc.clone()
+ ret.table = table
+ return ret
+}
+
+func (uc *updateClauses) SetValues() interface{} {
+ return uc.setValues
+}
+
+func (uc *updateClauses) HasSetValues() bool {
+ return uc.setValues != nil
+}
+
+func (uc *updateClauses) SetSetValues(values interface{}) UpdateClauses {
+ ret := uc.clone()
+ ret.setValues = values
+ return ret
+}
+
+func (uc *updateClauses) From() ColumnListExpression {
+ return uc.from
+}
+
+func (uc *updateClauses) HasFrom() bool {
+ return uc.from != nil && !uc.from.IsEmpty()
+}
+
+func (uc *updateClauses) SetFrom(from ColumnListExpression) UpdateClauses {
+ ret := uc.clone()
+ ret.from = from
+ return ret
+}
+
+func (uc *updateClauses) Where() ExpressionList {
+ return uc.where
+}
+
+func (uc *updateClauses) ClearWhere() UpdateClauses {
+ ret := uc.clone()
+ ret.where = nil
+ return ret
+}
+
+func (uc *updateClauses) WhereAppend(expressions ...Expression) UpdateClauses {
+ if len(expressions) == 0 {
+ return uc
+ }
+ ret := uc.clone()
+ if ret.where == nil {
+ ret.where = NewExpressionList(AndType, expressions...)
+ } else {
+ ret.where = ret.where.Append(expressions...)
+ }
+ return ret
+}
+
+func (uc *updateClauses) Order() ColumnListExpression {
+ return uc.order
+}
+
+func (uc *updateClauses) HasOrder() bool {
+ return uc.order != nil
+}
+
+func (uc *updateClauses) ClearOrder() UpdateClauses {
+ ret := uc.clone()
+ ret.order = nil
+ return ret
+}
+
+func (uc *updateClauses) SetOrder(oes ...OrderedExpression) UpdateClauses {
+ ret := uc.clone()
+ ret.order = NewOrderedColumnList(oes...)
+ return ret
+}
+
+func (uc *updateClauses) OrderAppend(oes ...OrderedExpression) UpdateClauses {
+ if uc.order == nil {
+ return uc.SetOrder(oes...)
+ }
+ ret := uc.clone()
+ ret.order = ret.order.Append(NewOrderedColumnList(oes...).Columns()...)
+ return ret
+}
+
+func (uc *updateClauses) OrderPrepend(oes ...OrderedExpression) UpdateClauses {
+ if uc.order == nil {
+ return uc.SetOrder(oes...)
+ }
+ ret := uc.clone()
+ ret.order = NewOrderedColumnList(oes...).Append(ret.order.Columns()...)
+ return ret
+}
+
+func (uc *updateClauses) Limit() interface{} {
+ return uc.limit
+}
+
+func (uc *updateClauses) HasLimit() bool {
+ return uc.limit != nil
+}
+
+func (uc *updateClauses) ClearLimit() UpdateClauses {
+ ret := uc.clone()
+ ret.limit = nil
+ return ret
+}
+
+func (uc *updateClauses) SetLimit(limit interface{}) UpdateClauses {
+ ret := uc.clone()
+ ret.limit = limit
+ return ret
+}
+
+func (uc *updateClauses) Returning() ColumnListExpression {
+ return uc.returning
+}
+
+func (uc *updateClauses) HasReturning() bool {
+ return uc.returning != nil && !uc.returning.IsEmpty()
+}
+
+func (uc *updateClauses) SetReturning(cl ColumnListExpression) UpdateClauses {
+ ret := uc.clone()
+ ret.returning = cl
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/window.go b/vendor/github.com/doug-martin/goqu/v9/exp/window.go
new file mode 100644
index 000000000..a33178a03
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/window.go
@@ -0,0 +1,90 @@
+package exp
+
+type sqlWindowExpression struct {
+ name IdentifierExpression
+ parent IdentifierExpression
+ partitionCols ColumnListExpression
+ orderCols ColumnListExpression
+}
+
+func NewWindowExpression(window, parent IdentifierExpression, partitionCols, orderCols ColumnListExpression) WindowExpression {
+ if partitionCols == nil {
+ partitionCols = NewColumnListExpression()
+ }
+ if orderCols == nil {
+ orderCols = NewColumnListExpression()
+ }
+ return sqlWindowExpression{
+ name: window,
+ parent: parent,
+ partitionCols: partitionCols,
+ orderCols: orderCols,
+ }
+}
+
+func (we sqlWindowExpression) clone() sqlWindowExpression {
+ return sqlWindowExpression{
+ name: we.name,
+ parent: we.parent,
+ partitionCols: we.partitionCols.Clone().(ColumnListExpression),
+ orderCols: we.orderCols.Clone().(ColumnListExpression),
+ }
+}
+
+func (we sqlWindowExpression) Clone() Expression {
+ return we.clone()
+}
+
+func (we sqlWindowExpression) Expression() Expression {
+ return we
+}
+
+func (we sqlWindowExpression) Name() IdentifierExpression {
+ return we.name
+}
+
+func (we sqlWindowExpression) HasName() bool {
+ return we.name != nil
+}
+
+func (we sqlWindowExpression) Parent() IdentifierExpression {
+ return we.parent
+}
+
+func (we sqlWindowExpression) HasParent() bool {
+ return we.parent != nil
+}
+
+func (we sqlWindowExpression) PartitionCols() ColumnListExpression {
+ return we.partitionCols
+}
+
+func (we sqlWindowExpression) HasPartitionBy() bool {
+ return we.partitionCols != nil && !we.partitionCols.IsEmpty()
+}
+
+func (we sqlWindowExpression) OrderCols() ColumnListExpression {
+ return we.orderCols
+}
+
+func (we sqlWindowExpression) HasOrder() bool {
+ return we.orderCols != nil && !we.orderCols.IsEmpty()
+}
+
+func (we sqlWindowExpression) PartitionBy(cols ...interface{}) WindowExpression {
+ ret := we.clone()
+ ret.partitionCols = NewColumnListExpression(cols...)
+ return ret
+}
+
+func (we sqlWindowExpression) OrderBy(cols ...interface{}) WindowExpression {
+ ret := we.clone()
+ ret.orderCols = NewColumnListExpression(cols...)
+ return ret
+}
+
+func (we sqlWindowExpression) Inherit(parent string) WindowExpression {
+ ret := we.clone()
+ ret.parent = ParseIdentifier(parent)
+ return ret
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/exp/window_func.go b/vendor/github.com/doug-martin/goqu/v9/exp/window_func.go
new file mode 100644
index 000000000..d5ae5531a
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/exp/window_func.go
@@ -0,0 +1,124 @@
+package exp
+
+type sqlWindowFunctionExpression struct {
+ fn SQLFunctionExpression
+ windowName IdentifierExpression
+ window WindowExpression
+}
+
+func NewSQLWindowFunctionExpression(
+ fn SQLFunctionExpression,
+ windowName IdentifierExpression,
+ window WindowExpression) SQLWindowFunctionExpression {
+ return sqlWindowFunctionExpression{
+ fn: fn,
+ windowName: windowName,
+ window: window,
+ }
+}
+
+func (swfe sqlWindowFunctionExpression) clone() sqlWindowFunctionExpression {
+ return sqlWindowFunctionExpression{
+ fn: swfe.fn.Clone().(SQLFunctionExpression),
+ windowName: swfe.windowName,
+ window: swfe.window,
+ }
+}
+
+func (swfe sqlWindowFunctionExpression) Clone() Expression {
+ return swfe.clone()
+}
+
+func (swfe sqlWindowFunctionExpression) Expression() Expression {
+ return swfe
+}
+
+func (swfe sqlWindowFunctionExpression) As(val interface{}) AliasedExpression {
+ return NewAliasExpression(swfe, val)
+}
+func (swfe sqlWindowFunctionExpression) Eq(val interface{}) BooleanExpression { return eq(swfe, val) }
+func (swfe sqlWindowFunctionExpression) Neq(val interface{}) BooleanExpression { return neq(swfe, val) }
+func (swfe sqlWindowFunctionExpression) Gt(val interface{}) BooleanExpression { return gt(swfe, val) }
+func (swfe sqlWindowFunctionExpression) Gte(val interface{}) BooleanExpression { return gte(swfe, val) }
+func (swfe sqlWindowFunctionExpression) Lt(val interface{}) BooleanExpression { return lt(swfe, val) }
+func (swfe sqlWindowFunctionExpression) Lte(val interface{}) BooleanExpression { return lte(swfe, val) }
+func (swfe sqlWindowFunctionExpression) Between(val RangeVal) RangeExpression {
+ return between(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) NotBetween(val RangeVal) RangeExpression {
+ return notBetween(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) Like(val interface{}) BooleanExpression {
+ return like(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) NotLike(val interface{}) BooleanExpression {
+ return notLike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) ILike(val interface{}) BooleanExpression {
+ return iLike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) NotILike(val interface{}) BooleanExpression {
+ return notILike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) RegexpLike(val interface{}) BooleanExpression {
+ return regexpLike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) RegexpNotLike(val interface{}) BooleanExpression {
+ return regexpNotLike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) RegexpILike(val interface{}) BooleanExpression {
+ return regexpILike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) RegexpNotILike(val interface{}) BooleanExpression {
+ return regexpNotILike(swfe, val)
+}
+
+func (swfe sqlWindowFunctionExpression) In(vals ...interface{}) BooleanExpression {
+ return in(swfe, vals...)
+}
+
+func (swfe sqlWindowFunctionExpression) NotIn(vals ...interface{}) BooleanExpression {
+ return notIn(swfe, vals...)
+}
+func (swfe sqlWindowFunctionExpression) Is(val interface{}) BooleanExpression { return is(swfe, val) }
+func (swfe sqlWindowFunctionExpression) IsNot(val interface{}) BooleanExpression {
+ return isNot(swfe, val)
+}
+func (swfe sqlWindowFunctionExpression) IsNull() BooleanExpression { return is(swfe, nil) }
+func (swfe sqlWindowFunctionExpression) IsNotNull() BooleanExpression { return isNot(swfe, nil) }
+func (swfe sqlWindowFunctionExpression) IsTrue() BooleanExpression { return is(swfe, true) }
+func (swfe sqlWindowFunctionExpression) IsNotTrue() BooleanExpression { return isNot(swfe, true) }
+func (swfe sqlWindowFunctionExpression) IsFalse() BooleanExpression { return is(swfe, false) }
+func (swfe sqlWindowFunctionExpression) IsNotFalse() BooleanExpression { return isNot(swfe, false) }
+
+func (swfe sqlWindowFunctionExpression) Asc() OrderedExpression { return asc(swfe) }
+func (swfe sqlWindowFunctionExpression) Desc() OrderedExpression { return desc(swfe) }
+
+func (swfe sqlWindowFunctionExpression) Func() SQLFunctionExpression {
+ return swfe.fn
+}
+
+func (swfe sqlWindowFunctionExpression) Window() WindowExpression {
+ return swfe.window
+}
+
+func (swfe sqlWindowFunctionExpression) WindowName() IdentifierExpression {
+ return swfe.windowName
+}
+
+func (swfe sqlWindowFunctionExpression) HasWindow() bool {
+ return swfe.window != nil
+}
+
+func (swfe sqlWindowFunctionExpression) HasWindowName() bool {
+ return swfe.windowName != nil
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/expressions.go b/vendor/github.com/doug-martin/goqu/v9/expressions.go
new file mode 100644
index 000000000..5e5ef86f8
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/expressions.go
@@ -0,0 +1,303 @@
+package goqu
+
+import (
+ "github.com/doug-martin/goqu/v9/exp"
+)
+
+type (
+ Expression = exp.Expression
+ Ex = exp.Ex
+ ExOr = exp.ExOr
+ Op = exp.Op
+ Record = exp.Record
+ Vals = exp.Vals
+ // Options to use when generating a TRUNCATE statement
+ TruncateOptions = exp.TruncateOptions
+)
+
+// emptyWindow is an empty WINDOW clause without name
+var emptyWindow = exp.NewWindowExpression(nil, nil, nil, nil)
+
+const (
+ Wait = exp.Wait
+ NoWait = exp.NoWait
+ SkipLocked = exp.SkipLocked
+)
+
+// Creates a new Casted expression
+// Cast(I("a"), "NUMERIC") -> CAST("a" AS NUMERIC)
+func Cast(e exp.Expression, t string) exp.CastExpression {
+ return exp.NewCastExpression(e, t)
+}
+
+// Creates a conflict struct to be passed to InsertConflict to ignore constraint errors
+// InsertConflict(DoNothing(),...) -> INSERT INTO ... ON CONFLICT DO NOTHING
+func DoNothing() exp.ConflictExpression {
+ return exp.NewDoNothingConflictExpression()
+}
+
+// Creates a ConflictUpdate struct to be passed to InsertConflict
+// Represents a ON CONFLICT DO UPDATE portion of an INSERT statement (ON DUPLICATE KEY UPDATE for mysql)
+//
+// InsertConflict(DoUpdate("target_column", update),...) ->
+// INSERT INTO ... ON CONFLICT DO UPDATE SET a=b
+// InsertConflict(DoUpdate("target_column", update).Where(Ex{"a": 1},...) ->
+// INSERT INTO ... ON CONFLICT DO UPDATE SET a=b WHERE a=1
+func DoUpdate(target string, update interface{}) exp.ConflictUpdateExpression {
+ return exp.NewDoUpdateConflictExpression(target, update)
+}
+
+// A list of expressions that should be ORed together
+// Or(I("a").Eq(10), I("b").Eq(11)) //(("a" = 10) OR ("b" = 11))
+func Or(expressions ...exp.Expression) exp.ExpressionList {
+ return exp.NewExpressionList(exp.OrType, expressions...)
+}
+
+// A list of expressions that should be ANDed together
+// And(I("a").Eq(10), I("b").Eq(11)) //(("a" = 10) AND ("b" = 11))
+func And(expressions ...exp.Expression) exp.ExpressionList {
+ return exp.NewExpressionList(exp.AndType, expressions...)
+}
+
+// Creates a new SQLFunctionExpression with the given name and arguments
+func Func(name string, args ...interface{}) exp.SQLFunctionExpression {
+ return exp.NewSQLFunctionExpression(name, args...)
+}
+
+// used internally to normalize the column name if passed in as a string it should be turned into an identifier
+func newIdentifierFunc(name string, col interface{}) exp.SQLFunctionExpression {
+ if s, ok := col.(string); ok {
+ col = I(s)
+ }
+ return Func(name, col)
+}
+
+// Creates a new DISTINCT sql function
+// DISTINCT("a") -> DISTINCT("a")
+// DISTINCT(I("a")) -> DISTINCT("a")
+func DISTINCT(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("DISTINCT", col) }
+
+// Creates a new COUNT sql function
+// COUNT("a") -> COUNT("a")
+// COUNT("*") -> COUNT("*")
+// COUNT(I("a")) -> COUNT("a")
+func COUNT(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("COUNT", col) }
+
+// Creates a new MIN sql function
+// MIN("a") -> MIN("a")
+// MIN(I("a")) -> MIN("a")
+func MIN(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("MIN", col) }
+
+// Creates a new MAX sql function
+// MAX("a") -> MAX("a")
+// MAX(I("a")) -> MAX("a")
+func MAX(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("MAX", col) }
+
+// Creates a new AVG sql function
+// AVG("a") -> AVG("a")
+// AVG(I("a")) -> AVG("a")
+func AVG(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("AVG", col) }
+
+// Creates a new FIRST sql function
+// FIRST("a") -> FIRST("a")
+// FIRST(I("a")) -> FIRST("a")
+func FIRST(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("FIRST", col) }
+
+// Creates a new LAST sql function
+// LAST("a") -> LAST("a")
+// LAST(I("a")) -> LAST("a")
+func LAST(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("LAST", col) }
+
+// Creates a new SUM sql function
+// SUM("a") -> SUM("a")
+// SUM(I("a")) -> SUM("a")
+func SUM(col interface{}) exp.SQLFunctionExpression { return newIdentifierFunc("SUM", col) }
+
+// Creates a new COALESCE sql function
+// COALESCE(I("a"), "a") -> COALESCE("a", 'a')
+// COALESCE(I("a"), I("b"), nil) -> COALESCE("a", "b", NULL)
+func COALESCE(vals ...interface{}) exp.SQLFunctionExpression {
+ return Func("COALESCE", vals...)
+}
+
+//nolint:stylecheck,golint // sql function name
+func ROW_NUMBER() exp.SQLFunctionExpression {
+ return Func("ROW_NUMBER")
+}
+
+func RANK() exp.SQLFunctionExpression {
+ return Func("RANK")
+}
+
+//nolint:stylecheck,golint // sql function name
+func DENSE_RANK() exp.SQLFunctionExpression {
+ return Func("DENSE_RANK")
+}
+
+//nolint:stylecheck,golint // sql function name
+func PERCENT_RANK() exp.SQLFunctionExpression {
+ return Func("PERCENT_RANK")
+}
+
+//nolint:stylecheck,golint //sql function name
+func CUME_DIST() exp.SQLFunctionExpression {
+ return Func("CUME_DIST")
+}
+
+func NTILE(n int) exp.SQLFunctionExpression {
+ return Func("NTILE", n)
+}
+
+//nolint:stylecheck,golint //sql function name
+func FIRST_VALUE(val interface{}) exp.SQLFunctionExpression {
+ return newIdentifierFunc("FIRST_VALUE", val)
+}
+
+//nolint:stylecheck,golint //sql function name
+func LAST_VALUE(val interface{}) exp.SQLFunctionExpression {
+ return newIdentifierFunc("LAST_VALUE", val)
+}
+
+//nolint:stylecheck,golint //sql function name
+func NTH_VALUE(val interface{}, nth int) exp.SQLFunctionExpression {
+ if s, ok := val.(string); ok {
+ val = I(s)
+ }
+ return Func("NTH_VALUE", val, nth)
+}
+
+// Creates a new Identifier, the generated sql will use adapter specific quoting or '"' by default, this ensures case
+// sensitivity and in certain databases allows for special characters, (e.g. "curr-table", "my table").
+//
+// The identifier will be split by '.'
+//
+// Table and Column example
+// I("table.column") -> "table"."column" //A Column and table
+// Schema table and column
+// I("schema.table.column") -> "schema"."table"."column"
+// Table with star
+// I("table.*") -> "table".*
+func I(ident string) exp.IdentifierExpression {
+ return exp.ParseIdentifier(ident)
+}
+
+// Creates a new Column Identifier, the generated sql will use adapter specific quoting or '"' by default, this ensures case
+// sensitivity and in certain databases allows for special characters, (e.g. "curr-table", "my table").
+// An Identifier can represent a one or a combination of schema, table, and/or column.
+// C("column") -> "column" //A Column
+// C("column").Table("table") -> "table"."column" //A Column and table
+// C("column").Table("table").Schema("schema") //Schema table and column
+// C("*") //Also handles the * operator
+func C(col string) exp.IdentifierExpression {
+ return exp.NewIdentifierExpression("", "", col)
+}
+
+// Creates a new Schema Identifier, the generated sql will use adapter specific quoting or '"' by default, this ensures case
+// sensitivity and in certain databases allows for special characters, (e.g. "curr-schema", "my schema").
+// S("schema") -> "schema" //A Schema
+// S("schema").Table("table") -> "schema"."table" //A Schema and table
+// S("schema").Table("table").Col("col") //Schema table and column
+// S("schema").Table("table").Col("*") //Schema table and all columns
+func S(schema string) exp.IdentifierExpression {
+ return exp.NewIdentifierExpression(schema, "", "")
+}
+
+// Creates a new Table Identifier, the generated sql will use adapter specific quoting or '"' by default, this ensures case
+// sensitivity and in certain databases allows for special characters, (e.g. "curr-table", "my table").
+// T("table") -> "table" //A Column
+// T("table").Col("col") -> "table"."column" //A Column and table
+// T("table").Schema("schema").Col("col) -> "schema"."table"."column" //Schema table and column
+// T("table").Schema("schema").Col("*") -> "schema"."table".* //Also handles the * operator
+func T(table string) exp.IdentifierExpression {
+ return exp.NewIdentifierExpression("", table, "")
+}
+
+// Create a new WINDOW clause
+// W() -> ()
+// W().PartitionBy("a") -> (PARTITION BY "a")
+// W().PartitionBy("a").OrderBy("b") -> (PARTITION BY "a" ORDER BY "b")
+// W().PartitionBy("a").OrderBy("b").Inherit("w1") -> ("w1" PARTITION BY "a" ORDER BY "b")
+// W().PartitionBy("a").OrderBy(I("b").Desc()).Inherit("w1") -> ("w1" PARTITION BY "a" ORDER BY "b" DESC)
+// W("w") -> "w" AS ()
+// W("w", "w1") -> "w" AS ("w1")
+// W("w").Inherit("w1") -> "w" AS ("w1")
+// W("w").PartitionBy("a") -> "w" AS (PARTITION BY "a")
+// W("w", "w1").PartitionBy("a") -> "w" AS ("w1" PARTITION BY "a")
+// W("w", "w1").PartitionBy("a").OrderBy("b") -> "w" AS ("w1" PARTITION BY "a" ORDER BY "b")
+func W(ws ...string) exp.WindowExpression {
+ switch len(ws) {
+ case 0:
+ return emptyWindow
+ case 1:
+ return exp.NewWindowExpression(I(ws[0]), nil, nil, nil)
+ default:
+ return exp.NewWindowExpression(I(ws[0]), I(ws[1]), nil, nil)
+ }
+}
+
+// Creates a new ON clause to be used within a join
+// ds.Join(goqu.T("my_table"), goqu.On(
+// goqu.I("my_table.fkey").Eq(goqu.I("other_table.id")),
+// ))
+func On(expressions ...exp.Expression) exp.JoinCondition {
+ return exp.NewJoinOnCondition(expressions...)
+}
+
+// Creates a new USING clause to be used within a join
+// ds.Join(goqu.T("my_table"), goqu.Using("fkey"))
+func Using(columns ...interface{}) exp.JoinCondition {
+ return exp.NewJoinUsingCondition(columns...)
+}
+
+// Creates a new SQL literal with the provided arguments.
+// L("a = 1") -> a = 1
+// You can also you placeholders. All placeholders within a Literal are represented by '?'
+// L("a = ?", "b") -> a = 'b'
+// Literals can also contain placeholders for other expressions
+// L("(? AND ?) OR (?)", I("a").Eq(1), I("b").Eq("b"), I("c").In([]string{"a", "b", "c"}))
+func L(sql string, args ...interface{}) exp.LiteralExpression {
+ return Literal(sql, args...)
+}
+
+// Alias for goqu.L
+func Literal(sql string, args ...interface{}) exp.LiteralExpression {
+ return exp.NewLiteralExpression(sql, args...)
+}
+
+// Create a new SQL value ( alias for goqu.L("?", val) ). The prrimary use case for this would be in selects.
+// See examples.
+func V(val interface{}) exp.LiteralExpression {
+ return exp.NewLiteralExpression("?", val)
+}
+
+// Creates a new Range to be used with a Between expression
+// exp.C("col").Between(exp.Range(1, 10))
+func Range(start, end interface{}) exp.RangeVal {
+ return exp.NewRangeVal(start, end)
+}
+
+// Creates a literal *
+func Star() exp.LiteralExpression { return exp.Star() }
+
+// Returns a literal for DEFAULT sql keyword
+func Default() exp.LiteralExpression {
+ return exp.Default()
+}
+
+func Lateral(table exp.AppendableExpression) exp.LateralExpression {
+ return exp.NewLateralExpression(table)
+}
+
+// Create a new ANY comparison
+func Any(val interface{}) exp.SQLFunctionExpression {
+ return Func("ANY ", val)
+}
+
+// Create a new ALL comparison
+func All(val interface{}) exp.SQLFunctionExpression {
+ return Func("ALL ", val)
+}
+
+func Case() exp.CaseExpression {
+ return exp.NewCaseExpression()
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/go.test.sh b/vendor/github.com/doug-martin/goqu/v9/go.test.sh
new file mode 100644
index 000000000..4d7be372e
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/go.test.sh
@@ -0,0 +1,6 @@
+#!/usr/bin/env bash
+
+set -e
+echo "" > coverage.txt
+
+go test -race -coverprofile=coverage.txt -coverpkg=./... ./...
\ No newline at end of file
diff --git a/vendor/github.com/doug-martin/goqu/v9/goqu.go b/vendor/github.com/doug-martin/goqu/v9/goqu.go
new file mode 100644
index 000000000..a2c0ec285
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/goqu.go
@@ -0,0 +1,86 @@
+/*
+goqu an idiomatch SQL builder, and query package.
+
+ __ _ ___ __ _ _ _
+ / _` |/ _ \ / _` | | | |
+ | (_| | (_) | (_| | |_| |
+ \__, |\___/ \__, |\__,_|
+ |___/ |_|
+
+
+Please see https://github.com/doug-martin/goqu for an introduction to goqu.
+*/
+package goqu
+
+import (
+ "time"
+
+ "github.com/doug-martin/goqu/v9/internal/util"
+ "github.com/doug-martin/goqu/v9/sqlgen"
+)
+
+type DialectWrapper struct {
+ dialect string
+}
+
+// Creates a new DialectWrapper to create goqu.Datasets or goqu.Databases with the specified dialect.
+func Dialect(dialect string) DialectWrapper {
+ return DialectWrapper{dialect: dialect}
+}
+
+// Create a new dataset for creating SELECT sql statements
+func (dw DialectWrapper) From(table ...interface{}) *SelectDataset {
+ return From(table...).WithDialect(dw.dialect)
+}
+
+// Create a new dataset for creating SELECT sql statements
+func (dw DialectWrapper) Select(cols ...interface{}) *SelectDataset {
+ return newDataset(dw.dialect, nil).Select(cols...)
+}
+
+// Create a new dataset for creating UPDATE sql statements
+func (dw DialectWrapper) Update(table interface{}) *UpdateDataset {
+ return Update(table).WithDialect(dw.dialect)
+}
+
+// Create a new dataset for creating INSERT sql statements
+func (dw DialectWrapper) Insert(table interface{}) *InsertDataset {
+ return Insert(table).WithDialect(dw.dialect)
+}
+
+// Create a new dataset for creating DELETE sql statements
+func (dw DialectWrapper) Delete(table interface{}) *DeleteDataset {
+ return Delete(table).WithDialect(dw.dialect)
+}
+
+// Create a new dataset for creating TRUNCATE sql statements
+func (dw DialectWrapper) Truncate(table ...interface{}) *TruncateDataset {
+ return Truncate(table...).WithDialect(dw.dialect)
+}
+
+func (dw DialectWrapper) DB(db SQLDatabase) *Database {
+ return newDatabase(dw.dialect, db)
+}
+
+func New(dialect string, db SQLDatabase) *Database {
+ return newDatabase(dialect, db)
+}
+
+// Set the behavior when encountering struct fields that do not have a db tag.
+// By default this is false; if set to true any field without a db tag will not
+// be targeted by Select or Scan operations.
+func SetIgnoreUntaggedFields(ignore bool) {
+ util.SetIgnoreUntaggedFields(ignore)
+}
+
+// Set the column rename function. This is used for struct fields that do not have a db tag to specify the column name
+// By default all struct fields that do not have a db tag will be converted lowercase
+func SetColumnRenameFunction(renameFunc func(string) string) {
+ util.SetColumnRenameFunction(renameFunc)
+}
+
+// Set the location to use when interpolating time.Time instances. See https://golang.org/pkg/time/#LoadLocation
+// NOTE: This has no effect when using prepared statements.
+func SetTimeLocation(loc *time.Location) {
+ sqlgen.SetTimeLocation(loc)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/insert_dataset.go b/vendor/github.com/doug-martin/goqu/v9/insert_dataset.go
new file mode 100644
index 000000000..5404ee82c
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/insert_dataset.go
@@ -0,0 +1,271 @@
+package goqu
+
+import (
+ "fmt"
+
+ "github.com/doug-martin/goqu/v9/exec"
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type InsertDataset struct {
+ dialect SQLDialect
+ clauses exp.InsertClauses
+ isPrepared prepared
+ queryFactory exec.QueryFactory
+ err error
+}
+
+var ErrUnsupportedIntoType = errors.New("unsupported table type, a string or identifier expression is required")
+
+// used internally by database to create a database with a specific adapter
+func newInsertDataset(d string, queryFactory exec.QueryFactory) *InsertDataset {
+ return &InsertDataset{
+ clauses: exp.NewInsertClauses(),
+ dialect: GetDialect(d),
+ queryFactory: queryFactory,
+ }
+}
+
+// Creates a new InsertDataset for the provided table. Using this method will only allow you
+// to create SQL user Database#From to create an InsertDataset with query capabilities
+func Insert(table interface{}) *InsertDataset {
+ return newInsertDataset("default", nil).Into(table)
+}
+
+// Set the parameter interpolation behavior. See examples
+//
+// prepared: If true the dataset WILL NOT interpolate the parameters.
+func (id *InsertDataset) Prepared(prepared bool) *InsertDataset {
+ ret := id.copy(id.clauses)
+ ret.isPrepared = preparedFromBool(prepared)
+ return ret
+}
+
+func (id *InsertDataset) IsPrepared() bool {
+ return id.isPrepared.Bool()
+}
+
+// Sets the adapter used to serialize values and create the SQL statement
+func (id *InsertDataset) WithDialect(dl string) *InsertDataset {
+ ds := id.copy(id.GetClauses())
+ ds.dialect = GetDialect(dl)
+ return ds
+}
+
+// Returns the current adapter on the dataset
+func (id *InsertDataset) Dialect() SQLDialect {
+ return id.dialect
+}
+
+// Returns the current adapter on the dataset
+func (id *InsertDataset) SetDialect(dialect SQLDialect) *InsertDataset {
+ cd := id.copy(id.GetClauses())
+ cd.dialect = dialect
+ return cd
+}
+
+func (id *InsertDataset) Expression() exp.Expression {
+ return id
+}
+
+// Clones the dataset
+func (id *InsertDataset) Clone() exp.Expression {
+ return id.copy(id.clauses)
+}
+
+// Returns the current clauses on the dataset.
+func (id *InsertDataset) GetClauses() exp.InsertClauses {
+ return id.clauses
+}
+
+// used interally to copy the dataset
+func (id *InsertDataset) copy(clauses exp.InsertClauses) *InsertDataset {
+ return &InsertDataset{
+ dialect: id.dialect,
+ clauses: clauses,
+ isPrepared: id.isPrepared,
+ queryFactory: id.queryFactory,
+ err: id.err,
+ }
+}
+
+// Creates a WITH clause for a common table expression (CTE).
+//
+// The name will be available to SELECT from in the associated query; and can optionally
+// contain a list of column names "name(col1, col2, col3)".
+//
+// The name will refer to the results of the specified subquery.
+func (id *InsertDataset) With(name string, subquery exp.Expression) *InsertDataset {
+ return id.copy(id.clauses.CommonTablesAppend(exp.NewCommonTableExpression(false, name, subquery)))
+}
+
+// Creates a WITH RECURSIVE clause for a common table expression (CTE)
+//
+// The name will be available to SELECT from in the associated query; and must
+// contain a list of column names "name(col1, col2, col3)" for a recursive clause.
+//
+// The name will refer to the results of the specified subquery. The subquery for
+// a recursive query will always end with a UNION or UNION ALL with a clause that
+// refers to the CTE by name.
+func (id *InsertDataset) WithRecursive(name string, subquery exp.Expression) *InsertDataset {
+ return id.copy(id.clauses.CommonTablesAppend(exp.NewCommonTableExpression(true, name, subquery)))
+}
+
+// Sets the table to insert INTO. This return a new dataset with the original table replaced. See examples.
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// Expression: Any valid expression (IdentifierExpression, AliasedExpression, Literal, etc.)
+func (id *InsertDataset) Into(into interface{}) *InsertDataset {
+ switch t := into.(type) {
+ case exp.Expression:
+ return id.copy(id.clauses.SetInto(t))
+ case string:
+ return id.copy(id.clauses.SetInto(exp.ParseIdentifier(t)))
+ default:
+ panic(ErrUnsupportedIntoType)
+ }
+}
+
+// Sets the Columns to insert into
+func (id *InsertDataset) Cols(cols ...interface{}) *InsertDataset {
+ return id.copy(id.clauses.SetCols(exp.NewColumnListExpression(cols...)))
+}
+
+// Clears the Columns to insert into
+func (id *InsertDataset) ClearCols() *InsertDataset {
+ return id.copy(id.clauses.SetCols(nil))
+}
+
+// Adds columns to the current list of columns clause. See examples
+func (id *InsertDataset) ColsAppend(cols ...interface{}) *InsertDataset {
+ return id.copy(id.clauses.ColsAppend(exp.NewColumnListExpression(cols...)))
+}
+
+// Adds a subquery to the insert. See examples.
+func (id *InsertDataset) FromQuery(from exp.AppendableExpression) *InsertDataset {
+ if sds, ok := from.(*SelectDataset); ok {
+ if sds.dialect != GetDialect("default") && id.Dialect() != sds.dialect {
+ panic(
+ fmt.Errorf(
+ "incompatible dialects for INSERT (%q) and SELECT (%q)",
+ id.dialect.Dialect(), sds.dialect.Dialect(),
+ ),
+ )
+ }
+ sds.dialect = id.dialect
+ }
+ return id.copy(id.clauses.SetFrom(from))
+}
+
+// Manually set values to insert See examples.
+func (id *InsertDataset) Vals(vals ...[]interface{}) *InsertDataset {
+ return id.copy(id.clauses.ValsAppend(vals))
+}
+
+// Clears the values. See examples.
+func (id *InsertDataset) ClearVals() *InsertDataset {
+ return id.copy(id.clauses.SetVals(nil))
+}
+
+// Insert rows. Rows can be a map, goqu.Record or struct. See examples.
+func (id *InsertDataset) Rows(rows ...interface{}) *InsertDataset {
+ return id.copy(id.clauses.SetRows(rows))
+}
+
+// Clears the rows for this insert dataset. See examples.
+func (id *InsertDataset) ClearRows() *InsertDataset {
+ return id.copy(id.clauses.SetRows(nil))
+}
+
+// Adds a RETURNING clause to the dataset if the adapter supports it See examples.
+func (id *InsertDataset) Returning(returning ...interface{}) *InsertDataset {
+ return id.copy(id.clauses.SetReturning(exp.NewColumnListExpression(returning...)))
+}
+
+// Adds an (ON CONFLICT/ON DUPLICATE KEY) clause to the dataset if the dialect supports it. See examples.
+func (id *InsertDataset) OnConflict(conflict exp.ConflictExpression) *InsertDataset {
+ return id.copy(id.clauses.SetOnConflict(conflict))
+}
+
+// Clears the on conflict clause. See example
+func (id *InsertDataset) ClearOnConflict() *InsertDataset {
+ return id.OnConflict(nil)
+}
+
+// Get any error that has been set or nil if no error has been set.
+func (id *InsertDataset) Error() error {
+ return id.err
+}
+
+// Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
+// or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
+// track those separately.
+func (id *InsertDataset) SetError(err error) *InsertDataset {
+ if id.err == nil {
+ id.err = err
+ }
+
+ return id
+}
+
+// Generates the default INSERT statement. If Prepared has been called with true then the statement will not be
+// interpolated. See examples. When using structs you may specify a column to be skipped in the insert, (e.g. id) by
+// specifying a goqu tag with `skipinsert`
+// type Item struct{
+// Id uint32 `db:"id" goqu:"skipinsert"`
+// Name string `db:"name"`
+// }
+//
+// rows: variable number arguments of either map[string]interface, Record, struct, or a single slice argument of the
+// accepted types.
+//
+// Errors:
+// * There is no INTO clause
+// * Different row types passed in, all rows must be of the same type
+// * Maps with different numbers of K/V pairs
+// * Rows of different lengths, (i.e. (Record{"name": "a"}, Record{"name": "a", "age": 10})
+// * Error generating SQL
+func (id *InsertDataset) ToSQL() (sql string, params []interface{}, err error) {
+ return id.insertSQLBuilder().ToSQL()
+}
+
+// Appends this Dataset's INSERT statement to the SQLBuilder
+// This is used internally when using inserts in CTEs
+func (id *InsertDataset) AppendSQL(b sb.SQLBuilder) {
+ if id.err != nil {
+ b.SetError(id.err)
+ return
+ }
+ id.dialect.ToInsertSQL(b, id.GetClauses())
+}
+
+func (id *InsertDataset) GetAs() exp.IdentifierExpression {
+ return id.clauses.Alias()
+}
+
+// Sets the alias for this dataset. This is typically used when using a Dataset as MySQL upsert
+func (id *InsertDataset) As(alias string) *InsertDataset {
+ return id.copy(id.clauses.SetAlias(T(alias)))
+}
+
+func (id *InsertDataset) ReturnsColumns() bool {
+ return id.clauses.HasReturning()
+}
+
+// Generates the INSERT sql, and returns an QueryExecutor struct with the sql set to the INSERT statement
+// db.Insert("test").Rows(Record{"name":"Bob"}).Executor().Exec()
+//
+func (id *InsertDataset) Executor() exec.QueryExecutor {
+ return id.queryFactory.FromSQLBuilder(id.insertSQLBuilder())
+}
+
+func (id *InsertDataset) insertSQLBuilder() sb.SQLBuilder {
+ buf := sb.NewSQLBuilder(id.isPrepared.Bool())
+ if id.err != nil {
+ return buf.SetError(id.err)
+ }
+ id.dialect.ToInsertSQL(buf, id.clauses)
+ return buf
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/internal/errors/error.go b/vendor/github.com/doug-martin/goqu/v9/internal/errors/error.go
new file mode 100644
index 000000000..d0cb8072f
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/internal/errors/error.go
@@ -0,0 +1,19 @@
+package errors
+
+import "fmt"
+
+type Error struct {
+ err string
+}
+
+func New(message string, args ...interface{}) error {
+ return Error{err: "goqu: " + fmt.Sprintf(message, args...)}
+}
+
+func NewEncodeError(t interface{}) error {
+ return Error{err: "goqu_encode_error: " + fmt.Sprintf("Unable to encode value %+v", t)}
+}
+
+func (e Error) Error() string {
+ return e.err
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/internal/sb/sql_builder.go b/vendor/github.com/doug-martin/goqu/v9/internal/sb/sql_builder.go
new file mode 100644
index 000000000..e60e4572b
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/internal/sb/sql_builder.go
@@ -0,0 +1,101 @@
+package sb
+
+import (
+ "bytes"
+)
+
+// Builder that is composed of a bytes.Buffer. It is used internally and by adapters to build SQL statements
+type (
+ SQLBuilder interface {
+ Error() error
+ SetError(err error) SQLBuilder
+ WriteArg(i ...interface{}) SQLBuilder
+ Write(p []byte) SQLBuilder
+ WriteStrings(ss ...string) SQLBuilder
+ WriteRunes(r ...rune) SQLBuilder
+ IsPrepared() bool
+ CurrentArgPosition() int
+ ToSQL() (sql string, args []interface{}, err error)
+ }
+ sqlBuilder struct {
+ buf *bytes.Buffer
+ // True if the sql should not be interpolated
+ isPrepared bool
+ // Current Number of arguments, used by adapters that need positional placeholders
+ currentArgPosition int
+ args []interface{}
+ err error
+ }
+)
+
+func NewSQLBuilder(isPrepared bool) SQLBuilder {
+ return &sqlBuilder{
+ buf: &bytes.Buffer{},
+ isPrepared: isPrepared,
+ args: make([]interface{}, 0),
+ currentArgPosition: 1,
+ }
+}
+
+func (b *sqlBuilder) Error() error {
+ return b.err
+}
+
+func (b *sqlBuilder) SetError(err error) SQLBuilder {
+ if b.err == nil {
+ b.err = err
+ }
+ return b
+}
+
+func (b *sqlBuilder) Write(bs []byte) SQLBuilder {
+ if b.err == nil {
+ b.buf.Write(bs)
+ }
+ return b
+}
+
+func (b *sqlBuilder) WriteStrings(ss ...string) SQLBuilder {
+ if b.err == nil {
+ for _, s := range ss {
+ b.buf.WriteString(s)
+ }
+ }
+ return b
+}
+
+func (b *sqlBuilder) WriteRunes(rs ...rune) SQLBuilder {
+ if b.err == nil {
+ for _, r := range rs {
+ b.buf.WriteRune(r)
+ }
+ }
+ return b
+}
+
+// Returns true if the sql is a prepared statement
+func (b *sqlBuilder) IsPrepared() bool {
+ return b.isPrepared
+}
+
+// Returns true if the sql is a prepared statement
+func (b *sqlBuilder) CurrentArgPosition() int {
+ return b.currentArgPosition
+}
+
+// Adds an argument to the builder, used when IsPrepared is false
+func (b *sqlBuilder) WriteArg(i ...interface{}) SQLBuilder {
+ if b.err == nil {
+ b.currentArgPosition += len(i)
+ b.args = append(b.args, i...)
+ }
+ return b
+}
+
+// Returns the sql string, and arguments.
+func (b *sqlBuilder) ToSQL() (sql string, args []interface{}, err error) {
+ if b.err != nil {
+ return sql, args, b.err
+ }
+ return b.buf.String(), b.args, nil
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/internal/tag/tags.go b/vendor/github.com/doug-martin/goqu/v9/internal/tag/tags.go
new file mode 100644
index 000000000..03652e9e4
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/internal/tag/tags.go
@@ -0,0 +1,51 @@
+package tag
+
+import (
+ "reflect"
+ "strings"
+)
+
+// tagOptions is the string following a comma in a struct field's "json"
+// tag, or the empty string. It does not include the leading comma.
+type Options string
+
+func New(tagName string, st reflect.StructTag) Options {
+ return Options(st.Get(tagName))
+}
+
+func (o Options) Values() []string {
+ if string(o) == "" {
+ return []string{}
+ }
+ return strings.Split(string(o), ",")
+}
+
+// Contains reports whether a comma-separated list of options
+// contains a particular substr flag. substr must be surrounded by a
+// string boundary or commas.
+func (o Options) Contains(optionName string) bool {
+ if o.IsEmpty() {
+ return false
+ }
+ values := o.Values()
+ for _, s := range values {
+ if s == optionName {
+ return true
+ }
+ }
+ return false
+}
+
+// Contains reports whether a comma-separated list of options
+// contains a particular substr flag. substr must be surrounded by a
+// string boundary or commas.
+func (o Options) Equals(val string) bool {
+ if len(o) == 0 {
+ return false
+ }
+ return string(o) == val
+}
+
+func (o Options) IsEmpty() bool {
+ return len(o) == 0
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/internal/util/column_map.go b/vendor/github.com/doug-martin/goqu/v9/internal/util/column_map.go
new file mode 100644
index 000000000..b82693419
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/internal/util/column_map.go
@@ -0,0 +1,130 @@
+package util
+
+import (
+ "reflect"
+ "sort"
+ "strings"
+
+ "github.com/doug-martin/goqu/v9/internal/tag"
+)
+
+type (
+ ColumnData struct {
+ ColumnName string
+ FieldIndex []int
+ ShouldInsert bool
+ ShouldUpdate bool
+ DefaultIfEmpty bool
+ GoType reflect.Type
+ }
+ ColumnMap map[string]ColumnData
+)
+
+func newColumnMap(t reflect.Type, fieldIndex []int, prefixes []string) ColumnMap {
+ cm, n := ColumnMap{}, t.NumField()
+ var subColMaps []ColumnMap
+ for i := 0; i < n; i++ {
+ f := t.Field(i)
+ if f.Anonymous && (f.Type.Kind() == reflect.Struct || f.Type.Kind() == reflect.Ptr) {
+ goquTag := tag.New("db", f.Tag)
+ if !goquTag.Contains("-") {
+ subColMaps = append(subColMaps, getStructColumnMap(&f, fieldIndex, goquTag.Values(), prefixes))
+ }
+ } else if f.PkgPath == "" {
+ dbTag := tag.New("db", f.Tag)
+ // if PkgPath is empty then it is an exported field
+ columnName := getColumnName(&f, dbTag)
+ if !shouldIgnoreField(dbTag) {
+ if !implementsScanner(f.Type) {
+ subCm := getStructColumnMap(&f, fieldIndex, []string{columnName}, prefixes)
+ if len(subCm) != 0 {
+ subColMaps = append(subColMaps, subCm)
+ continue
+ }
+ }
+ goquTag := tag.New("goqu", f.Tag)
+ columnName = strings.Join(append(prefixes, columnName), ".")
+ cm[columnName] = newColumnData(&f, columnName, fieldIndex, goquTag)
+ }
+ }
+ }
+ return cm.Merge(subColMaps)
+}
+
+func (cm ColumnMap) Cols() []string {
+ structCols := make([]string, 0, len(cm))
+ for key := range cm {
+ structCols = append(structCols, key)
+ }
+ sort.Strings(structCols)
+ return structCols
+}
+
+func (cm ColumnMap) Merge(colMaps []ColumnMap) ColumnMap {
+ for _, subCm := range colMaps {
+ for key, val := range subCm {
+ if _, ok := cm[key]; !ok {
+ cm[key] = val
+ }
+ }
+ }
+ return cm
+}
+
+func implementsScanner(t reflect.Type) bool {
+ if IsPointer(t.Kind()) {
+ t = t.Elem()
+ }
+ if reflect.PtrTo(t).Implements(scannerType) {
+ return true
+ }
+ if !IsStruct(t.Kind()) {
+ return true
+ }
+
+ return false
+}
+
+func newColumnData(f *reflect.StructField, columnName string, fieldIndex []int, goquTag tag.Options) ColumnData {
+ return ColumnData{
+ ColumnName: columnName,
+ ShouldInsert: !goquTag.Contains(skipInsertTagName),
+ ShouldUpdate: !goquTag.Contains(skipUpdateTagName),
+ DefaultIfEmpty: goquTag.Contains(defaultIfEmptyTagName),
+ FieldIndex: concatFieldIndexes(fieldIndex, f.Index),
+ GoType: f.Type,
+ }
+}
+
+func getStructColumnMap(f *reflect.StructField, fieldIndex []int, fieldNames, prefixes []string) ColumnMap {
+ subFieldIndexes := concatFieldIndexes(fieldIndex, f.Index)
+ subPrefixes := append(prefixes, fieldNames...)
+ if f.Type.Kind() == reflect.Ptr {
+ return newColumnMap(f.Type.Elem(), subFieldIndexes, subPrefixes)
+ }
+ return newColumnMap(f.Type, subFieldIndexes, subPrefixes)
+}
+
+func getColumnName(f *reflect.StructField, dbTag tag.Options) string {
+ if dbTag.IsEmpty() {
+ return columnRenameFunction(f.Name)
+ }
+ return dbTag.Values()[0]
+}
+
+func shouldIgnoreField(dbTag tag.Options) bool {
+ if dbTag.Equals("-") {
+ return true
+ } else if dbTag.IsEmpty() && ignoreUntaggedFields {
+ return true
+ }
+
+ return false
+}
+
+// safely concat two fieldIndex slices into one.
+func concatFieldIndexes(fieldIndexPath, fieldIndex []int) []int {
+ fieldIndexes := make([]int, 0, len(fieldIndexPath)+len(fieldIndex))
+ fieldIndexes = append(fieldIndexes, fieldIndexPath...)
+ return append(fieldIndexes, fieldIndex...)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/internal/util/reflect.go b/vendor/github.com/doug-martin/goqu/v9/internal/util/reflect.go
new file mode 100644
index 000000000..bc18b8bd5
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/internal/util/reflect.go
@@ -0,0 +1,220 @@
+package util
+
+import (
+ "database/sql"
+ "reflect"
+ "strings"
+ "sync"
+
+ "github.com/doug-martin/goqu/v9/internal/errors"
+)
+
+const (
+ skipUpdateTagName = "skipupdate"
+ skipInsertTagName = "skipinsert"
+ defaultIfEmptyTagName = "defaultifempty"
+)
+
+var scannerType = reflect.TypeOf((*sql.Scanner)(nil)).Elem()
+
+func IsUint(k reflect.Kind) bool {
+ return (k == reflect.Uint) ||
+ (k == reflect.Uint8) ||
+ (k == reflect.Uint16) ||
+ (k == reflect.Uint32) ||
+ (k == reflect.Uint64)
+}
+
+func IsInt(k reflect.Kind) bool {
+ return (k == reflect.Int) ||
+ (k == reflect.Int8) ||
+ (k == reflect.Int16) ||
+ (k == reflect.Int32) ||
+ (k == reflect.Int64)
+}
+
+func IsFloat(k reflect.Kind) bool {
+ return (k == reflect.Float32) ||
+ (k == reflect.Float64)
+}
+
+func IsString(k reflect.Kind) bool {
+ return k == reflect.String
+}
+
+func IsBool(k reflect.Kind) bool {
+ return k == reflect.Bool
+}
+
+func IsSlice(k reflect.Kind) bool {
+ return k == reflect.Slice
+}
+
+func IsStruct(k reflect.Kind) bool {
+ return k == reflect.Struct
+}
+
+func IsInvalid(k reflect.Kind) bool {
+ return k == reflect.Invalid
+}
+
+func IsPointer(k reflect.Kind) bool {
+ return k == reflect.Ptr
+}
+
+func IsEmptyValue(v reflect.Value) bool {
+ switch v.Kind() {
+ case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
+ return v.Len() == 0
+ case reflect.Bool:
+ return !v.Bool()
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ return v.Int() == 0
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
+ return v.Uint() == 0
+ case reflect.Float32, reflect.Float64:
+ return v.Float() == 0
+ case reflect.Interface, reflect.Ptr:
+ return v.IsNil()
+ case reflect.Invalid:
+ return true
+ default:
+ return false
+ }
+}
+
+var (
+ structMapCache = make(map[interface{}]ColumnMap)
+ structMapCacheLock = sync.Mutex{}
+)
+
+var (
+ DefaultColumnRenameFunction = strings.ToLower
+ columnRenameFunction = DefaultColumnRenameFunction
+ ignoreUntaggedFields = false
+)
+
+func SetIgnoreUntaggedFields(ignore bool) {
+ // If the value here is changing, reset the struct map cache
+ if ignore != ignoreUntaggedFields {
+ ignoreUntaggedFields = ignore
+
+ structMapCacheLock.Lock()
+ defer structMapCacheLock.Unlock()
+
+ structMapCache = make(map[interface{}]ColumnMap)
+ }
+}
+
+func SetColumnRenameFunction(newFunction func(string) string) {
+ columnRenameFunction = newFunction
+}
+
+// GetSliceElementType returns the type for a slices elements.
+func GetSliceElementType(val reflect.Value) reflect.Type {
+ elemType := val.Type().Elem()
+ if elemType.Kind() == reflect.Ptr {
+ elemType = elemType.Elem()
+ }
+
+ return elemType
+}
+
+// AppendSliceElement will append val to slice. Handles slice of pointers and
+// not pointers. Val needs to be a pointer.
+func AppendSliceElement(slice, val reflect.Value) {
+ if slice.Type().Elem().Kind() == reflect.Ptr {
+ slice.Set(reflect.Append(slice, val))
+ } else {
+ slice.Set(reflect.Append(slice, reflect.Indirect(val)))
+ }
+}
+
+func GetTypeInfo(i interface{}, val reflect.Value) (reflect.Type, reflect.Kind) {
+ var t reflect.Type
+ valKind := val.Kind()
+ if valKind == reflect.Slice {
+ if reflect.ValueOf(i).Kind() == reflect.Ptr {
+ t = reflect.TypeOf(i).Elem().Elem()
+ } else {
+ t = reflect.TypeOf(i).Elem()
+ }
+ if t.Kind() == reflect.Ptr {
+ t = t.Elem()
+ }
+ valKind = t.Kind()
+ } else {
+ t = val.Type()
+ }
+ return t, valKind
+}
+
+func SafeGetFieldByIndex(v reflect.Value, fieldIndex []int) (result reflect.Value, isAvailable bool) {
+ switch len(fieldIndex) {
+ case 0:
+ return v, true
+ case 1:
+ return v.FieldByIndex(fieldIndex), true
+ default:
+ if f := reflect.Indirect(v.Field(fieldIndex[0])); f.IsValid() {
+ return SafeGetFieldByIndex(f, fieldIndex[1:])
+ }
+ }
+ return reflect.ValueOf(nil), false
+}
+
+func SafeSetFieldByIndex(v reflect.Value, fieldIndex []int, src interface{}) (result reflect.Value) {
+ v = reflect.Indirect(v)
+ switch len(fieldIndex) {
+ case 0:
+ return v
+ case 1:
+ f := v.FieldByIndex(fieldIndex)
+ srcVal := reflect.ValueOf(src)
+ f.Set(reflect.Indirect(srcVal))
+ default:
+ f := v.Field(fieldIndex[0])
+ switch f.Kind() {
+ case reflect.Ptr:
+ s := f
+ if f.IsNil() || !f.IsValid() {
+ s = reflect.New(f.Type().Elem())
+ f.Set(s)
+ }
+ SafeSetFieldByIndex(reflect.Indirect(s), fieldIndex[1:], src)
+ case reflect.Struct:
+ SafeSetFieldByIndex(f, fieldIndex[1:], src)
+ default: // use the original value
+ }
+ }
+ return v
+}
+
+type rowData = map[string]interface{}
+
+// AssignStructVals will assign the data from rd to i.
+func AssignStructVals(i interface{}, rd rowData, cm ColumnMap) {
+ val := reflect.Indirect(reflect.ValueOf(i))
+
+ for name, data := range cm {
+ src, ok := rd[name]
+ if ok {
+ SafeSetFieldByIndex(val, data.FieldIndex, src)
+ }
+ }
+}
+
+func GetColumnMap(i interface{}) (ColumnMap, error) {
+ val := reflect.Indirect(reflect.ValueOf(i))
+ t, valKind := GetTypeInfo(i, val)
+ if valKind != reflect.Struct {
+ return nil, errors.New("cannot scan into this type: %v", t) // #nosec
+ }
+
+ structMapCacheLock.Lock()
+ defer structMapCacheLock.Unlock()
+ if _, ok := structMapCache[t]; !ok {
+ structMapCache[t] = newColumnMap(t, []int{}, []string{})
+ }
+ return structMapCache[t], nil
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/internal/util/value_slice.go b/vendor/github.com/doug-martin/goqu/v9/internal/util/value_slice.go
new file mode 100644
index 000000000..b013ed5ee
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/internal/util/value_slice.go
@@ -0,0 +1,33 @@
+package util
+
+import (
+ "fmt"
+ "reflect"
+ "sort"
+ "strings"
+)
+
+type ValueSlice []reflect.Value
+
+func (vs ValueSlice) Len() int { return len(vs) }
+func (vs ValueSlice) Less(i, j int) bool { return vs[i].String() < vs[j].String() }
+func (vs ValueSlice) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
+
+func (vs ValueSlice) Equal(other ValueSlice) bool {
+ sort.Sort(other)
+ for i, key := range vs {
+ if other[i].String() != key.String() {
+ return false
+ }
+ }
+ return true
+}
+
+func (vs ValueSlice) String() string {
+ vals := make([]string, vs.Len())
+ for i, key := range vs {
+ vals[i] = fmt.Sprintf(`"%s"`, key.String())
+ }
+ sort.Strings(vals)
+ return fmt.Sprintf("[%s]", strings.Join(vals, ","))
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/prepared.go b/vendor/github.com/doug-martin/goqu/v9/prepared.go
new file mode 100644
index 000000000..796ce98e9
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/prepared.go
@@ -0,0 +1,48 @@
+package goqu
+
+var (
+ // defaultPrepared is controlled by SetDefaultPrepared
+ defaultPrepared bool
+)
+
+type prepared int
+
+const (
+ // zero value that defers to defaultPrepared
+ preparedNoPreference prepared = iota
+
+ // explicitly enabled via Prepared(true) on a dataset
+ preparedEnabled
+
+ // explicitly disabled via Prepared(false) on a dataset
+ preparedDisabled
+)
+
+// Bool converts the ternary prepared state into a boolean. If the prepared
+// state is preparedNoPreference, the value depends on the last value that
+// SetDefaultPrepared was called with which is false by default.
+func (p prepared) Bool() bool {
+ if p == preparedNoPreference {
+ return defaultPrepared
+ } else if p == preparedEnabled {
+ return true
+ }
+
+ return false
+}
+
+// preparedFromBool converts a bool from e.g. Prepared(true) into a prepared
+// const.
+func preparedFromBool(prepared bool) prepared {
+ if prepared {
+ return preparedEnabled
+ }
+
+ return preparedDisabled
+}
+
+// SetDefaultPrepared controls the default Prepared state of all datasets. If
+// set to true, any new dataset will use prepared queries by default.
+func SetDefaultPrepared(prepared bool) {
+ defaultPrepared = prepared
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/select_dataset.go b/vendor/github.com/doug-martin/goqu/v9/select_dataset.go
new file mode 100644
index 000000000..775c387df
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/select_dataset.go
@@ -0,0 +1,695 @@
+package goqu
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/doug-martin/goqu/v9/exec"
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+// Dataset for creating and/or executing SELECT SQL statements.
+type SelectDataset struct {
+ dialect SQLDialect
+ clauses exp.SelectClauses
+ isPrepared prepared
+ queryFactory exec.QueryFactory
+ err error
+}
+
+var ErrQueryFactoryNotFoundError = errors.New(
+ "unable to execute query did you use goqu.Database#From to create the dataset",
+)
+
+// used internally by database to create a database with a specific adapter
+func newDataset(d string, queryFactory exec.QueryFactory) *SelectDataset {
+ return &SelectDataset{
+ clauses: exp.NewSelectClauses(),
+ dialect: GetDialect(d),
+ queryFactory: queryFactory,
+ }
+}
+
+func From(table ...interface{}) *SelectDataset {
+ return newDataset("default", nil).From(table...)
+}
+
+func Select(cols ...interface{}) *SelectDataset {
+ return newDataset("default", nil).Select(cols...)
+}
+
+// Sets the adapter used to serialize values and create the SQL statement
+func (sd *SelectDataset) WithDialect(dl string) *SelectDataset {
+ ds := sd.copy(sd.GetClauses())
+ ds.dialect = GetDialect(dl)
+ return ds
+}
+
+// Set the parameter interpolation behavior. See examples
+//
+// prepared: If true the dataset WILL NOT interpolate the parameters.
+func (sd *SelectDataset) Prepared(prepared bool) *SelectDataset {
+ ret := sd.copy(sd.clauses)
+ ret.isPrepared = preparedFromBool(prepared)
+ return ret
+}
+
+func (sd *SelectDataset) IsPrepared() bool {
+ return sd.isPrepared.Bool()
+}
+
+// Returns the current adapter on the dataset
+func (sd *SelectDataset) Dialect() SQLDialect {
+ return sd.dialect
+}
+
+// Returns the current adapter on the dataset
+func (sd *SelectDataset) SetDialect(dialect SQLDialect) *SelectDataset {
+ cd := sd.copy(sd.GetClauses())
+ cd.dialect = dialect
+ return cd
+}
+
+func (sd *SelectDataset) Expression() exp.Expression {
+ return sd
+}
+
+// Clones the dataset
+func (sd *SelectDataset) Clone() exp.Expression {
+ return sd.copy(sd.clauses)
+}
+
+// Returns the current clauses on the dataset.
+func (sd *SelectDataset) GetClauses() exp.SelectClauses {
+ return sd.clauses
+}
+
+// used interally to copy the dataset
+func (sd *SelectDataset) copy(clauses exp.SelectClauses) *SelectDataset {
+ return &SelectDataset{
+ dialect: sd.dialect,
+ clauses: clauses,
+ isPrepared: sd.isPrepared,
+ queryFactory: sd.queryFactory,
+ err: sd.err,
+ }
+}
+
+// Creates a new UpdateDataset using the FROM of this dataset. This method will also copy over the `WITH`, `WHERE`,
+// `ORDER , and `LIMIT`
+func (sd *SelectDataset) Update() *UpdateDataset {
+ u := newUpdateDataset(sd.dialect.Dialect(), sd.queryFactory).
+ Prepared(sd.isPrepared.Bool())
+ if sd.clauses.HasSources() {
+ u = u.Table(sd.GetClauses().From().Columns()[0])
+ }
+ c := u.clauses
+ for _, ce := range sd.clauses.CommonTables() {
+ c = c.CommonTablesAppend(ce)
+ }
+ if sd.clauses.Where() != nil {
+ c = c.WhereAppend(sd.clauses.Where())
+ }
+ if sd.clauses.HasLimit() {
+ c = c.SetLimit(sd.clauses.Limit())
+ }
+ if sd.clauses.HasOrder() {
+ for _, oe := range sd.clauses.Order().Columns() {
+ c = c.OrderAppend(oe.(exp.OrderedExpression))
+ }
+ }
+ u.clauses = c
+ return u
+}
+
+// Creates a new InsertDataset using the FROM of this dataset. This method will also copy over the `WITH` clause to the
+// insert.
+func (sd *SelectDataset) Insert() *InsertDataset {
+ i := newInsertDataset(sd.dialect.Dialect(), sd.queryFactory).
+ Prepared(sd.isPrepared.Bool())
+ if sd.clauses.HasSources() {
+ i = i.Into(sd.GetClauses().From().Columns()[0])
+ }
+ c := i.clauses
+ for _, ce := range sd.clauses.CommonTables() {
+ c = c.CommonTablesAppend(ce)
+ }
+ i.clauses = c
+ return i
+}
+
+// Creates a new DeleteDataset using the FROM of this dataset. This method will also copy over the `WITH`, `WHERE`,
+// `ORDER , and `LIMIT`
+func (sd *SelectDataset) Delete() *DeleteDataset {
+ d := newDeleteDataset(sd.dialect.Dialect(), sd.queryFactory).
+ Prepared(sd.isPrepared.Bool())
+ if sd.clauses.HasSources() {
+ d = d.From(sd.clauses.From().Columns()[0])
+ }
+ c := d.clauses
+ for _, ce := range sd.clauses.CommonTables() {
+ c = c.CommonTablesAppend(ce)
+ }
+ if sd.clauses.Where() != nil {
+ c = c.WhereAppend(sd.clauses.Where())
+ }
+ if sd.clauses.HasLimit() {
+ c = c.SetLimit(sd.clauses.Limit())
+ }
+ if sd.clauses.HasOrder() {
+ for _, oe := range sd.clauses.Order().Columns() {
+ c = c.OrderAppend(oe.(exp.OrderedExpression))
+ }
+ }
+ d.clauses = c
+ return d
+}
+
+// Creates a new TruncateDataset using the FROM of this dataset.
+func (sd *SelectDataset) Truncate() *TruncateDataset {
+ td := newTruncateDataset(sd.dialect.Dialect(), sd.queryFactory)
+ if sd.clauses.HasSources() {
+ td = td.Table(sd.clauses.From())
+ }
+ return td
+}
+
+// Creates a WITH clause for a common table expression (CTE).
+//
+// The name will be available to SELECT from in the associated query; and can optionally
+// contain a list of column names "name(col1, col2, col3)".
+//
+// The name will refer to the results of the specified subquery.
+func (sd *SelectDataset) With(name string, subquery exp.Expression) *SelectDataset {
+ return sd.copy(sd.clauses.CommonTablesAppend(exp.NewCommonTableExpression(false, name, subquery)))
+}
+
+// Creates a WITH RECURSIVE clause for a common table expression (CTE)
+//
+// The name will be available to SELECT from in the associated query; and must
+// contain a list of column names "name(col1, col2, col3)" for a recursive clause.
+//
+// The name will refer to the results of the specified subquery. The subquery for
+// a recursive query will always end with a UNION or UNION ALL with a clause that
+// refers to the CTE by name.
+func (sd *SelectDataset) WithRecursive(name string, subquery exp.Expression) *SelectDataset {
+ return sd.copy(sd.clauses.CommonTablesAppend(exp.NewCommonTableExpression(true, name, subquery)))
+}
+
+// Adds columns to the SELECT clause. See examples
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// Dataset: Will use the SQL generated from that Dataset. If the dataset is aliased it will use that alias as the
+// column name.
+// LiteralExpression: (See Literal) Will use the literal SQL
+// SQLFunction: (See Func, MIN, MAX, COUNT....)
+// Struct: If passing in an instance of a struct, we will parse the struct for the column names to select.
+// See examples
+func (sd *SelectDataset) Select(selects ...interface{}) *SelectDataset {
+ if len(selects) == 0 {
+ return sd.ClearSelect()
+ }
+ return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(selects...)))
+}
+
+// Adds columns to the SELECT DISTINCT clause. See examples
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// Dataset: Will use the SQL generated from that Dataset. If the dataset is aliased it will use that alias as the
+// column name.
+// LiteralExpression: (See Literal) Will use the literal SQL
+// SQLFunction: (See Func, MIN, MAX, COUNT....)
+// Struct: If passing in an instance of a struct, we will parse the struct for the column names to select.
+// See examples
+// Deprecated: Use Distinct() instead.
+func (sd *SelectDataset) SelectDistinct(selects ...interface{}) *SelectDataset {
+ if len(selects) == 0 {
+ cleared := sd.ClearSelect()
+ return cleared.copy(cleared.clauses.SetDistinct(nil))
+ }
+ return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(selects...)).SetDistinct(exp.NewColumnListExpression()))
+}
+
+// Resets to SELECT *. If the SelectDistinct or Distinct was used the returned Dataset will have the the dataset set to SELECT *.
+// See examples.
+func (sd *SelectDataset) ClearSelect() *SelectDataset {
+ return sd.copy(sd.clauses.SetSelect(exp.NewColumnListExpression(exp.Star())).SetDistinct(nil))
+}
+
+// Adds columns to the SELECT clause. See examples
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// Dataset: Will use the SQL generated from that Dataset. If the dataset is aliased it will use that alias as the
+// column name.
+// LiteralExpression: (See Literal) Will use the literal SQL
+// SQLFunction: (See Func, MIN, MAX, COUNT....)
+func (sd *SelectDataset) SelectAppend(selects ...interface{}) *SelectDataset {
+ return sd.copy(sd.clauses.SelectAppend(exp.NewColumnListExpression(selects...)))
+}
+
+func (sd *SelectDataset) Distinct(on ...interface{}) *SelectDataset {
+ return sd.copy(sd.clauses.SetDistinct(exp.NewColumnListExpression(on...)))
+}
+
+// Adds a FROM clause. This return a new dataset with the original sources replaced. See examples.
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// Dataset: Will be added as a sub select. If the Dataset is not aliased it will automatically be aliased
+// LiteralExpression: (See Literal) Will use the literal SQL
+func (sd *SelectDataset) From(from ...interface{}) *SelectDataset {
+ var sources []interface{}
+ numSources := 0
+ for _, source := range from {
+ if ds, ok := source.(*SelectDataset); ok && !ds.clauses.HasAlias() {
+ numSources++
+ sources = append(sources, ds.As(fmt.Sprintf("t%d", numSources)))
+ } else {
+ sources = append(sources, source)
+ }
+ }
+ return sd.copy(sd.clauses.SetFrom(exp.NewColumnListExpression(sources...)))
+}
+
+// Returns a new Dataset with the current one as an source. If the current Dataset is not aliased (See Dataset#As) then
+// it will automatically be aliased. See examples.
+func (sd *SelectDataset) FromSelf() *SelectDataset {
+ return sd.copy(exp.NewSelectClauses()).From(sd)
+}
+
+// Alias to InnerJoin. See examples.
+func (sd *SelectDataset) Join(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.InnerJoin(table, condition)
+}
+
+// Adds an INNER JOIN clause. See examples.
+func (sd *SelectDataset) InnerJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.InnerJoinType, table, condition))
+}
+
+// Adds a FULL OUTER JOIN clause. See examples.
+func (sd *SelectDataset) FullOuterJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.FullOuterJoinType, table, condition))
+}
+
+// Adds a RIGHT OUTER JOIN clause. See examples.
+func (sd *SelectDataset) RightOuterJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.RightOuterJoinType, table, condition))
+}
+
+// Adds a LEFT OUTER JOIN clause. See examples.
+func (sd *SelectDataset) LeftOuterJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.LeftOuterJoinType, table, condition))
+}
+
+// Adds a FULL JOIN clause. See examples.
+func (sd *SelectDataset) FullJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.FullJoinType, table, condition))
+}
+
+// Adds a RIGHT JOIN clause. See examples.
+func (sd *SelectDataset) RightJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.RightJoinType, table, condition))
+}
+
+// Adds a LEFT JOIN clause. See examples.
+func (sd *SelectDataset) LeftJoin(table exp.Expression, condition exp.JoinCondition) *SelectDataset {
+ return sd.joinTable(exp.NewConditionedJoinExpression(exp.LeftJoinType, table, condition))
+}
+
+// Adds a NATURAL JOIN clause. See examples.
+func (sd *SelectDataset) NaturalJoin(table exp.Expression) *SelectDataset {
+ return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalJoinType, table))
+}
+
+// Adds a NATURAL LEFT JOIN clause. See examples.
+func (sd *SelectDataset) NaturalLeftJoin(table exp.Expression) *SelectDataset {
+ return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalLeftJoinType, table))
+}
+
+// Adds a NATURAL RIGHT JOIN clause. See examples.
+func (sd *SelectDataset) NaturalRightJoin(table exp.Expression) *SelectDataset {
+ return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalRightJoinType, table))
+}
+
+// Adds a NATURAL FULL JOIN clause. See examples.
+func (sd *SelectDataset) NaturalFullJoin(table exp.Expression) *SelectDataset {
+ return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.NaturalFullJoinType, table))
+}
+
+// Adds a CROSS JOIN clause. See examples.
+func (sd *SelectDataset) CrossJoin(table exp.Expression) *SelectDataset {
+ return sd.joinTable(exp.NewUnConditionedJoinExpression(exp.CrossJoinType, table))
+}
+
+// Joins this Datasets table with another
+func (sd *SelectDataset) joinTable(join exp.JoinExpression) *SelectDataset {
+ return sd.copy(sd.clauses.JoinsAppend(join))
+}
+
+// Adds a WHERE clause. See examples.
+func (sd *SelectDataset) Where(expressions ...exp.Expression) *SelectDataset {
+ return sd.copy(sd.clauses.WhereAppend(expressions...))
+}
+
+// Removes the WHERE clause. See examples.
+func (sd *SelectDataset) ClearWhere() *SelectDataset {
+ return sd.copy(sd.clauses.ClearWhere())
+}
+
+// Adds a FOR UPDATE clause. See examples.
+func (sd *SelectDataset) ForUpdate(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
+ return sd.withLock(exp.ForUpdate, waitOption, of...)
+}
+
+// Adds a FOR NO KEY UPDATE clause. See examples.
+func (sd *SelectDataset) ForNoKeyUpdate(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
+ return sd.withLock(exp.ForNoKeyUpdate, waitOption, of...)
+}
+
+// Adds a FOR KEY SHARE clause. See examples.
+func (sd *SelectDataset) ForKeyShare(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
+ return sd.withLock(exp.ForKeyShare, waitOption, of...)
+}
+
+// Adds a FOR SHARE clause. See examples.
+func (sd *SelectDataset) ForShare(waitOption exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
+ return sd.withLock(exp.ForShare, waitOption, of...)
+}
+
+func (sd *SelectDataset) withLock(strength exp.LockStrength, option exp.WaitOption, of ...exp.IdentifierExpression) *SelectDataset {
+ return sd.copy(sd.clauses.SetLock(exp.NewLock(strength, option, of...)))
+}
+
+// Adds a GROUP BY clause. See examples.
+func (sd *SelectDataset) GroupBy(groupBy ...interface{}) *SelectDataset {
+ return sd.copy(sd.clauses.SetGroupBy(exp.NewColumnListExpression(groupBy...)))
+}
+
+// Adds more columns to the current GROUP BY clause. See examples.
+func (sd *SelectDataset) GroupByAppend(groupBy ...interface{}) *SelectDataset {
+ return sd.copy(sd.clauses.GroupByAppend(exp.NewColumnListExpression(groupBy...)))
+}
+
+// Adds a HAVING clause. See examples.
+func (sd *SelectDataset) Having(expressions ...exp.Expression) *SelectDataset {
+ return sd.copy(sd.clauses.HavingAppend(expressions...))
+}
+
+// Adds a ORDER clause. If the ORDER is currently set it replaces it. See examples.
+func (sd *SelectDataset) Order(order ...exp.OrderedExpression) *SelectDataset {
+ return sd.copy(sd.clauses.SetOrder(order...))
+}
+
+// Adds a more columns to the current ORDER BY clause. If no order has be previously specified it is the same as
+// calling Order. See examples.
+func (sd *SelectDataset) OrderAppend(order ...exp.OrderedExpression) *SelectDataset {
+ return sd.copy(sd.clauses.OrderAppend(order...))
+}
+
+// Adds a more columns to the beginning of the current ORDER BY clause. If no order has be previously specified it is the same as
+// calling Order. See examples.
+func (sd *SelectDataset) OrderPrepend(order ...exp.OrderedExpression) *SelectDataset {
+ return sd.copy(sd.clauses.OrderPrepend(order...))
+}
+
+// Removes the ORDER BY clause. See examples.
+func (sd *SelectDataset) ClearOrder() *SelectDataset {
+ return sd.copy(sd.clauses.ClearOrder())
+}
+
+// Adds a LIMIT clause. If the LIMIT is currently set it replaces it. See examples.
+func (sd *SelectDataset) Limit(limit uint) *SelectDataset {
+ if limit > 0 {
+ return sd.copy(sd.clauses.SetLimit(limit))
+ }
+ return sd.copy(sd.clauses.ClearLimit())
+}
+
+// Adds a LIMIT ALL clause. If the LIMIT is currently set it replaces it. See examples.
+func (sd *SelectDataset) LimitAll() *SelectDataset {
+ return sd.copy(sd.clauses.SetLimit(L("ALL")))
+}
+
+// Removes the LIMIT clause.
+func (sd *SelectDataset) ClearLimit() *SelectDataset {
+ return sd.copy(sd.clauses.ClearLimit())
+}
+
+// Adds an OFFSET clause. If the OFFSET is currently set it replaces it. See examples.
+func (sd *SelectDataset) Offset(offset uint) *SelectDataset {
+ return sd.copy(sd.clauses.SetOffset(offset))
+}
+
+// Removes the OFFSET clause from the Dataset
+func (sd *SelectDataset) ClearOffset() *SelectDataset {
+ return sd.copy(sd.clauses.ClearOffset())
+}
+
+// Creates an UNION statement with another dataset.
+// If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
+// See examples.
+func (sd *SelectDataset) Union(other *SelectDataset) *SelectDataset {
+ return sd.withCompound(exp.UnionCompoundType, other.CompoundFromSelf())
+}
+
+// Creates an UNION ALL statement with another dataset.
+// If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
+// See examples.
+func (sd *SelectDataset) UnionAll(other *SelectDataset) *SelectDataset {
+ return sd.withCompound(exp.UnionAllCompoundType, other.CompoundFromSelf())
+}
+
+// Creates an INTERSECT statement with another dataset.
+// If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
+// See examples.
+func (sd *SelectDataset) Intersect(other *SelectDataset) *SelectDataset {
+ return sd.withCompound(exp.IntersectCompoundType, other.CompoundFromSelf())
+}
+
+// Creates an INTERSECT ALL statement with another dataset.
+// If this or the other dataset has a limit or offset it will use that dataset as a subselect in the FROM clause.
+// See examples.
+func (sd *SelectDataset) IntersectAll(other *SelectDataset) *SelectDataset {
+ return sd.withCompound(exp.IntersectAllCompoundType, other.CompoundFromSelf())
+}
+
+func (sd *SelectDataset) withCompound(ct exp.CompoundType, other exp.AppendableExpression) *SelectDataset {
+ ce := exp.NewCompoundExpression(ct, other)
+ ret := sd.CompoundFromSelf()
+ ret.clauses = ret.clauses.CompoundsAppend(ce)
+ return ret
+}
+
+// Used internally to determine if the dataset needs to use iteself as a source.
+// If the dataset has an order or limit it will select from itself
+func (sd *SelectDataset) CompoundFromSelf() *SelectDataset {
+ if sd.clauses.HasOrder() || sd.clauses.HasLimit() {
+ return sd.FromSelf()
+ }
+ return sd.copy(sd.clauses)
+}
+
+// Sets the alias for this dataset. This is typically used when using a Dataset as a subselect. See examples.
+func (sd *SelectDataset) As(alias string) *SelectDataset {
+ return sd.copy(sd.clauses.SetAlias(T(alias)))
+}
+
+// Returns the alias value as an identiier expression
+func (sd *SelectDataset) GetAs() exp.IdentifierExpression {
+ return sd.clauses.Alias()
+}
+
+// Sets the WINDOW clauses
+func (sd *SelectDataset) Window(ws ...exp.WindowExpression) *SelectDataset {
+ return sd.copy(sd.clauses.SetWindows(ws))
+}
+
+// Sets the WINDOW clauses
+func (sd *SelectDataset) WindowAppend(ws ...exp.WindowExpression) *SelectDataset {
+ return sd.copy(sd.clauses.WindowsAppend(ws...))
+}
+
+// Sets the WINDOW clauses
+func (sd *SelectDataset) ClearWindow() *SelectDataset {
+ return sd.copy(sd.clauses.ClearWindows())
+}
+
+// Get any error that has been set or nil if no error has been set.
+func (sd *SelectDataset) Error() error {
+ return sd.err
+}
+
+// Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
+// or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
+// track those separately.
+func (sd *SelectDataset) SetError(err error) *SelectDataset {
+ if sd.err == nil {
+ sd.err = err
+ }
+
+ return sd
+}
+
+// Generates a SELECT sql statement, if Prepared has been called with true then the parameters will not be interpolated.
+// See examples.
+//
+// Errors:
+// * There is an error generating the SQL
+func (sd *SelectDataset) ToSQL() (sql string, params []interface{}, err error) {
+ return sd.selectSQLBuilder().ToSQL()
+}
+
+// Generates the SELECT sql, and returns an Exec struct with the sql set to the SELECT statement
+// db.From("test").Select("col").Executor()
+//
+// See Dataset#ToUpdateSQL for arguments
+func (sd *SelectDataset) Executor() exec.QueryExecutor {
+ return sd.queryFactory.FromSQLBuilder(sd.selectSQLBuilder())
+}
+
+// Appends this Dataset's SELECT statement to the SQLBuilder
+// This is used internally for sub-selects by the dialect
+func (sd *SelectDataset) AppendSQL(b sb.SQLBuilder) {
+ if sd.err != nil {
+ b.SetError(sd.err)
+ return
+ }
+ sd.dialect.ToSelectSQL(b, sd.GetClauses())
+}
+
+func (sd *SelectDataset) ReturnsColumns() bool {
+ return true
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanStructs to scan the results into a slice of structs.
+//
+// ScanStructs will only select the columns that can be scanned in to the struct unless you have explicitly selected
+// certain columns. See examples.
+//
+// i: A pointer to a slice of structs
+func (sd *SelectDataset) ScanStructs(i interface{}) error {
+ return sd.ScanStructsContext(context.Background(), i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanStructsContext to scan the results into a slice of
+// structs.
+//
+// ScanStructsContext will only select the columns that can be scanned in to the struct unless you have explicitly
+// selected certain columns. See examples.
+//
+// i: A pointer to a slice of structs
+func (sd *SelectDataset) ScanStructsContext(ctx context.Context, i interface{}) error {
+ if sd.queryFactory == nil {
+ return ErrQueryFactoryNotFoundError
+ }
+ ds := sd
+ if sd.GetClauses().IsDefaultSelect() {
+ ds = sd.Select(i)
+ }
+ return ds.Executor().ScanStructsContext(ctx, i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanStruct to scan the result into a slice of structs
+//
+// ScanStruct will only select the columns that can be scanned in to the struct unless you have explicitly selected
+// certain columns. See examples.
+//
+// i: A pointer to a structs
+func (sd *SelectDataset) ScanStruct(i interface{}) (bool, error) {
+ return sd.ScanStructContext(context.Background(), i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanStructContext to scan the result into a slice of structs
+//
+// ScanStructContext will only select the columns that can be scanned in to the struct unless you have explicitly
+// selected certain columns. See examples.
+//
+// i: A pointer to a structs
+func (sd *SelectDataset) ScanStructContext(ctx context.Context, i interface{}) (bool, error) {
+ if sd.queryFactory == nil {
+ return false, ErrQueryFactoryNotFoundError
+ }
+ ds := sd
+ if sd.GetClauses().IsDefaultSelect() {
+ ds = sd.Select(i)
+ }
+ return ds.Limit(1).Executor().ScanStructContext(ctx, i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanVals to scan the results into a slice of primitive values
+//
+// i: A pointer to a slice of primitive values
+func (sd *SelectDataset) ScanVals(i interface{}) error {
+ return sd.ScanValsContext(context.Background(), i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanValsContext to scan the results into a slice of primitive
+// values
+//
+// i: A pointer to a slice of primitive values
+func (sd *SelectDataset) ScanValsContext(ctx context.Context, i interface{}) error {
+ if sd.queryFactory == nil {
+ return ErrQueryFactoryNotFoundError
+ }
+ return sd.Executor().ScanValsContext(ctx, i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanVal to scan the result into a primitive value
+//
+// i: A pointer to a primitive value
+func (sd *SelectDataset) ScanVal(i interface{}) (bool, error) {
+ return sd.ScanValContext(context.Background(), i)
+}
+
+// Generates the SELECT sql for this dataset and uses Exec#ScanValContext to scan the result into a primitive value
+//
+// i: A pointer to a primitive value
+func (sd *SelectDataset) ScanValContext(ctx context.Context, i interface{}) (bool, error) {
+ if sd.queryFactory == nil {
+ return false, ErrQueryFactoryNotFoundError
+ }
+ return sd.Limit(1).Executor().ScanValContext(ctx, i)
+}
+
+// Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanVal to scan the result into an int64.
+func (sd *SelectDataset) Count() (int64, error) {
+ return sd.CountContext(context.Background())
+}
+
+// Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanValContext to scan the result into an int64.
+func (sd *SelectDataset) CountContext(ctx context.Context) (int64, error) {
+ var count int64
+ _, err := sd.Select(COUNT(Star()).As("count")).ScanValContext(ctx, &count)
+ return count, err
+}
+
+// Generates the SELECT sql only selecting the passed in column and uses Exec#ScanVals to scan the result into a slice
+// of primitive values.
+//
+// i: A slice of primitive values
+//
+// col: The column to select when generative the SQL
+func (sd *SelectDataset) Pluck(i interface{}, col string) error {
+ return sd.PluckContext(context.Background(), i, col)
+}
+
+// Generates the SELECT sql only selecting the passed in column and uses Exec#ScanValsContext to scan the result into a
+// slice of primitive values.
+//
+// i: A slice of primitive values
+//
+// col: The column to select when generative the SQL
+func (sd *SelectDataset) PluckContext(ctx context.Context, i interface{}, col string) error {
+ return sd.Select(col).ScanValsContext(ctx, i)
+}
+
+func (sd *SelectDataset) selectSQLBuilder() sb.SQLBuilder {
+ buf := sb.NewSQLBuilder(sd.isPrepared.Bool())
+ if sd.err != nil {
+ return buf.SetError(sd.err)
+ }
+ sd.dialect.ToSelectSQL(buf, sd.GetClauses())
+ return buf
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sql_dialect.go b/vendor/github.com/doug-martin/goqu/v9/sql_dialect.go
new file mode 100644
index 000000000..796827411
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sql_dialect.go
@@ -0,0 +1,103 @@
+package goqu
+
+import (
+ "strings"
+ "sync"
+
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+ "github.com/doug-martin/goqu/v9/sqlgen"
+)
+
+type (
+ SQLDialectOptions = sqlgen.SQLDialectOptions
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ SQLDialect interface {
+ Dialect() string
+ ToSelectSQL(b sb.SQLBuilder, clauses exp.SelectClauses)
+ ToUpdateSQL(b sb.SQLBuilder, clauses exp.UpdateClauses)
+ ToInsertSQL(b sb.SQLBuilder, clauses exp.InsertClauses)
+ ToDeleteSQL(b sb.SQLBuilder, clauses exp.DeleteClauses)
+ ToTruncateSQL(b sb.SQLBuilder, clauses exp.TruncateClauses)
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ sqlDialect struct {
+ dialect string
+ dialectOptions *SQLDialectOptions
+ selectGen sqlgen.SelectSQLGenerator
+ updateGen sqlgen.UpdateSQLGenerator
+ insertGen sqlgen.InsertSQLGenerator
+ deleteGen sqlgen.DeleteSQLGenerator
+ truncateGen sqlgen.TruncateSQLGenerator
+ }
+)
+
+var (
+ dialects = make(map[string]SQLDialect)
+ DefaultDialectOptions = sqlgen.DefaultDialectOptions
+ dialectsMu sync.RWMutex
+)
+
+func init() {
+ RegisterDialect("default", DefaultDialectOptions())
+}
+
+func RegisterDialect(name string, do *SQLDialectOptions) {
+ dialectsMu.Lock()
+ defer dialectsMu.Unlock()
+ lowerName := strings.ToLower(name)
+ dialects[lowerName] = newDialect(lowerName, do)
+}
+
+func DeregisterDialect(name string) {
+ dialectsMu.Lock()
+ defer dialectsMu.Unlock()
+ delete(dialects, strings.ToLower(name))
+}
+
+func GetDialect(name string) SQLDialect {
+ name = strings.ToLower(name)
+ if d, ok := dialects[name]; ok {
+ return d
+ }
+ return newDialect("default", DefaultDialectOptions())
+}
+
+func newDialect(dialect string, do *SQLDialectOptions) SQLDialect {
+ return &sqlDialect{
+ dialect: dialect,
+ dialectOptions: do,
+ selectGen: sqlgen.NewSelectSQLGenerator(dialect, do),
+ updateGen: sqlgen.NewUpdateSQLGenerator(dialect, do),
+ insertGen: sqlgen.NewInsertSQLGenerator(dialect, do),
+ deleteGen: sqlgen.NewDeleteSQLGenerator(dialect, do),
+ truncateGen: sqlgen.NewTruncateSQLGenerator(dialect, do),
+ }
+}
+
+func (d *sqlDialect) Dialect() string {
+ return d.dialect
+}
+
+func (d *sqlDialect) ToSelectSQL(b sb.SQLBuilder, clauses exp.SelectClauses) {
+ d.selectGen.Generate(b, clauses)
+}
+
+func (d *sqlDialect) ToUpdateSQL(b sb.SQLBuilder, clauses exp.UpdateClauses) {
+ d.updateGen.Generate(b, clauses)
+}
+
+func (d *sqlDialect) ToInsertSQL(b sb.SQLBuilder, clauses exp.InsertClauses) {
+ d.insertGen.Generate(b, clauses)
+}
+
+func (d *sqlDialect) ToDeleteSQL(b sb.SQLBuilder, clauses exp.DeleteClauses) {
+ d.deleteGen.Generate(b, clauses)
+}
+
+func (d *sqlDialect) ToTruncateSQL(b sb.SQLBuilder, clauses exp.TruncateClauses) {
+ d.truncateGen.Generate(b, clauses)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/common_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/common_sql_generator.go
new file mode 100644
index 000000000..b54a87019
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/common_sql_generator.go
@@ -0,0 +1,155 @@
+package sqlgen
+
+import (
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+var ErrNoUpdatedValuesProvided = errors.New("no update values provided")
+
+func ErrCTENotSupported(dialect string) error {
+ return errors.New("dialect does not support CTE WITH clause [dialect=%s]", dialect)
+}
+
+func ErrRecursiveCTENotSupported(dialect string) error {
+ return errors.New("dialect does not support CTE WITH RECURSIVE clause [dialect=%s]", dialect)
+}
+
+func ErrReturnNotSupported(dialect string) error {
+ return errors.New("dialect does not support RETURNING clause [dialect=%s]", dialect)
+}
+
+func ErrNotSupportedFragment(sqlType string, f SQLFragmentType) error {
+ return errors.New("unsupported %s SQL fragment %s", sqlType, f)
+}
+
+type (
+ CommonSQLGenerator interface {
+ Dialect() string
+ DialectOptions() *SQLDialectOptions
+ ExpressionSQLGenerator() ExpressionSQLGenerator
+ ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression)
+ FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
+ SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
+ WhereSQL(b sb.SQLBuilder, where exp.ExpressionList)
+ OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression)
+ OrderWithOffsetFetchSQL(b sb.SQLBuilder, order exp.ColumnListExpression, offset uint, limit interface{})
+ LimitSQL(b sb.SQLBuilder, limit interface{})
+ UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression)
+ }
+ commonSQLGenerator struct {
+ dialect string
+ esg ExpressionSQLGenerator
+ dialectOptions *SQLDialectOptions
+ }
+)
+
+func NewCommonSQLGenerator(dialect string, do *SQLDialectOptions) CommonSQLGenerator {
+ return &commonSQLGenerator{dialect: dialect, esg: NewExpressionSQLGenerator(dialect, do), dialectOptions: do}
+}
+
+func (csg *commonSQLGenerator) Dialect() string {
+ return csg.dialect
+}
+
+func (csg *commonSQLGenerator) DialectOptions() *SQLDialectOptions {
+ return csg.dialectOptions
+}
+
+func (csg *commonSQLGenerator) ExpressionSQLGenerator() ExpressionSQLGenerator {
+ return csg.esg
+}
+
+func (csg *commonSQLGenerator) ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression) {
+ if returns != nil && len(returns.Columns()) > 0 {
+ if csg.dialectOptions.SupportsReturn {
+ b.Write(csg.dialectOptions.ReturningFragment)
+ csg.esg.Generate(b, returns)
+ } else {
+ b.SetError(ErrReturnNotSupported(csg.dialect))
+ }
+ }
+}
+
+// Adds the FROM clause and tables to an sql statement
+func (csg *commonSQLGenerator) FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression) {
+ if from != nil && !from.IsEmpty() {
+ b.Write(csg.dialectOptions.FromFragment)
+ csg.SourcesSQL(b, from)
+ }
+}
+
+// Adds the generates the SQL for a column list
+func (csg *commonSQLGenerator) SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression) {
+ b.WriteRunes(csg.dialectOptions.SpaceRune)
+ csg.esg.Generate(b, from)
+}
+
+// Generates the WHERE clause for an SQL statement
+func (csg *commonSQLGenerator) WhereSQL(b sb.SQLBuilder, where exp.ExpressionList) {
+ if where != nil && !where.IsEmpty() {
+ b.Write(csg.dialectOptions.WhereFragment)
+ csg.esg.Generate(b, where)
+ }
+}
+
+// Generates the ORDER BY clause for an SQL statement
+func (csg *commonSQLGenerator) OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression) {
+ if order != nil && len(order.Columns()) > 0 {
+ b.Write(csg.dialectOptions.OrderByFragment)
+ csg.esg.Generate(b, order)
+ }
+}
+
+func (csg *commonSQLGenerator) OrderWithOffsetFetchSQL(
+ b sb.SQLBuilder,
+ order exp.ColumnListExpression,
+ offset uint,
+ limit interface{},
+) {
+ if order == nil {
+ return
+ }
+
+ csg.OrderSQL(b, order)
+ if offset > 0 {
+ b.Write(csg.dialectOptions.OffsetFragment)
+ csg.esg.Generate(b, offset)
+ b.Write([]byte(" ROWS"))
+
+ if limit != nil {
+ b.Write(csg.dialectOptions.FetchFragment)
+ csg.esg.Generate(b, limit)
+ b.Write([]byte(" ROWS ONLY"))
+ }
+ }
+}
+
+// Generates the LIMIT clause for an SQL statement
+func (csg *commonSQLGenerator) LimitSQL(b sb.SQLBuilder, limit interface{}) {
+ if limit != nil {
+ b.Write(csg.dialectOptions.LimitFragment)
+ if csg.dialectOptions.SurroundLimitWithParentheses {
+ b.WriteRunes(csg.dialectOptions.LeftParenRune)
+ }
+ csg.esg.Generate(b, limit)
+ if csg.dialectOptions.SurroundLimitWithParentheses {
+ b.WriteRunes(csg.dialectOptions.RightParenRune)
+ }
+ }
+}
+
+func (csg *commonSQLGenerator) UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression) {
+ if len(updates) == 0 {
+ b.SetError(ErrNoUpdatedValuesProvided)
+ return
+ }
+ updateLen := len(updates)
+ for i, update := range updates {
+ csg.esg.Generate(b, update)
+ if i < updateLen-1 {
+ b.WriteRunes(csg.dialectOptions.CommaRune)
+ }
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/delete_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/delete_sql_generator.go
new file mode 100644
index 000000000..107708a28
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/delete_sql_generator.go
@@ -0,0 +1,72 @@
+package sqlgen
+
+import (
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type (
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ DeleteSQLGenerator interface {
+ Dialect() string
+ Generate(b sb.SQLBuilder, clauses exp.DeleteClauses)
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ deleteSQLGenerator struct {
+ CommonSQLGenerator
+ }
+)
+
+var ErrNoSourceForDelete = errors.New("no source found when generating delete sql")
+
+func NewDeleteSQLGenerator(dialect string, do *SQLDialectOptions) DeleteSQLGenerator {
+ return &deleteSQLGenerator{NewCommonSQLGenerator(dialect, do)}
+}
+
+func (dsg *deleteSQLGenerator) Generate(b sb.SQLBuilder, clauses exp.DeleteClauses) {
+ if !clauses.HasFrom() {
+ b.SetError(ErrNoSourceForDelete)
+ return
+ }
+ for _, f := range dsg.DialectOptions().DeleteSQLOrder {
+ if b.Error() != nil {
+ return
+ }
+ switch f {
+ case CommonTableSQLFragment:
+ dsg.ExpressionSQLGenerator().Generate(b, clauses.CommonTables())
+ case DeleteBeginSQLFragment:
+ dsg.DeleteBeginSQL(
+ b, exp.NewColumnListExpression(clauses.From()), !(clauses.HasLimit() || clauses.HasOrder()),
+ )
+ case FromSQLFragment:
+ dsg.FromSQL(b, exp.NewColumnListExpression(clauses.From()))
+ case WhereSQLFragment:
+ dsg.WhereSQL(b, clauses.Where())
+ case OrderSQLFragment:
+ if dsg.DialectOptions().SupportsOrderByOnDelete {
+ dsg.OrderSQL(b, clauses.Order())
+ }
+ case LimitSQLFragment:
+ if dsg.DialectOptions().SupportsLimitOnDelete {
+ dsg.LimitSQL(b, clauses.Limit())
+ }
+ case ReturningSQLFragment:
+ dsg.ReturningSQL(b, clauses.Returning())
+ default:
+ b.SetError(ErrNotSupportedFragment("DELETE", f))
+ }
+ }
+}
+
+// Adds the correct fragment to being an DELETE statement
+func (dsg *deleteSQLGenerator) DeleteBeginSQL(b sb.SQLBuilder, from exp.ColumnListExpression, multiTable bool) {
+ b.Write(dsg.DialectOptions().DeleteClause)
+ if multiTable && dsg.DialectOptions().SupportsDeleteTableHint {
+ dsg.SourcesSQL(b, from)
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/expression_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/expression_sql_generator.go
new file mode 100644
index 000000000..82ce15c58
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/expression_sql_generator.go
@@ -0,0 +1,733 @@
+package sqlgen
+
+import (
+ "database/sql/driver"
+ "reflect"
+ "strconv"
+ "time"
+ "unicode/utf8"
+
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+ "github.com/doug-martin/goqu/v9/internal/util"
+)
+
+type (
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ ExpressionSQLGenerator interface {
+ Dialect() string
+ Generate(b sb.SQLBuilder, val interface{})
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ expressionSQLGenerator struct {
+ dialect string
+ dialectOptions *SQLDialectOptions
+ }
+)
+
+var (
+ replacementRune = '?'
+ TrueLiteral = exp.NewLiteralExpression("TRUE")
+ FalseLiteral = exp.NewLiteralExpression("FALSE")
+
+ ErrEmptyIdentifier = errors.New(
+ `a empty identifier was encountered, please specify a "schema", "table" or "column"`,
+ )
+ ErrUnexpectedNamedWindow = errors.New(`unexpected named window function`)
+ ErrEmptyCaseWhens = errors.New(`when conditions not found for case statement`)
+)
+
+func errUnsupportedExpressionType(e exp.Expression) error {
+ return errors.New("unsupported expression type %T", e)
+}
+
+func errUnsupportedIdentifierExpression(t interface{}) error {
+ return errors.New("unexpected col type must be string or LiteralExpression received %T", t)
+}
+
+func errUnsupportedBooleanExpressionOperator(op exp.BooleanOperation) error {
+ return errors.New("boolean operator '%+v' not supported", op)
+}
+
+func errUnsupportedBitwiseExpressionOperator(op exp.BitwiseOperation) error {
+ return errors.New("bitwise operator '%+v' not supported", op)
+}
+
+func errUnsupportedRangeExpressionOperator(op exp.RangeOperation) error {
+ return errors.New("range operator %+v not supported", op)
+}
+
+func errLateralNotSupported(dialect string) error {
+ return errors.New("dialect does not support lateral expressions [dialect=%s]", dialect)
+}
+
+func NewExpressionSQLGenerator(dialect string, do *SQLDialectOptions) ExpressionSQLGenerator {
+ return &expressionSQLGenerator{dialect: dialect, dialectOptions: do}
+}
+
+func (esg *expressionSQLGenerator) Dialect() string {
+ return esg.dialect
+}
+
+var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
+
+func (esg *expressionSQLGenerator) Generate(b sb.SQLBuilder, val interface{}) {
+ if b.Error() != nil {
+ return
+ }
+ if val == nil {
+ esg.literalNil(b)
+ return
+ }
+ switch v := val.(type) {
+ case exp.Expression:
+ esg.expressionSQL(b, v)
+ case int:
+ esg.literalInt(b, int64(v))
+ case int32:
+ esg.literalInt(b, int64(v))
+ case int64:
+ esg.literalInt(b, v)
+ case float32:
+ esg.literalFloat(b, float64(v))
+ case float64:
+ esg.literalFloat(b, v)
+ case string:
+ esg.literalString(b, v)
+ case bool:
+ esg.literalBool(b, v)
+ case time.Time:
+ esg.literalTime(b, v)
+ case *time.Time:
+ if v == nil {
+ esg.literalNil(b)
+ return
+ }
+ esg.literalTime(b, *v)
+ case driver.Valuer:
+ // See https://github.com/golang/go/commit/0ce1d79a6a771f7449ec493b993ed2a720917870
+ if rv := reflect.ValueOf(val); rv.Kind() == reflect.Ptr &&
+ rv.IsNil() &&
+ rv.Type().Elem().Implements(valuerReflectType) {
+ esg.literalNil(b)
+ return
+ }
+ dVal, err := v.Value()
+ if err != nil {
+ b.SetError(err)
+ return
+ }
+ esg.Generate(b, dVal)
+ default:
+ esg.reflectSQL(b, val)
+ }
+}
+
+func (esg *expressionSQLGenerator) reflectSQL(b sb.SQLBuilder, val interface{}) {
+ v := reflect.Indirect(reflect.ValueOf(val))
+ valKind := v.Kind()
+ switch {
+ case util.IsInvalid(valKind):
+ esg.literalNil(b)
+ case util.IsSlice(valKind):
+ switch t := val.(type) {
+ case []byte:
+ esg.literalBytes(b, t)
+ case []exp.CommonTableExpression:
+ esg.commonTablesSliceSQL(b, t)
+ default:
+ esg.sliceValueSQL(b, v)
+ }
+ case util.IsInt(valKind):
+ esg.Generate(b, v.Int())
+ case util.IsUint(valKind):
+ esg.Generate(b, int64(v.Uint()))
+ case util.IsFloat(valKind):
+ esg.Generate(b, v.Float())
+ case util.IsString(valKind):
+ esg.Generate(b, v.String())
+ case util.IsBool(valKind):
+ esg.Generate(b, v.Bool())
+ default:
+ b.SetError(errors.NewEncodeError(val))
+ }
+}
+
+// nolint:gocyclo // not complex just long
+func (esg *expressionSQLGenerator) expressionSQL(b sb.SQLBuilder, expression exp.Expression) {
+ switch e := expression.(type) {
+ case exp.ColumnListExpression:
+ esg.columnListSQL(b, e)
+ case exp.ExpressionList:
+ esg.expressionListSQL(b, e)
+ case exp.LiteralExpression:
+ esg.literalExpressionSQL(b, e)
+ case exp.IdentifierExpression:
+ esg.identifierExpressionSQL(b, e)
+ case exp.LateralExpression:
+ esg.lateralExpressionSQL(b, e)
+ case exp.AliasedExpression:
+ esg.aliasedExpressionSQL(b, e)
+ case exp.BooleanExpression:
+ esg.booleanExpressionSQL(b, e)
+ case exp.BitwiseExpression:
+ esg.bitwiseExpressionSQL(b, e)
+ case exp.RangeExpression:
+ esg.rangeExpressionSQL(b, e)
+ case exp.OrderedExpression:
+ esg.orderedExpressionSQL(b, e)
+ case exp.UpdateExpression:
+ esg.updateExpressionSQL(b, e)
+ case exp.SQLFunctionExpression:
+ esg.sqlFunctionExpressionSQL(b, e)
+ case exp.SQLWindowFunctionExpression:
+ esg.sqlWindowFunctionExpression(b, e)
+ case exp.WindowExpression:
+ esg.windowExpressionSQL(b, e)
+ case exp.CastExpression:
+ esg.castExpressionSQL(b, e)
+ case exp.AppendableExpression:
+ esg.appendableExpressionSQL(b, e)
+ case exp.CommonTableExpression:
+ esg.commonTableExpressionSQL(b, e)
+ case exp.CompoundExpression:
+ esg.compoundExpressionSQL(b, e)
+ case exp.CaseExpression:
+ esg.caseExpressionSQL(b, e)
+ case exp.Ex:
+ esg.expressionMapSQL(b, e)
+ case exp.ExOr:
+ esg.expressionOrMapSQL(b, e)
+ default:
+ b.SetError(errUnsupportedExpressionType(e))
+ }
+}
+
+// Generates a placeholder (e.g. ?, $1)
+func (esg *expressionSQLGenerator) placeHolderSQL(b sb.SQLBuilder, i interface{}) {
+ b.Write(esg.dialectOptions.PlaceHolderFragment)
+ if esg.dialectOptions.IncludePlaceholderNum {
+ b.WriteStrings(strconv.FormatInt(int64(b.CurrentArgPosition()), 10))
+ }
+ b.WriteArg(i)
+}
+
+// Generates creates the sql for a sub select on a Dataset
+func (esg *expressionSQLGenerator) appendableExpressionSQL(b sb.SQLBuilder, a exp.AppendableExpression) {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+ a.AppendSQL(b)
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+ if a.GetAs() != nil {
+ b.Write(esg.dialectOptions.AsFragment)
+ esg.Generate(b, a.GetAs())
+ }
+}
+
+// Quotes an identifier (e.g. "col", "table"."col"
+func (esg *expressionSQLGenerator) identifierExpressionSQL(b sb.SQLBuilder, ident exp.IdentifierExpression) {
+ if ident.IsEmpty() {
+ b.SetError(ErrEmptyIdentifier)
+ return
+ }
+ schema, table, col := ident.GetSchema(), ident.GetTable(), ident.GetCol()
+ if schema != esg.dialectOptions.EmptyString {
+ b.WriteRunes(esg.dialectOptions.QuoteRune).
+ WriteStrings(schema).
+ WriteRunes(esg.dialectOptions.QuoteRune)
+ }
+ if table != esg.dialectOptions.EmptyString {
+ if schema != esg.dialectOptions.EmptyString {
+ b.WriteRunes(esg.dialectOptions.PeriodRune)
+ }
+ b.WriteRunes(esg.dialectOptions.QuoteRune).
+ WriteStrings(table).
+ WriteRunes(esg.dialectOptions.QuoteRune)
+ }
+ switch t := col.(type) {
+ case nil:
+ case string:
+ if col != esg.dialectOptions.EmptyString {
+ if table != esg.dialectOptions.EmptyString || schema != esg.dialectOptions.EmptyString {
+ b.WriteRunes(esg.dialectOptions.PeriodRune)
+ }
+ b.WriteRunes(esg.dialectOptions.QuoteRune).
+ WriteStrings(t).
+ WriteRunes(esg.dialectOptions.QuoteRune)
+ }
+ case exp.LiteralExpression:
+ if table != esg.dialectOptions.EmptyString || schema != esg.dialectOptions.EmptyString {
+ b.WriteRunes(esg.dialectOptions.PeriodRune)
+ }
+ esg.Generate(b, t)
+ default:
+ b.SetError(errUnsupportedIdentifierExpression(col))
+ }
+}
+
+func (esg *expressionSQLGenerator) lateralExpressionSQL(b sb.SQLBuilder, le exp.LateralExpression) {
+ if !esg.dialectOptions.SupportsLateral {
+ b.SetError(errLateralNotSupported(esg.dialect))
+ return
+ }
+ b.Write(esg.dialectOptions.LateralFragment)
+ esg.Generate(b, le.Table())
+}
+
+// Generates SQL NULL value
+func (esg *expressionSQLGenerator) literalNil(b sb.SQLBuilder) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, nil)
+ return
+ }
+ b.Write(esg.dialectOptions.Null)
+}
+
+// Generates SQL bool literal, (e.g. TRUE, FALSE, mysql 1, 0, sqlite3 1, 0)
+func (esg *expressionSQLGenerator) literalBool(b sb.SQLBuilder, bl bool) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, bl)
+ return
+ }
+ if bl {
+ b.Write(esg.dialectOptions.True)
+ } else {
+ b.Write(esg.dialectOptions.False)
+ }
+}
+
+// Generates SQL for a time.Time value
+func (esg *expressionSQLGenerator) literalTime(b sb.SQLBuilder, t time.Time) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, t)
+ return
+ }
+ esg.Generate(b, t.In(timeLocation).Format(esg.dialectOptions.TimeFormat))
+}
+
+// Generates SQL for a Float Value
+func (esg *expressionSQLGenerator) literalFloat(b sb.SQLBuilder, f float64) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, f)
+ return
+ }
+ b.WriteStrings(strconv.FormatFloat(f, 'f', -1, 64))
+}
+
+// Generates SQL for an int value
+func (esg *expressionSQLGenerator) literalInt(b sb.SQLBuilder, i int64) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, i)
+ return
+ }
+ b.WriteStrings(strconv.FormatInt(i, 10))
+}
+
+// Generates SQL for a string
+func (esg *expressionSQLGenerator) literalString(b sb.SQLBuilder, s string) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, s)
+ return
+ }
+ b.WriteRunes(esg.dialectOptions.StringQuote)
+ for _, char := range s {
+ if e, ok := esg.dialectOptions.EscapedRunes[char]; ok {
+ b.Write(e)
+ } else {
+ b.WriteRunes(char)
+ }
+ }
+
+ b.WriteRunes(esg.dialectOptions.StringQuote)
+}
+
+// Generates SQL for a slice of bytes
+func (esg *expressionSQLGenerator) literalBytes(b sb.SQLBuilder, bs []byte) {
+ if b.IsPrepared() {
+ esg.placeHolderSQL(b, bs)
+ return
+ }
+ b.WriteRunes(esg.dialectOptions.StringQuote)
+ i := 0
+ for len(bs) > 0 {
+ char, l := utf8.DecodeRune(bs)
+ if e, ok := esg.dialectOptions.EscapedRunes[char]; ok {
+ b.Write(e)
+ } else {
+ b.WriteRunes(char)
+ }
+ i++
+ bs = bs[l:]
+ }
+ b.WriteRunes(esg.dialectOptions.StringQuote)
+}
+
+// Generates SQL for a slice of values (e.g. []int64{1,2,3,4} -> (1,2,3,4)
+func (esg *expressionSQLGenerator) sliceValueSQL(b sb.SQLBuilder, slice reflect.Value) {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+ for i, l := 0, slice.Len(); i < l; i++ {
+ esg.Generate(b, slice.Index(i).Interface())
+ if i < l-1 {
+ b.WriteRunes(esg.dialectOptions.CommaRune, esg.dialectOptions.SpaceRune)
+ }
+ }
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates SQL for an AliasedExpression (e.g. I("a").As("b") -> "a" AS "b")
+func (esg *expressionSQLGenerator) aliasedExpressionSQL(b sb.SQLBuilder, aliased exp.AliasedExpression) {
+ esg.Generate(b, aliased.Aliased())
+ b.Write(esg.dialectOptions.AsFragment)
+ esg.Generate(b, aliased.GetAs())
+}
+
+// Generates SQL for a BooleanExpresion (e.g. I("a").Eq(2) -> "a" = 2)
+func (esg *expressionSQLGenerator) booleanExpressionSQL(b sb.SQLBuilder, operator exp.BooleanExpression) {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+ esg.Generate(b, operator.LHS())
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ operatorOp := operator.Op()
+ if val, ok := esg.dialectOptions.BooleanOperatorLookup[operatorOp]; ok {
+ b.Write(val)
+ } else {
+ b.SetError(errUnsupportedBooleanExpressionOperator(operatorOp))
+ return
+ }
+ rhs := operator.RHS()
+
+ if (operatorOp == exp.IsOp || operatorOp == exp.IsNotOp) && rhs != nil && !esg.dialectOptions.BooleanDataTypeSupported {
+ b.SetError(errors.New("boolean data type is not supported by dialect %q", esg.dialect))
+ return
+ }
+
+ if (operatorOp == exp.IsOp || operatorOp == exp.IsNotOp) && esg.dialectOptions.UseLiteralIsBools {
+ // these values must be interpolated because preparing them generates invalid SQL
+ switch rhs {
+ case true:
+ rhs = TrueLiteral
+ case false:
+ rhs = FalseLiteral
+ case nil:
+ rhs = exp.NewLiteralExpression(string(esg.dialectOptions.Null))
+ }
+ }
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+
+ if (operatorOp == exp.IsOp || operatorOp == exp.IsNotOp) && rhs == nil && !esg.dialectOptions.BooleanDataTypeSupported {
+ // e.g. for SQL server dialect which does not support "IS @p1" for "IS NULL"
+ b.Write(esg.dialectOptions.Null)
+ } else {
+ esg.Generate(b, rhs)
+ }
+
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates SQL for a BitwiseExpresion (e.g. I("a").BitwiseOr(2) - > "a" | 2)
+func (esg *expressionSQLGenerator) bitwiseExpressionSQL(b sb.SQLBuilder, operator exp.BitwiseExpression) {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+
+ if operator.LHS() != nil {
+ esg.Generate(b, operator.LHS())
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ }
+
+ operatorOp := operator.Op()
+ if val, ok := esg.dialectOptions.BitwiseOperatorLookup[operatorOp]; ok {
+ b.Write(val)
+ } else {
+ b.SetError(errUnsupportedBitwiseExpressionOperator(operatorOp))
+ return
+ }
+
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ esg.Generate(b, operator.RHS())
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates SQL for a RangeExpresion (e.g. I("a").Between(RangeVal{Start:2,End:5}) -> "a" BETWEEN 2 AND 5)
+func (esg *expressionSQLGenerator) rangeExpressionSQL(b sb.SQLBuilder, operator exp.RangeExpression) {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+ esg.Generate(b, operator.LHS())
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ operatorOp := operator.Op()
+ if val, ok := esg.dialectOptions.RangeOperatorLookup[operatorOp]; ok {
+ b.Write(val)
+ } else {
+ b.SetError(errUnsupportedRangeExpressionOperator(operatorOp))
+ return
+ }
+ rhs := operator.RHS()
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ esg.Generate(b, rhs.Start())
+ b.Write(esg.dialectOptions.AndFragment)
+ esg.Generate(b, rhs.End())
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates SQL for an OrderedExpression (e.g. I("a").Asc() -> "a" ASC)
+func (esg *expressionSQLGenerator) orderedExpressionSQL(b sb.SQLBuilder, order exp.OrderedExpression) {
+ esg.Generate(b, order.SortExpression())
+ if order.IsAsc() {
+ b.Write(esg.dialectOptions.AscFragment)
+ } else {
+ b.Write(esg.dialectOptions.DescFragment)
+ }
+ switch order.NullSortType() {
+ case exp.NoNullsSortType:
+ return
+ case exp.NullsFirstSortType:
+ b.Write(esg.dialectOptions.NullsFirstFragment)
+ case exp.NullsLastSortType:
+ b.Write(esg.dialectOptions.NullsLastFragment)
+ }
+}
+
+// Generates SQL for an ExpressionList (e.g. And(I("a").Eq("a"), I("b").Eq("b")) -> (("a" = 'a') AND ("b" = 'b')))
+func (esg *expressionSQLGenerator) expressionListSQL(b sb.SQLBuilder, expressionList exp.ExpressionList) {
+ if expressionList.IsEmpty() {
+ return
+ }
+ var op []byte
+ if expressionList.Type() == exp.AndType {
+ op = esg.dialectOptions.AndFragment
+ } else {
+ op = esg.dialectOptions.OrFragment
+ }
+ exps := expressionList.Expressions()
+ expLen := len(exps) - 1
+ if expLen > 0 {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+ } else {
+ esg.Generate(b, exps[0])
+ return
+ }
+ for i, e := range exps {
+ esg.Generate(b, e)
+ if i < expLen {
+ b.Write(op)
+ }
+ }
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates SQL for a ColumnListExpression
+func (esg *expressionSQLGenerator) columnListSQL(b sb.SQLBuilder, columnList exp.ColumnListExpression) {
+ cols := columnList.Columns()
+ colLen := len(cols)
+ for i, col := range cols {
+ esg.Generate(b, col)
+ if i < colLen-1 {
+ b.WriteRunes(esg.dialectOptions.CommaRune, esg.dialectOptions.SpaceRune)
+ }
+ }
+}
+
+// Generates SQL for an UpdateEpxresion
+func (esg *expressionSQLGenerator) updateExpressionSQL(b sb.SQLBuilder, update exp.UpdateExpression) {
+ esg.Generate(b, update.Col())
+ b.WriteRunes(esg.dialectOptions.SetOperatorRune)
+ esg.Generate(b, update.Val())
+}
+
+// Generates SQL for a LiteralExpression
+// L("a + b") -> a + b
+// L("a = ?", 1) -> a = 1
+func (esg *expressionSQLGenerator) literalExpressionSQL(b sb.SQLBuilder, literal exp.LiteralExpression) {
+ l := literal.Literal()
+ args := literal.Args()
+ if argsLen := len(args); argsLen > 0 {
+ currIndex := 0
+ for _, char := range l {
+ if char == replacementRune && currIndex < argsLen {
+ esg.Generate(b, args[currIndex])
+ currIndex++
+ } else {
+ b.WriteRunes(char)
+ }
+ }
+ return
+ }
+ b.WriteStrings(l)
+}
+
+// Generates SQL for a SQLFunctionExpression
+// COUNT(I("a")) -> COUNT("a")
+func (esg *expressionSQLGenerator) sqlFunctionExpressionSQL(b sb.SQLBuilder, sqlFunc exp.SQLFunctionExpression) {
+ b.WriteStrings(sqlFunc.Name())
+ esg.Generate(b, sqlFunc.Args())
+}
+
+func (esg *expressionSQLGenerator) sqlWindowFunctionExpression(b sb.SQLBuilder, sqlWinFunc exp.SQLWindowFunctionExpression) {
+ if !esg.dialectOptions.SupportsWindowFunction {
+ b.SetError(ErrWindowNotSupported(esg.dialect))
+ return
+ }
+ esg.Generate(b, sqlWinFunc.Func())
+ b.Write(esg.dialectOptions.WindowOverFragment)
+ switch {
+ case sqlWinFunc.HasWindowName():
+ esg.Generate(b, sqlWinFunc.WindowName())
+ case sqlWinFunc.HasWindow():
+ if sqlWinFunc.Window().HasName() {
+ b.SetError(ErrUnexpectedNamedWindow)
+ return
+ }
+ esg.Generate(b, sqlWinFunc.Window())
+ default:
+ esg.Generate(b, exp.NewWindowExpression(nil, nil, nil, nil))
+ }
+}
+
+func (esg *expressionSQLGenerator) windowExpressionSQL(b sb.SQLBuilder, we exp.WindowExpression) {
+ if !esg.dialectOptions.SupportsWindowFunction {
+ b.SetError(ErrWindowNotSupported(esg.dialect))
+ return
+ }
+ if we.HasName() {
+ esg.Generate(b, we.Name())
+ b.Write(esg.dialectOptions.AsFragment)
+ }
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+
+ hasPartition := we.HasPartitionBy()
+ hasOrder := we.HasOrder()
+
+ if we.HasParent() {
+ esg.Generate(b, we.Parent())
+ if hasPartition || hasOrder {
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ }
+ }
+
+ if hasPartition {
+ b.Write(esg.dialectOptions.WindowPartitionByFragment)
+ esg.Generate(b, we.PartitionCols())
+ if hasOrder {
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+ }
+ }
+ if hasOrder {
+ b.Write(esg.dialectOptions.WindowOrderByFragment)
+ esg.Generate(b, we.OrderCols())
+ }
+
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates SQL for a CastExpression
+// I("a").Cast("NUMERIC") -> CAST("a" AS NUMERIC)
+func (esg *expressionSQLGenerator) castExpressionSQL(b sb.SQLBuilder, cast exp.CastExpression) {
+ b.Write(esg.dialectOptions.CastFragment).WriteRunes(esg.dialectOptions.LeftParenRune)
+ esg.Generate(b, cast.Casted())
+ b.Write(esg.dialectOptions.AsFragment)
+ esg.Generate(b, cast.Type())
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+}
+
+// Generates the sql for the WITH clauses for common table expressions (CTE)
+func (esg *expressionSQLGenerator) commonTablesSliceSQL(b sb.SQLBuilder, ctes []exp.CommonTableExpression) {
+ l := len(ctes)
+ if l == 0 {
+ return
+ }
+ if !esg.dialectOptions.SupportsWithCTE {
+ b.SetError(ErrCTENotSupported(esg.dialect))
+ return
+ }
+ b.Write(esg.dialectOptions.WithFragment)
+ anyRecursive := false
+ for _, cte := range ctes {
+ anyRecursive = anyRecursive || cte.IsRecursive()
+ }
+ if anyRecursive {
+ if !esg.dialectOptions.SupportsWithCTERecursive {
+ b.SetError(ErrRecursiveCTENotSupported(esg.dialect))
+ return
+ }
+ b.Write(esg.dialectOptions.RecursiveFragment)
+ }
+ for i, cte := range ctes {
+ esg.Generate(b, cte)
+ if i < l-1 {
+ b.WriteRunes(esg.dialectOptions.CommaRune, esg.dialectOptions.SpaceRune)
+ }
+ }
+ b.WriteRunes(esg.dialectOptions.SpaceRune)
+}
+
+// Generates SQL for a CommonTableExpression
+func (esg *expressionSQLGenerator) commonTableExpressionSQL(b sb.SQLBuilder, cte exp.CommonTableExpression) {
+ esg.Generate(b, cte.Name())
+ b.Write(esg.dialectOptions.AsFragment)
+ esg.Generate(b, cte.SubQuery())
+}
+
+// Generates SQL for a CompoundExpression
+func (esg *expressionSQLGenerator) compoundExpressionSQL(b sb.SQLBuilder, compound exp.CompoundExpression) {
+ switch compound.Type() {
+ case exp.UnionCompoundType:
+ b.Write(esg.dialectOptions.UnionFragment)
+ case exp.UnionAllCompoundType:
+ b.Write(esg.dialectOptions.UnionAllFragment)
+ case exp.IntersectCompoundType:
+ b.Write(esg.dialectOptions.IntersectFragment)
+ case exp.IntersectAllCompoundType:
+ b.Write(esg.dialectOptions.IntersectAllFragment)
+ }
+ if esg.dialectOptions.WrapCompoundsInParens {
+ b.WriteRunes(esg.dialectOptions.LeftParenRune)
+ compound.RHS().AppendSQL(b)
+ b.WriteRunes(esg.dialectOptions.RightParenRune)
+ } else {
+ compound.RHS().AppendSQL(b)
+ }
+}
+
+// Generates SQL for a CaseExpression
+func (esg *expressionSQLGenerator) caseExpressionSQL(b sb.SQLBuilder, caseExpression exp.CaseExpression) {
+ caseVal := caseExpression.GetValue()
+ whens := caseExpression.GetWhens()
+ elseResult := caseExpression.GetElse()
+
+ if len(whens) == 0 {
+ b.SetError(ErrEmptyCaseWhens)
+ return
+ }
+ b.Write(esg.dialectOptions.CaseFragment)
+ if caseVal != nil {
+ esg.Generate(b, caseVal)
+ }
+ for _, when := range whens {
+ b.Write(esg.dialectOptions.WhenFragment)
+ esg.Generate(b, when.Condition())
+ b.Write(esg.dialectOptions.ThenFragment)
+ esg.Generate(b, when.Result())
+ }
+ if elseResult != nil {
+ b.Write(esg.dialectOptions.ElseFragment)
+ esg.Generate(b, elseResult.Result())
+ }
+ b.Write(esg.dialectOptions.EndFragment)
+}
+
+func (esg *expressionSQLGenerator) expressionMapSQL(b sb.SQLBuilder, ex exp.Ex) {
+ expressionList, err := ex.ToExpressions()
+ if err != nil {
+ b.SetError(err)
+ return
+ }
+ esg.Generate(b, expressionList)
+}
+
+func (esg *expressionSQLGenerator) expressionOrMapSQL(b sb.SQLBuilder, ex exp.ExOr) {
+ expressionList, err := ex.ToExpressions()
+ if err != nil {
+ b.SetError(err)
+ return
+ }
+ esg.Generate(b, expressionList)
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/insert_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/insert_sql_generator.go
new file mode 100644
index 000000000..1c6105b93
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/insert_sql_generator.go
@@ -0,0 +1,203 @@
+package sqlgen
+
+import (
+ "strings"
+
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type (
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ InsertSQLGenerator interface {
+ Dialect() string
+ Generate(b sb.SQLBuilder, clauses exp.InsertClauses)
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ insertSQLGenerator struct {
+ CommonSQLGenerator
+ }
+)
+
+var (
+ ErrConflictUpdateValuesRequired = errors.New("values are required for on conflict update expression")
+ ErrNoSourceForInsert = errors.New("no source found when generating insert sql")
+)
+
+func errMisMatchedRowLength(expectedL, actualL int) error {
+ return errors.New("rows with different value length expected %d got %d", expectedL, actualL)
+}
+
+func errUpsertWithWhereNotSupported(dialect string) error {
+ return errors.New("dialect does not support upsert with where clause [dialect=%s]", dialect)
+}
+
+func NewInsertSQLGenerator(dialect string, do *SQLDialectOptions) InsertSQLGenerator {
+ return &insertSQLGenerator{NewCommonSQLGenerator(dialect, do)}
+}
+
+func (isg *insertSQLGenerator) Generate(
+ b sb.SQLBuilder,
+ clauses exp.InsertClauses,
+) {
+ if !clauses.HasInto() {
+ b.SetError(ErrNoSourceForInsert)
+ return
+ }
+ for _, f := range isg.DialectOptions().InsertSQLOrder {
+ if b.Error() != nil {
+ return
+ }
+ switch f {
+ case CommonTableSQLFragment:
+ isg.ExpressionSQLGenerator().Generate(b, clauses.CommonTables())
+ case InsertBeingSQLFragment:
+ isg.InsertBeginSQL(b, clauses.OnConflict())
+ case IntoSQLFragment:
+ b.WriteRunes(isg.DialectOptions().SpaceRune)
+ isg.ExpressionSQLGenerator().Generate(b, clauses.Into())
+ case InsertSQLFragment:
+ isg.InsertSQL(b, clauses)
+ case ReturningSQLFragment:
+ isg.ReturningSQL(b, clauses.Returning())
+ default:
+ b.SetError(ErrNotSupportedFragment("INSERT", f))
+ }
+ }
+}
+
+// Adds the correct fragment to being an INSERT statement
+func (isg *insertSQLGenerator) InsertBeginSQL(b sb.SQLBuilder, o exp.ConflictExpression) {
+ if isg.DialectOptions().SupportsInsertIgnoreSyntax && o != nil {
+ b.Write(isg.DialectOptions().InsertIgnoreClause)
+ } else {
+ b.Write(isg.DialectOptions().InsertClause)
+ }
+}
+
+// Adds the columns list to an insert statement
+func (isg *insertSQLGenerator) InsertSQL(b sb.SQLBuilder, ic exp.InsertClauses) {
+ switch {
+ case ic.HasRows():
+ ie, err := exp.NewInsertExpression(ic.Rows()...)
+ if err != nil {
+ b.SetError(err)
+ return
+ }
+ isg.InsertExpressionSQL(b, ie)
+ case ic.HasCols() && ic.HasVals():
+ isg.insertColumnsSQL(b, ic.Cols())
+ isg.insertValuesSQL(b, ic.Vals())
+ case ic.HasCols() && ic.HasFrom():
+ isg.insertColumnsSQL(b, ic.Cols())
+ isg.insertFromSQL(b, ic.From())
+ case ic.HasFrom():
+ isg.insertFromSQL(b, ic.From())
+ default:
+ isg.defaultValuesSQL(b)
+ }
+ if ic.HasAlias() {
+ b.Write(isg.DialectOptions().AsFragment)
+ isg.ExpressionSQLGenerator().Generate(b, ic.Alias())
+ }
+ isg.onConflictSQL(b, ic.OnConflict())
+}
+
+func (isg *insertSQLGenerator) InsertExpressionSQL(b sb.SQLBuilder, ie exp.InsertExpression) {
+ switch {
+ case ie.IsInsertFrom():
+ isg.insertFromSQL(b, ie.From())
+ case ie.IsEmpty():
+ isg.defaultValuesSQL(b)
+ default:
+ isg.insertColumnsSQL(b, ie.Cols())
+ isg.insertValuesSQL(b, ie.Vals())
+ }
+}
+
+// Adds the DefaultValuesFragment to an SQL statement
+func (isg *insertSQLGenerator) defaultValuesSQL(b sb.SQLBuilder) {
+ b.Write(isg.DialectOptions().DefaultValuesFragment)
+}
+
+func (isg *insertSQLGenerator) insertFromSQL(b sb.SQLBuilder, ae exp.AppendableExpression) {
+ b.WriteRunes(isg.DialectOptions().SpaceRune)
+ ae.AppendSQL(b)
+}
+
+// Adds the columns list to an insert statement
+func (isg *insertSQLGenerator) insertColumnsSQL(b sb.SQLBuilder, cols exp.ColumnListExpression) {
+ b.WriteRunes(isg.DialectOptions().SpaceRune, isg.DialectOptions().LeftParenRune)
+ isg.ExpressionSQLGenerator().Generate(b, cols)
+ b.WriteRunes(isg.DialectOptions().RightParenRune)
+}
+
+// Adds the values clause to an SQL statement
+func (isg *insertSQLGenerator) insertValuesSQL(b sb.SQLBuilder, values [][]interface{}) {
+ b.Write(isg.DialectOptions().ValuesFragment)
+ rowLen := len(values[0])
+ valueLen := len(values)
+ for i, row := range values {
+ if len(row) != rowLen {
+ b.SetError(errMisMatchedRowLength(rowLen, len(row)))
+ return
+ }
+ isg.ExpressionSQLGenerator().Generate(b, row)
+ if i < valueLen-1 {
+ b.WriteRunes(isg.DialectOptions().CommaRune, isg.DialectOptions().SpaceRune)
+ }
+ }
+}
+
+// Adds the DefaultValuesFragment to an SQL statement
+func (isg *insertSQLGenerator) onConflictSQL(b sb.SQLBuilder, o exp.ConflictExpression) {
+ if o == nil {
+ return
+ }
+ b.Write(isg.DialectOptions().ConflictFragment)
+ switch t := o.(type) {
+ case exp.ConflictUpdateExpression:
+ target := t.TargetColumn()
+ if isg.DialectOptions().SupportsConflictTarget && target != "" {
+ wrapParens := !strings.HasPrefix(strings.ToLower(target), "on constraint")
+
+ b.WriteRunes(isg.DialectOptions().SpaceRune)
+ if wrapParens {
+ b.WriteRunes(isg.DialectOptions().LeftParenRune).
+ WriteStrings(target).
+ WriteRunes(isg.DialectOptions().RightParenRune)
+ } else {
+ b.Write([]byte(target))
+ }
+ }
+ isg.onConflictDoUpdateSQL(b, t)
+ default:
+ b.Write(isg.DialectOptions().ConflictDoNothingFragment)
+ }
+}
+
+func (isg *insertSQLGenerator) onConflictDoUpdateSQL(b sb.SQLBuilder, o exp.ConflictUpdateExpression) {
+ b.Write(isg.DialectOptions().ConflictDoUpdateFragment)
+ update := o.Update()
+ if update == nil {
+ b.SetError(ErrConflictUpdateValuesRequired)
+ return
+ }
+ ue, err := exp.NewUpdateExpressions(update)
+ if err != nil {
+ b.SetError(err)
+ return
+ }
+ isg.UpdateExpressionSQL(b, ue...)
+ if b.Error() == nil && o.WhereClause() != nil {
+ if !isg.DialectOptions().SupportsConflictUpdateWhere {
+ b.SetError(errUpsertWithWhereNotSupported(isg.Dialect()))
+ return
+ }
+ isg.WhereSQL(b, o.WhereClause())
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/select_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/select_sql_generator.go
new file mode 100644
index 000000000..de322910e
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/select_sql_generator.go
@@ -0,0 +1,266 @@
+package sqlgen
+
+import (
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type (
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ SelectSQLGenerator interface {
+ Dialect() string
+ Generate(b sb.SQLBuilder, clauses exp.SelectClauses)
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ selectSQLGenerator struct {
+ CommonSQLGenerator
+ }
+)
+
+func ErrNotSupportedJoinType(j exp.JoinExpression) error {
+ return errors.New("dialect does not support %v", j.JoinType())
+}
+
+func ErrJoinConditionRequired(j exp.JoinExpression) error {
+ return errors.New("join condition required for conditioned join %v", j.JoinType())
+}
+
+func ErrDistinctOnNotSupported(dialect string) error {
+ return errors.New("dialect does not support DISTINCT ON clause [dialect=%s]", dialect)
+}
+
+func ErrWindowNotSupported(dialect string) error {
+ return errors.New("dialect does not support WINDOW clause [dialect=%s]", dialect)
+}
+
+var ErrNoWindowName = errors.New("window expresion has no valid name")
+
+func NewSelectSQLGenerator(dialect string, do *SQLDialectOptions) SelectSQLGenerator {
+ return &selectSQLGenerator{NewCommonSQLGenerator(dialect, do)}
+}
+
+func (ssg *selectSQLGenerator) Generate(b sb.SQLBuilder, clauses exp.SelectClauses) {
+ for _, f := range ssg.DialectOptions().SelectSQLOrder {
+ if b.Error() != nil {
+ return
+ }
+ switch f {
+ case CommonTableSQLFragment:
+ ssg.ExpressionSQLGenerator().Generate(b, clauses.CommonTables())
+ case SelectSQLFragment:
+ ssg.SelectSQL(b, clauses)
+ case SelectWithLimitSQLFragment:
+ ssg.SelectWithLimitSQL(b, clauses)
+ case FromSQLFragment:
+ ssg.FromSQL(b, clauses.From())
+ case JoinSQLFragment:
+ ssg.JoinSQL(b, clauses.Joins())
+ case WhereSQLFragment:
+ ssg.WhereSQL(b, clauses.Where())
+ case GroupBySQLFragment:
+ ssg.GroupBySQL(b, clauses.GroupBy())
+ case HavingSQLFragment:
+ ssg.HavingSQL(b, clauses.Having())
+ case WindowSQLFragment:
+ ssg.WindowSQL(b, clauses.Windows())
+ case CompoundsSQLFragment:
+ ssg.CompoundsSQL(b, clauses.Compounds())
+ case OrderSQLFragment:
+ ssg.OrderSQL(b, clauses.Order())
+ case OrderWithOffsetFetchSQLFragment:
+ ssg.OrderWithOffsetFetchSQL(b, clauses.Order(), clauses.Offset(), clauses.Limit())
+ case LimitSQLFragment:
+ ssg.LimitSQL(b, clauses.Limit())
+ case OffsetSQLFragment:
+ ssg.OffsetSQL(b, clauses.Offset())
+ case ForSQLFragment:
+ ssg.ForSQL(b, clauses.Lock())
+ default:
+ b.SetError(ErrNotSupportedFragment("SELECT", f))
+ }
+ }
+}
+
+func (ssg *selectSQLGenerator) selectSQLCommon(b sb.SQLBuilder, clauses exp.SelectClauses) {
+ dc := clauses.Distinct()
+ if dc != nil {
+ b.Write(ssg.DialectOptions().DistinctFragment)
+ if !dc.IsEmpty() {
+ if ssg.DialectOptions().SupportsDistinctOn {
+ b.Write(ssg.DialectOptions().OnFragment).WriteRunes(ssg.DialectOptions().LeftParenRune)
+ ssg.ExpressionSQLGenerator().Generate(b, dc)
+ b.WriteRunes(ssg.DialectOptions().RightParenRune, ssg.DialectOptions().SpaceRune)
+ } else {
+ b.SetError(ErrDistinctOnNotSupported(ssg.Dialect()))
+ return
+ }
+ } else {
+ b.WriteRunes(ssg.DialectOptions().SpaceRune)
+ }
+ }
+
+ if cols := clauses.Select(); clauses.IsDefaultSelect() || len(cols.Columns()) == 0 {
+ b.WriteRunes(ssg.DialectOptions().StarRune)
+ } else {
+ ssg.ExpressionSQLGenerator().Generate(b, cols)
+ }
+}
+
+// Adds the SELECT clause and columns to a sql statement
+func (ssg *selectSQLGenerator) SelectSQL(b sb.SQLBuilder, clauses exp.SelectClauses) {
+ b.Write(ssg.DialectOptions().SelectClause).WriteRunes(ssg.DialectOptions().SpaceRune)
+ ssg.selectSQLCommon(b, clauses)
+}
+
+// Adds the SELECT clause along with LIMIT to a SQL statement (e.g. MSSQL dialect: SELECT TOP 10 ...)
+func (ssg *selectSQLGenerator) SelectWithLimitSQL(b sb.SQLBuilder, clauses exp.SelectClauses) {
+ b.Write(ssg.DialectOptions().SelectClause).WriteRunes(ssg.DialectOptions().SpaceRune)
+ if clauses.Offset() == 0 && clauses.Limit() != nil {
+ ssg.LimitSQL(b, clauses.Limit())
+ b.WriteRunes(ssg.DialectOptions().SpaceRune)
+ }
+ ssg.selectSQLCommon(b, clauses)
+}
+
+// Generates the JOIN clauses for an SQL statement
+func (ssg *selectSQLGenerator) JoinSQL(b sb.SQLBuilder, joins exp.JoinExpressions) {
+ if len(joins) > 0 {
+ for _, j := range joins {
+ joinType, ok := ssg.DialectOptions().JoinTypeLookup[j.JoinType()]
+ if !ok {
+ b.SetError(ErrNotSupportedJoinType(j))
+ return
+ }
+ b.Write(joinType)
+ ssg.ExpressionSQLGenerator().Generate(b, j.Table())
+ if t, ok := j.(exp.ConditionedJoinExpression); ok {
+ if t.IsConditionEmpty() {
+ b.SetError(ErrJoinConditionRequired(j))
+ return
+ }
+ ssg.joinConditionSQL(b, t.Condition())
+ }
+ }
+ }
+}
+
+// Generates the GROUP BY clause for an SQL statement
+func (ssg *selectSQLGenerator) GroupBySQL(b sb.SQLBuilder, groupBy exp.ColumnListExpression) {
+ if groupBy != nil && len(groupBy.Columns()) > 0 {
+ b.Write(ssg.DialectOptions().GroupByFragment)
+ ssg.ExpressionSQLGenerator().Generate(b, groupBy)
+ }
+}
+
+// Generates the HAVING clause for an SQL statement
+func (ssg *selectSQLGenerator) HavingSQL(b sb.SQLBuilder, having exp.ExpressionList) {
+ if having != nil && len(having.Expressions()) > 0 {
+ b.Write(ssg.DialectOptions().HavingFragment)
+ ssg.ExpressionSQLGenerator().Generate(b, having)
+ }
+}
+
+// Generates the OFFSET clause for an SQL statement
+func (ssg *selectSQLGenerator) OffsetSQL(b sb.SQLBuilder, offset uint) {
+ if offset > 0 {
+ b.Write(ssg.DialectOptions().OffsetFragment)
+ ssg.ExpressionSQLGenerator().Generate(b, offset)
+ }
+}
+
+// Generates the compound sql clause for an SQL statement (e.g. UNION, INTERSECT)
+func (ssg *selectSQLGenerator) CompoundsSQL(b sb.SQLBuilder, compounds []exp.CompoundExpression) {
+ for _, compound := range compounds {
+ ssg.ExpressionSQLGenerator().Generate(b, compound)
+ }
+}
+
+// Generates the FOR (aka "locking") clause for an SQL statement
+func (ssg *selectSQLGenerator) ForSQL(b sb.SQLBuilder, lockingClause exp.Lock) {
+ if lockingClause == nil {
+ return
+ }
+ switch lockingClause.Strength() {
+ case exp.ForNolock:
+ return
+ case exp.ForUpdate:
+ b.Write(ssg.DialectOptions().ForUpdateFragment)
+ case exp.ForNoKeyUpdate:
+ b.Write(ssg.DialectOptions().ForNoKeyUpdateFragment)
+ case exp.ForShare:
+ b.Write(ssg.DialectOptions().ForShareFragment)
+ case exp.ForKeyShare:
+ b.Write(ssg.DialectOptions().ForKeyShareFragment)
+ }
+
+ of := lockingClause.Of()
+ if ofLen := len(of); ofLen > 0 {
+ if ofFragment := ssg.DialectOptions().OfFragment; len(ofFragment) > 0 {
+ b.Write(ofFragment)
+ for i, table := range of {
+ ssg.ExpressionSQLGenerator().Generate(b, table)
+ if i < ofLen-1 {
+ b.WriteRunes(ssg.DialectOptions().CommaRune, ssg.DialectOptions().SpaceRune)
+ }
+ }
+ b.WriteRunes(ssg.DialectOptions().SpaceRune)
+ }
+ }
+
+ // the WAIT case is the default in Postgres, and is what you get if you don't specify NOWAIT or
+ // SKIP LOCKED. There's no special syntax for it in PG, so we don't do anything for it here
+ switch lockingClause.WaitOption() {
+ case exp.Wait:
+ return
+ case exp.NoWait:
+ b.Write(ssg.DialectOptions().NowaitFragment)
+ case exp.SkipLocked:
+ b.Write(ssg.DialectOptions().SkipLockedFragment)
+ }
+}
+
+func (ssg *selectSQLGenerator) WindowSQL(b sb.SQLBuilder, windows []exp.WindowExpression) {
+ weLen := len(windows)
+ if weLen == 0 {
+ return
+ }
+ if !ssg.DialectOptions().SupportsWindowFunction {
+ b.SetError(ErrWindowNotSupported(ssg.Dialect()))
+ return
+ }
+ b.Write(ssg.DialectOptions().WindowFragment)
+ for i, we := range windows {
+ if !we.HasName() {
+ b.SetError(ErrNoWindowName)
+ }
+ ssg.ExpressionSQLGenerator().Generate(b, we)
+ if i < weLen-1 {
+ b.WriteRunes(ssg.DialectOptions().CommaRune, ssg.DialectOptions().SpaceRune)
+ }
+ }
+}
+
+func (ssg *selectSQLGenerator) joinConditionSQL(b sb.SQLBuilder, jc exp.JoinCondition) {
+ switch t := jc.(type) {
+ case exp.JoinOnCondition:
+ ssg.joinOnConditionSQL(b, t)
+ case exp.JoinUsingCondition:
+ ssg.joinUsingConditionSQL(b, t)
+ }
+}
+
+func (ssg *selectSQLGenerator) joinUsingConditionSQL(b sb.SQLBuilder, jc exp.JoinUsingCondition) {
+ b.Write(ssg.DialectOptions().UsingFragment).
+ WriteRunes(ssg.DialectOptions().LeftParenRune)
+ ssg.ExpressionSQLGenerator().Generate(b, jc.Using())
+ b.WriteRunes(ssg.DialectOptions().RightParenRune)
+}
+
+func (ssg *selectSQLGenerator) joinOnConditionSQL(b sb.SQLBuilder, jc exp.JoinOnCondition) {
+ b.Write(ssg.DialectOptions().OnFragment)
+ ssg.ExpressionSQLGenerator().Generate(b, jc.On())
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/sql_dialect_options.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/sql_dialect_options.go
new file mode 100644
index 000000000..a0df394e4
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/sql_dialect_options.go
@@ -0,0 +1,607 @@
+package sqlgen
+
+import (
+ "fmt"
+ "time"
+
+ "github.com/doug-martin/goqu/v9/exp"
+)
+
+type (
+ SQLFragmentType int
+ SQLDialectOptions struct {
+ // Set to true if the dialect supports ORDER BY expressions in DELETE statements (DEFAULT=false)
+ SupportsOrderByOnDelete bool
+ // Set to true if the dialect supports table hint for DELETE statements (DELETE t FROM t ...), DEFAULT=false
+ SupportsDeleteTableHint bool
+ // Set to true if the dialect supports ORDER BY expressions in UPDATE statements (DEFAULT=false)
+ SupportsOrderByOnUpdate bool
+ // Set to true if the dialect supports LIMIT expressions in DELETE statements (DEFAULT=false)
+ SupportsLimitOnDelete bool
+ // Set to true if the dialect supports LIMIT expressions in UPDATE statements (DEFAULT=false)
+ SupportsLimitOnUpdate bool
+ // Set to true if the dialect supports RETURN expressions (DEFAULT=true)
+ SupportsReturn bool
+ // Set to true if the dialect supports Conflict Target (DEFAULT=true)
+ SupportsConflictTarget bool
+ // Set to true if the dialect supports Conflict Target (DEFAULT=true)
+ SupportsConflictUpdateWhere bool
+ // Set to true if the dialect supports Insert Ignore syntax (DEFAULT=false)
+ SupportsInsertIgnoreSyntax bool
+ // Set to true if the dialect supports Common Table Expressions (DEFAULT=true)
+ SupportsWithCTE bool
+ // Set to true if the dialect supports recursive Common Table Expressions (DEFAULT=true)
+ SupportsWithCTERecursive bool
+ // Set to true if multiple tables are supported in UPDATE statement. (DEFAULT=true)
+ SupportsMultipleUpdateTables bool
+ // Set to true if DISTINCT ON is supported (DEFAULT=true)
+ SupportsDistinctOn bool
+ // Set to true if LATERAL queries are supported (DEFAULT=true)
+ SupportsLateral bool
+ // Set to false if the dialect does not require expressions to be wrapped in parens (DEFAULT=true)
+ WrapCompoundsInParens bool
+
+ // Set to true if window function are supported in SELECT statement. (DEFAULT=true)
+ SupportsWindowFunction bool
+
+ // Set to true if the dialect requires join tables in UPDATE to be in a FROM clause (DEFAULT=true).
+ UseFromClauseForMultipleUpdateTables bool
+
+ // Surround LIMIT parameter with parentheses, like in MSSQL: SELECT TOP (10) ...
+ SurroundLimitWithParentheses bool
+
+ // The UPDATE fragment to use when generating sql. (DEFAULT=[]byte("UPDATE"))
+ UpdateClause []byte
+ // The INSERT fragment to use when generating sql. (DEFAULT=[]byte("INSERT INTO"))
+ InsertClause []byte
+ // The INSERT IGNORE INTO fragment to use when generating sql. (DEFAULT=[]byte("INSERT IGNORE INTO"))
+ InsertIgnoreClause []byte
+ // The SELECT fragment to use when generating sql. (DEFAULT=[]byte("SELECT"))
+ SelectClause []byte
+ // The DELETE fragment to use when generating sql. (DEFAULT=[]byte("DELETE"))
+ DeleteClause []byte
+ // The TRUNCATE fragment to use when generating sql. (DEFAULT=[]byte("TRUNCATE"))
+ TruncateClause []byte
+ // The WITH fragment to use when generating sql. (DEFAULT=[]byte("WITH "))
+ WithFragment []byte
+ // The RECURSIVE fragment to use when generating sql (after WITH). (DEFAULT=[]byte("RECURSIVE "))
+ RecursiveFragment []byte
+ // The CASCADE fragment to use when generating sql. (DEFAULT=[]byte(" CASCADE"))
+ CascadeFragment []byte
+ // The RESTRICT fragment to use when generating sql. (DEFAULT=[]byte(" RESTRICT"))
+ RestrictFragment []byte
+ // The SQL fragment to use when generating insert sql and using
+ // DEFAULT VALUES (e.g. postgres="DEFAULT VALUES", mysql="", sqlite3=""). (DEFAULT=[]byte(" DEFAULT VALUES"))
+ DefaultValuesFragment []byte
+ // The SQL fragment to use when generating insert sql and listing columns using a VALUES clause
+ // (DEFAULT=[]byte(" VALUES "))
+ ValuesFragment []byte
+ // The SQL fragment to use when generating truncate sql and using the IDENTITY clause
+ // (DEFAULT=[]byte(" IDENTITY"))
+ IdentityFragment []byte
+ // The SQL fragment to use when generating update sql and using the SET clause (DEFAULT=[]byte(" SET "))
+ SetFragment []byte
+ // The SQL DISTINCT keyword (DEFAULT=[]byte(" DISTINCT "))
+ DistinctFragment []byte
+ // The SQL RETURNING clause (DEFAULT=[]byte(" RETURNING "))
+ ReturningFragment []byte
+ // The SQL FROM clause fragment (DEFAULT=[]byte(" FROM"))
+ FromFragment []byte
+ // The SQL USING join clause fragment (DEFAULT=[]byte(" USING "))
+ UsingFragment []byte
+ // The SQL ON join clause fragment (DEFAULT=[]byte(" ON "))
+ OnFragment []byte
+ // The SQL WHERE clause fragment (DEFAULT=[]byte(" WHERE "))
+ WhereFragment []byte
+ // The SQL GROUP BY clause fragment(DEFAULT=[]byte(" GROUP BY "))
+ GroupByFragment []byte
+ // The SQL HAVING clause fragment(DEFAULT=[]byte(" HAVING "))
+ HavingFragment []byte
+ // The SQL WINDOW clause fragment(DEFAULT=[]byte(" WINDOW "))
+ WindowFragment []byte
+ // The SQL WINDOW clause PARTITION BY fragment(DEFAULT=[]byte("PARTITION BY "))
+ WindowPartitionByFragment []byte
+ // The SQL WINDOW clause ORDER BY fragment(DEFAULT=[]byte("ORDER BY "))
+ WindowOrderByFragment []byte
+ // The SQL WINDOW clause OVER fragment(DEFAULT=[]byte(" OVER "))
+ WindowOverFragment []byte
+ // The SQL ORDER BY clause fragment(DEFAULT=[]byte(" ORDER BY "))
+ OrderByFragment []byte
+ // The SQL FETCH fragment(DEFAULT=[]byte(" "))
+ FetchFragment []byte
+ // The SQL LIMIT BY clause fragment(DEFAULT=[]byte(" LIMIT "))
+ LimitFragment []byte
+ // The SQL OFFSET BY clause fragment(DEFAULT=[]byte(" OFFSET "))
+ OffsetFragment []byte
+ // The SQL FOR UPDATE fragment(DEFAULT=[]byte(" FOR UPDATE "))
+ ForUpdateFragment []byte
+ // The SQL FOR NO KEY UPDATE fragment(DEFAULT=[]byte(" FOR NO KEY UPDATE "))
+ ForNoKeyUpdateFragment []byte
+ // The SQL FOR SHARE fragment(DEFAULT=[]byte(" FOR SHARE "))
+ ForShareFragment []byte
+ // The SQL OF fragment(DEFAULT=[]byte("OF "))
+ OfFragment []byte
+ // The SQL FOR KEY SHARE fragment(DEFAULT=[]byte(" FOR KEY SHARE "))
+ ForKeyShareFragment []byte
+ // The SQL NOWAIT fragment(DEFAULT=[]byte("NOWAIT"))
+ NowaitFragment []byte
+ // The SQL SKIP LOCKED fragment(DEFAULT=[]byte("SKIP LOCKED"))
+ SkipLockedFragment []byte
+ // The SQL AS fragment when aliasing an Expression(DEFAULT=[]byte(" AS "))
+ AsFragment []byte
+ // The SQL LATERAL fragment used for LATERAL joins
+ LateralFragment []byte
+ // The quote rune to use when quoting identifiers(DEFAULT='"')
+ QuoteRune rune
+ // The NULL literal to use when interpolating nulls values (DEFAULT=[]byte("NULL"))
+ Null []byte
+ // The TRUE literal to use when interpolating bool true values (DEFAULT=[]byte("TRUE"))
+ True []byte
+ // The FALSE literal to use when interpolating bool false values (DEFAULT=[]byte("FALSE"))
+ False []byte
+ // The ASC fragment when specifying column order (DEFAULT=[]byte(" ASC"))
+ AscFragment []byte
+ // The DESC fragment when specifying column order (DEFAULT=[]byte(" DESC"))
+ DescFragment []byte
+ // The NULLS FIRST fragment when specifying column order (DEFAULT=[]byte(" NULLS FIRST"))
+ NullsFirstFragment []byte
+ // The NULLS LAST fragment when specifying column order (DEFAULT=[]byte(" NULLS LAST"))
+ NullsLastFragment []byte
+ // The AND keyword used when joining ExpressionLists (DEFAULT=[]byte(" AND "))
+ AndFragment []byte
+ // The OR keyword used when joining ExpressionLists (DEFAULT=[]byte(" OR "))
+ OrFragment []byte
+ // The UNION keyword used when creating compound statements (DEFAULT=[]byte(" UNION "))
+ UnionFragment []byte
+ // The UNION ALL keyword used when creating compound statements (DEFAULT=[]byte(" UNION ALL "))
+ UnionAllFragment []byte
+ // The INTERSECT keyword used when creating compound statements (DEFAULT=[]byte(" INTERSECT "))
+ IntersectFragment []byte
+ // The INTERSECT ALL keyword used when creating compound statements (DEFAULT=[]byte(" INTERSECT ALL "))
+ IntersectAllFragment []byte
+ // The CAST keyword to use when casting a value (DEFAULT=[]byte("CAST"))
+ CastFragment []byte
+ // The CASE keyword to use when when creating a CASE statement (DEFAULT=[]byte("CASE "))
+ CaseFragment []byte
+ // The WHEN keyword to use when when creating a CASE statement (DEFAULT=[]byte(" WHEN "))
+ WhenFragment []byte
+ // The THEN keyword to use when when creating a CASE statement (DEFAULT=[]byte(" THEN "))
+ ThenFragment []byte
+ // The ELSE keyword to use when when creating a CASE statement (DEFAULT=[]byte(" ELSE "))
+ ElseFragment []byte
+ // The End keyword to use when when creating a CASE statement (DEFAULT=[]byte(" END"))
+ EndFragment []byte
+ // The quote rune to use when quoting string literals (DEFAULT='\'')
+ StringQuote rune
+ // The operator to use when setting values in an update statement (DEFAULT='=')
+ SetOperatorRune rune
+ // The placeholder fragment to use when generating a non interpolated statement (DEFAULT=[]byte"?")
+ PlaceHolderFragment []byte
+ // Empty string (DEFAULT="")
+ EmptyString string
+ // Comma rune (DEFAULT=',')
+ CommaRune rune
+ // Space rune (DEFAULT=' ')
+ SpaceRune rune
+ // Left paren rune (DEFAULT='(')
+ LeftParenRune rune
+ // Right paren rune (DEFAULT=')')
+ RightParenRune rune
+ // Star rune (DEFAULT='*')
+ StarRune rune
+ // Period rune (DEFAULT='.')
+ PeriodRune rune
+ // Set to true to include positional argument numbers when creating a prepared statement (Default=false)
+ IncludePlaceholderNum bool
+ // The time format to use when serializing time.Time (DEFAULT=time.RFC3339Nano)
+ TimeFormat string
+ // A map used to look up BooleanOperations and their SQL equivalents
+ // (Default= map[exp.BooleanOperation][]byte{
+ // exp.EqOp: []byte("="),
+ // exp.NeqOp: []byte("!="),
+ // exp.GtOp: []byte(">"),
+ // exp.GteOp: []byte(">="),
+ // exp.LtOp: []byte("<"),
+ // exp.LteOp: []byte("<="),
+ // exp.InOp: []byte("IN"),
+ // exp.NotInOp: []byte("NOT IN"),
+ // exp.IsOp: []byte("IS"),
+ // exp.IsNotOp: []byte("IS NOT"),
+ // exp.LikeOp: []byte("LIKE"),
+ // exp.NotLikeOp: []byte("NOT LIKE"),
+ // exp.ILikeOp: []byte("ILIKE"),
+ // exp.NotILikeOp: []byte("NOT ILIKE"),
+ // exp.RegexpLikeOp: []byte("~"),
+ // exp.RegexpNotLikeOp: []byte("!~"),
+ // exp.RegexpILikeOp: []byte("~*"),
+ // exp.RegexpNotILikeOp: []byte("!~*"),
+ // })
+ BooleanOperatorLookup map[exp.BooleanOperation][]byte
+ // A map used to look up BitwiseOperations and their SQL equivalents
+ // (Default=map[exp.BitwiseOperation][]byte{
+ // exp.BitwiseInversionOp: []byte("~"),
+ // exp.BitwiseOrOp: []byte("|"),
+ // exp.BitwiseAndOp: []byte("&"),
+ // exp.BitwiseXorOp: []byte("#"),
+ // exp.BitwiseLeftShiftOp: []byte("<<"),
+ // exp.BitwiseRightShiftOp: []byte(">>"),
+ // }),
+ BitwiseOperatorLookup map[exp.BitwiseOperation][]byte
+ // A map used to look up RangeOperations and their SQL equivalents
+ // (Default=map[exp.RangeOperation][]byte{
+ // exp.BetweenOp: []byte("BETWEEN"),
+ // exp.NotBetweenOp: []byte("NOT BETWEEN"),
+ // })
+ RangeOperatorLookup map[exp.RangeOperation][]byte
+ // A map used to look up JoinTypes and their SQL equivalents
+ // (Default= map[exp.JoinType][]byte{
+ // exp.InnerJoinType: []byte(" INNER JOIN "),
+ // exp.FullOuterJoinType: []byte(" FULL OUTER JOIN "),
+ // exp.RightOuterJoinType: []byte(" RIGHT OUTER JOIN "),
+ // exp.LeftOuterJoinType: []byte(" LEFT OUTER JOIN "),
+ // exp.FullJoinType: []byte(" FULL JOIN "),
+ // exp.RightJoinType: []byte(" RIGHT JOIN "),
+ // exp.LeftJoinType: []byte(" LEFT JOIN "),
+ // exp.NaturalJoinType: []byte(" NATURAL JOIN "),
+ // exp.NaturalLeftJoinType: []byte(" NATURAL LEFT JOIN "),
+ // exp.NaturalRightJoinType: []byte(" NATURAL RIGHT JOIN "),
+ // exp.NaturalFullJoinType: []byte(" NATURAL FULL JOIN "),
+ // exp.CrossJoinType: []byte(" CROSS JOIN "),
+ // })
+ JoinTypeLookup map[exp.JoinType][]byte
+ // Whether or not boolean data type is supported
+ BooleanDataTypeSupported bool
+ // Whether or not to use literal TRUE or FALSE for IS statements (e.g. IS TRUE or IS 0)
+ UseLiteralIsBools bool
+ // EscapedRunes is a map of a rune and the corresponding escape sequence in bytes. Used when escaping text
+ // types.
+ // (Default= map[rune][]byte{
+ // '\'': []byte("''"),
+ // })
+ EscapedRunes map[rune][]byte
+
+ // The SQL fragment to use for CONFLICT (Default=[]byte(" ON CONFLICT"))
+ ConflictFragment []byte
+ // The SQL fragment to use for CONFLICT DO NOTHING (Default=[]byte(" DO NOTHING"))
+ ConflictDoNothingFragment []byte
+ // The SQL fragment to use for CONFLICT DO UPDATE (Default=[]byte(" DO UPDATE SET"))
+ ConflictDoUpdateFragment []byte
+
+ // The order of SQL fragments when creating a SELECT statement
+ // (Default=[]SQLFragmentType{
+ // CommonTableSQLFragment,
+ // SelectSQLFragment,
+ // FromSQLFragment,
+ // JoinSQLFragment,
+ // WhereSQLFragment,
+ // GroupBySQLFragment,
+ // HavingSQLFragment,
+ // CompoundsSQLFragment,
+ // OrderSQLFragment,
+ // LimitSQLFragment,
+ // OffsetSQLFragment,
+ // ForSQLFragment,
+ // })
+ SelectSQLOrder []SQLFragmentType
+
+ // The order of SQL fragments when creating an UPDATE statement
+ // (Default=[]SQLFragmentType{
+ // CommonTableSQLFragment,
+ // UpdateBeginSQLFragment,
+ // SourcesSQLFragment,
+ // UpdateSQLFragment,
+ // WhereSQLFragment,
+ // OrderSQLFragment,
+ // LimitSQLFragment,
+ // ReturningSQLFragment,
+ // })
+ UpdateSQLOrder []SQLFragmentType
+
+ // The order of SQL fragments when creating an INSERT statement
+ // (Default=[]SQLFragmentType{
+ // CommonTableSQLFragment,
+ // InsertBeingSQLFragment,
+ // SourcesSQLFragment,
+ // InsertSQLFragment,
+ // ReturningSQLFragment,
+ // })
+ InsertSQLOrder []SQLFragmentType
+
+ // The order of SQL fragments when creating a DELETE statement
+ // (Default=[]SQLFragmentType{
+ // CommonTableSQLFragment,
+ // DeleteBeginSQLFragment,
+ // FromSQLFragment,
+ // WhereSQLFragment,
+ // OrderSQLFragment,
+ // LimitSQLFragment,
+ // ReturningSQLFragment,
+ // })
+ DeleteSQLOrder []SQLFragmentType
+
+ // The order of SQL fragments when creating a TRUNCATE statement
+ // (Default=[]SQLFragmentType{
+ // TruncateSQLFragment,
+ // })
+ TruncateSQLOrder []SQLFragmentType
+ }
+)
+
+const (
+ CommonTableSQLFragment = iota
+ SelectSQLFragment
+ SelectWithLimitSQLFragment
+ FromSQLFragment
+ JoinSQLFragment
+ WhereSQLFragment
+ GroupBySQLFragment
+ HavingSQLFragment
+ CompoundsSQLFragment
+ OrderSQLFragment
+ OrderWithOffsetFetchSQLFragment
+ LimitSQLFragment
+ OffsetSQLFragment
+ ForSQLFragment
+ UpdateBeginSQLFragment
+ SourcesSQLFragment
+ IntoSQLFragment
+ UpdateSQLFragment
+ UpdateFromSQLFragment
+ ReturningSQLFragment
+ InsertBeingSQLFragment
+ InsertSQLFragment
+ DeleteBeginSQLFragment
+ TruncateSQLFragment
+ WindowSQLFragment
+)
+
+// nolint:gocyclo // simple type to string conversion
+func (sf SQLFragmentType) String() string {
+ switch sf {
+ case CommonTableSQLFragment:
+ return "CommonTableSQLFragment"
+ case SelectSQLFragment:
+ return "SelectSQLFragment"
+ case FromSQLFragment:
+ return "FromSQLFragment"
+ case JoinSQLFragment:
+ return "JoinSQLFragment"
+ case WhereSQLFragment:
+ return "WhereSQLFragment"
+ case GroupBySQLFragment:
+ return "GroupBySQLFragment"
+ case HavingSQLFragment:
+ return "HavingSQLFragment"
+ case CompoundsSQLFragment:
+ return "CompoundsSQLFragment"
+ case OrderSQLFragment:
+ return "OrderSQLFragment"
+ case LimitSQLFragment:
+ return "LimitSQLFragment"
+ case OffsetSQLFragment:
+ return "OffsetSQLFragment"
+ case ForSQLFragment:
+ return "ForSQLFragment"
+ case UpdateBeginSQLFragment:
+ return "UpdateBeginSQLFragment"
+ case SourcesSQLFragment:
+ return "SourcesSQLFragment"
+ case IntoSQLFragment:
+ return "IntoSQLFragment"
+ case UpdateSQLFragment:
+ return "UpdateSQLFragment"
+ case UpdateFromSQLFragment:
+ return "UpdateFromSQLFragment"
+ case ReturningSQLFragment:
+ return "ReturningSQLFragment"
+ case InsertBeingSQLFragment:
+ return "InsertBeingSQLFragment"
+ case DeleteBeginSQLFragment:
+ return "DeleteBeginSQLFragment"
+ case TruncateSQLFragment:
+ return "TruncateSQLFragment"
+ case WindowSQLFragment:
+ return "WindowSQLFragment"
+ }
+ return fmt.Sprintf("%d", sf)
+}
+
+//nolint:funlen
+func DefaultDialectOptions() *SQLDialectOptions {
+ return &SQLDialectOptions{
+ SupportsOrderByOnDelete: false,
+ SupportsDeleteTableHint: false,
+ SupportsOrderByOnUpdate: false,
+ SupportsLimitOnDelete: false,
+ SupportsLimitOnUpdate: false,
+ SupportsReturn: true,
+ SupportsConflictUpdateWhere: true,
+ SupportsInsertIgnoreSyntax: false,
+ SupportsConflictTarget: true,
+ SupportsWithCTE: true,
+ SupportsWithCTERecursive: true,
+ SupportsDistinctOn: true,
+ WrapCompoundsInParens: true,
+ SupportsWindowFunction: true,
+ SupportsLateral: true,
+
+ SupportsMultipleUpdateTables: true,
+ UseFromClauseForMultipleUpdateTables: true,
+
+ UpdateClause: []byte("UPDATE"),
+ InsertClause: []byte("INSERT INTO"),
+ InsertIgnoreClause: []byte("INSERT IGNORE INTO"),
+ SelectClause: []byte("SELECT"),
+ DeleteClause: []byte("DELETE"),
+ TruncateClause: []byte("TRUNCATE"),
+ WithFragment: []byte("WITH "),
+ RecursiveFragment: []byte("RECURSIVE "),
+ CascadeFragment: []byte(" CASCADE"),
+ RestrictFragment: []byte(" RESTRICT"),
+ DefaultValuesFragment: []byte(" DEFAULT VALUES"),
+ ValuesFragment: []byte(" VALUES "),
+ IdentityFragment: []byte(" IDENTITY"),
+ SetFragment: []byte(" SET "),
+ DistinctFragment: []byte("DISTINCT"),
+ ReturningFragment: []byte(" RETURNING "),
+ FromFragment: []byte(" FROM"),
+ UsingFragment: []byte(" USING "),
+ OnFragment: []byte(" ON "),
+ WhereFragment: []byte(" WHERE "),
+ GroupByFragment: []byte(" GROUP BY "),
+ HavingFragment: []byte(" HAVING "),
+ WindowFragment: []byte(" WINDOW "),
+ WindowPartitionByFragment: []byte("PARTITION BY "),
+ WindowOrderByFragment: []byte("ORDER BY "),
+ WindowOverFragment: []byte(" OVER "),
+ OrderByFragment: []byte(" ORDER BY "),
+ FetchFragment: []byte(" "),
+ LimitFragment: []byte(" LIMIT "),
+ OffsetFragment: []byte(" OFFSET "),
+ ForUpdateFragment: []byte(" FOR UPDATE "),
+ ForNoKeyUpdateFragment: []byte(" FOR NO KEY UPDATE "),
+ ForShareFragment: []byte(" FOR SHARE "),
+ ForKeyShareFragment: []byte(" FOR KEY SHARE "),
+ OfFragment: []byte("OF "),
+ NowaitFragment: []byte("NOWAIT"),
+ SkipLockedFragment: []byte("SKIP LOCKED"),
+ LateralFragment: []byte("LATERAL "),
+ AsFragment: []byte(" AS "),
+ AscFragment: []byte(" ASC"),
+ DescFragment: []byte(" DESC"),
+ NullsFirstFragment: []byte(" NULLS FIRST"),
+ NullsLastFragment: []byte(" NULLS LAST"),
+ AndFragment: []byte(" AND "),
+ OrFragment: []byte(" OR "),
+ UnionFragment: []byte(" UNION "),
+ UnionAllFragment: []byte(" UNION ALL "),
+ IntersectFragment: []byte(" INTERSECT "),
+ IntersectAllFragment: []byte(" INTERSECT ALL "),
+ ConflictFragment: []byte(" ON CONFLICT"),
+ ConflictDoUpdateFragment: []byte(" DO UPDATE SET "),
+ ConflictDoNothingFragment: []byte(" DO NOTHING"),
+ CastFragment: []byte("CAST"),
+ CaseFragment: []byte("CASE "),
+ WhenFragment: []byte(" WHEN "),
+ ThenFragment: []byte(" THEN "),
+ ElseFragment: []byte(" ELSE "),
+ EndFragment: []byte(" END"),
+ Null: []byte("NULL"),
+ True: []byte("TRUE"),
+ False: []byte("FALSE"),
+
+ PlaceHolderFragment: []byte("?"),
+ QuoteRune: '"',
+ StringQuote: '\'',
+ SetOperatorRune: '=',
+ CommaRune: ',',
+ SpaceRune: ' ',
+ LeftParenRune: '(',
+ RightParenRune: ')',
+ StarRune: '*',
+ PeriodRune: '.',
+ EmptyString: "",
+
+ BooleanOperatorLookup: map[exp.BooleanOperation][]byte{
+ exp.EqOp: []byte("="),
+ exp.NeqOp: []byte("!="),
+ exp.GtOp: []byte(">"),
+ exp.GteOp: []byte(">="),
+ exp.LtOp: []byte("<"),
+ exp.LteOp: []byte("<="),
+ exp.InOp: []byte("IN"),
+ exp.NotInOp: []byte("NOT IN"),
+ exp.IsOp: []byte("IS"),
+ exp.IsNotOp: []byte("IS NOT"),
+ exp.LikeOp: []byte("LIKE"),
+ exp.NotLikeOp: []byte("NOT LIKE"),
+ exp.ILikeOp: []byte("ILIKE"),
+ exp.NotILikeOp: []byte("NOT ILIKE"),
+ exp.RegexpLikeOp: []byte("~"),
+ exp.RegexpNotLikeOp: []byte("!~"),
+ exp.RegexpILikeOp: []byte("~*"),
+ exp.RegexpNotILikeOp: []byte("!~*"),
+ },
+ BitwiseOperatorLookup: map[exp.BitwiseOperation][]byte{
+ exp.BitwiseInversionOp: []byte("~"),
+ exp.BitwiseOrOp: []byte("|"),
+ exp.BitwiseAndOp: []byte("&"),
+ exp.BitwiseXorOp: []byte("#"),
+ exp.BitwiseLeftShiftOp: []byte("<<"),
+ exp.BitwiseRightShiftOp: []byte(">>"),
+ },
+ RangeOperatorLookup: map[exp.RangeOperation][]byte{
+ exp.BetweenOp: []byte("BETWEEN"),
+ exp.NotBetweenOp: []byte("NOT BETWEEN"),
+ },
+ JoinTypeLookup: map[exp.JoinType][]byte{
+ exp.InnerJoinType: []byte(" INNER JOIN "),
+ exp.FullOuterJoinType: []byte(" FULL OUTER JOIN "),
+ exp.RightOuterJoinType: []byte(" RIGHT OUTER JOIN "),
+ exp.LeftOuterJoinType: []byte(" LEFT OUTER JOIN "),
+ exp.FullJoinType: []byte(" FULL JOIN "),
+ exp.RightJoinType: []byte(" RIGHT JOIN "),
+ exp.LeftJoinType: []byte(" LEFT JOIN "),
+ exp.NaturalJoinType: []byte(" NATURAL JOIN "),
+ exp.NaturalLeftJoinType: []byte(" NATURAL LEFT JOIN "),
+ exp.NaturalRightJoinType: []byte(" NATURAL RIGHT JOIN "),
+ exp.NaturalFullJoinType: []byte(" NATURAL FULL JOIN "),
+ exp.CrossJoinType: []byte(" CROSS JOIN "),
+ },
+
+ TimeFormat: time.RFC3339Nano,
+
+ BooleanDataTypeSupported: true,
+ UseLiteralIsBools: true,
+
+ EscapedRunes: map[rune][]byte{
+ '\'': []byte("''"),
+ },
+
+ SelectSQLOrder: []SQLFragmentType{
+ CommonTableSQLFragment,
+ SelectSQLFragment,
+ FromSQLFragment,
+ JoinSQLFragment,
+ WhereSQLFragment,
+ GroupBySQLFragment,
+ HavingSQLFragment,
+ WindowSQLFragment,
+ CompoundsSQLFragment,
+ OrderSQLFragment,
+ LimitSQLFragment,
+ OffsetSQLFragment,
+ ForSQLFragment,
+ },
+ UpdateSQLOrder: []SQLFragmentType{
+ CommonTableSQLFragment,
+ UpdateBeginSQLFragment,
+ SourcesSQLFragment,
+ UpdateSQLFragment,
+ UpdateFromSQLFragment,
+ WhereSQLFragment,
+ OrderSQLFragment,
+ LimitSQLFragment,
+ ReturningSQLFragment,
+ },
+ InsertSQLOrder: []SQLFragmentType{
+ CommonTableSQLFragment,
+ InsertBeingSQLFragment,
+ IntoSQLFragment,
+ InsertSQLFragment,
+ ReturningSQLFragment,
+ },
+ DeleteSQLOrder: []SQLFragmentType{
+ CommonTableSQLFragment,
+ DeleteBeginSQLFragment,
+ FromSQLFragment,
+ WhereSQLFragment,
+ OrderSQLFragment,
+ LimitSQLFragment,
+ ReturningSQLFragment,
+ },
+ TruncateSQLOrder: []SQLFragmentType{
+ TruncateSQLFragment,
+ },
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/sqlgen.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/sqlgen.go
new file mode 100644
index 000000000..09757115b
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/sqlgen.go
@@ -0,0 +1,15 @@
+package sqlgen
+
+import "time"
+
+var timeLocation = time.UTC
+
+// Set the location to use when interpolating time.Time instances. See https://golang.org/pkg/time/#LoadLocation
+// NOTE: This has no effect when using prepared statements.
+func SetTimeLocation(loc *time.Location) {
+ timeLocation = loc
+}
+
+func GetTimeLocation() *time.Location {
+ return timeLocation
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/truncate_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/truncate_sql_generator.go
new file mode 100644
index 000000000..a2a6b41bb
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/truncate_sql_generator.go
@@ -0,0 +1,64 @@
+package sqlgen
+
+import (
+ "strings"
+
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type (
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ TruncateSQLGenerator interface {
+ Dialect() string
+ Generate(b sb.SQLBuilder, clauses exp.TruncateClauses)
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ truncateSQLGenerator struct {
+ CommonSQLGenerator
+ }
+)
+
+var errNoSourceForTruncate = errors.New("no source found when generating truncate sql")
+
+func NewTruncateSQLGenerator(dialect string, do *SQLDialectOptions) TruncateSQLGenerator {
+ return &truncateSQLGenerator{NewCommonSQLGenerator(dialect, do)}
+}
+
+func (tsg *truncateSQLGenerator) Generate(b sb.SQLBuilder, clauses exp.TruncateClauses) {
+ if !clauses.HasTable() {
+ b.SetError(errNoSourceForTruncate)
+ return
+ }
+ for _, f := range tsg.DialectOptions().TruncateSQLOrder {
+ if b.Error() != nil {
+ return
+ }
+ switch f {
+ case TruncateSQLFragment:
+ tsg.TruncateSQL(b, clauses.Table(), clauses.Options())
+ default:
+ b.SetError(ErrNotSupportedFragment("TRUNCATE", f))
+ }
+ }
+}
+
+// Generates a TRUNCATE statement
+func (tsg *truncateSQLGenerator) TruncateSQL(b sb.SQLBuilder, from exp.ColumnListExpression, opts exp.TruncateOptions) {
+ b.Write(tsg.DialectOptions().TruncateClause)
+ tsg.SourcesSQL(b, from)
+ if opts.Identity != tsg.DialectOptions().EmptyString {
+ b.WriteRunes(tsg.DialectOptions().SpaceRune).
+ WriteStrings(strings.ToUpper(opts.Identity)).
+ Write(tsg.DialectOptions().IdentityFragment)
+ }
+ if opts.Cascade {
+ b.Write(tsg.DialectOptions().CascadeFragment)
+ } else if opts.Restrict {
+ b.Write(tsg.DialectOptions().RestrictFragment)
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/sqlgen/update_sql_generator.go b/vendor/github.com/doug-martin/goqu/v9/sqlgen/update_sql_generator.go
new file mode 100644
index 000000000..3bf7b88ef
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/sqlgen/update_sql_generator.go
@@ -0,0 +1,112 @@
+package sqlgen
+
+import (
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type (
+ // An adapter interface to be used by a Dataset to generate SQL for a specific dialect.
+ // See DefaultAdapter for a concrete implementation and examples.
+ UpdateSQLGenerator interface {
+ Dialect() string
+ Generate(b sb.SQLBuilder, clauses exp.UpdateClauses)
+ }
+ // The default adapter. This class should be used when building a new adapter. When creating a new adapter you can
+ // either override methods, or more typically update default values.
+ // See (github.com/doug-martin/goqu/dialect/postgres)
+ updateSQLGenerator struct {
+ CommonSQLGenerator
+ }
+)
+
+var (
+ ErrNoSourceForUpdate = errors.New("no source found when generating update sql")
+ ErrNoSetValuesForUpdate = errors.New("no set values found when generating UPDATE sql")
+)
+
+func NewUpdateSQLGenerator(dialect string, do *SQLDialectOptions) UpdateSQLGenerator {
+ return &updateSQLGenerator{NewCommonSQLGenerator(dialect, do)}
+}
+
+func (usg *updateSQLGenerator) Generate(b sb.SQLBuilder, clauses exp.UpdateClauses) {
+ if !clauses.HasTable() {
+ b.SetError(ErrNoSourceForUpdate)
+ return
+ }
+ if !clauses.HasSetValues() {
+ b.SetError(ErrNoSetValuesForUpdate)
+ return
+ }
+ if !usg.DialectOptions().SupportsMultipleUpdateTables && clauses.HasFrom() {
+ b.SetError(errors.New("%s dialect does not support multiple tables in UPDATE", usg.Dialect()))
+ }
+ updates, err := exp.NewUpdateExpressions(clauses.SetValues())
+ if err != nil {
+ b.SetError(err)
+ return
+ }
+ for _, f := range usg.DialectOptions().UpdateSQLOrder {
+ if b.Error() != nil {
+ return
+ }
+ switch f {
+ case CommonTableSQLFragment:
+ usg.ExpressionSQLGenerator().Generate(b, clauses.CommonTables())
+ case UpdateBeginSQLFragment:
+ usg.UpdateBeginSQL(b)
+ case SourcesSQLFragment:
+ usg.updateTableSQL(b, clauses)
+ case UpdateSQLFragment:
+ usg.UpdateExpressionsSQL(b, updates...)
+ case UpdateFromSQLFragment:
+ usg.updateFromSQL(b, clauses.From())
+ case WhereSQLFragment:
+ usg.WhereSQL(b, clauses.Where())
+ case OrderSQLFragment:
+ if usg.DialectOptions().SupportsOrderByOnUpdate {
+ usg.OrderSQL(b, clauses.Order())
+ }
+ case LimitSQLFragment:
+ if usg.DialectOptions().SupportsLimitOnUpdate {
+ usg.LimitSQL(b, clauses.Limit())
+ }
+ case ReturningSQLFragment:
+ usg.ReturningSQL(b, clauses.Returning())
+ default:
+ b.SetError(ErrNotSupportedFragment("UPDATE", f))
+ }
+ }
+}
+
+// Adds the correct fragment to being an UPDATE statement
+func (usg *updateSQLGenerator) UpdateBeginSQL(b sb.SQLBuilder) {
+ b.Write(usg.DialectOptions().UpdateClause)
+}
+
+// Adds column setters in an update SET clause
+func (usg *updateSQLGenerator) UpdateExpressionsSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression) {
+ b.Write(usg.DialectOptions().SetFragment)
+ usg.UpdateExpressionSQL(b, updates...)
+}
+
+func (usg *updateSQLGenerator) updateTableSQL(b sb.SQLBuilder, uc exp.UpdateClauses) {
+ b.WriteRunes(usg.DialectOptions().SpaceRune)
+ usg.ExpressionSQLGenerator().Generate(b, uc.Table())
+ if uc.HasFrom() {
+ if !usg.DialectOptions().UseFromClauseForMultipleUpdateTables {
+ b.WriteRunes(usg.DialectOptions().CommaRune)
+ usg.ExpressionSQLGenerator().Generate(b, uc.From())
+ }
+ }
+}
+
+func (usg *updateSQLGenerator) updateFromSQL(b sb.SQLBuilder, ce exp.ColumnListExpression) {
+ if ce == nil || ce.IsEmpty() {
+ return
+ }
+ if usg.DialectOptions().UseFromClauseForMultipleUpdateTables {
+ usg.FromSQL(b, ce)
+ }
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/truncate_dataset.go b/vendor/github.com/doug-martin/goqu/v9/truncate_dataset.go
new file mode 100644
index 000000000..fda8196bd
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/truncate_dataset.go
@@ -0,0 +1,169 @@
+package goqu
+
+import (
+ "github.com/doug-martin/goqu/v9/exec"
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type TruncateDataset struct {
+ dialect SQLDialect
+ clauses exp.TruncateClauses
+ isPrepared prepared
+ queryFactory exec.QueryFactory
+ err error
+}
+
+// used internally by database to create a database with a specific adapter
+func newTruncateDataset(d string, queryFactory exec.QueryFactory) *TruncateDataset {
+ return &TruncateDataset{
+ clauses: exp.NewTruncateClauses(),
+ dialect: GetDialect(d),
+ queryFactory: queryFactory,
+ }
+}
+
+func Truncate(table ...interface{}) *TruncateDataset {
+ return newTruncateDataset("default", nil).Table(table...)
+}
+
+// Sets the adapter used to serialize values and create the SQL statement
+func (td *TruncateDataset) WithDialect(dl string) *TruncateDataset {
+ ds := td.copy(td.GetClauses())
+ ds.dialect = GetDialect(dl)
+ return ds
+}
+
+// Set the parameter interpolation behavior. See examples
+//
+// prepared: If true the dataset WILL NOT interpolate the parameters.
+func (td *TruncateDataset) Prepared(prepared bool) *TruncateDataset {
+ ret := td.copy(td.clauses)
+ ret.isPrepared = preparedFromBool(prepared)
+ return ret
+}
+
+func (td *TruncateDataset) IsPrepared() bool {
+ return td.isPrepared.Bool()
+}
+
+// Returns the current adapter on the dataset
+func (td *TruncateDataset) Dialect() SQLDialect {
+ return td.dialect
+}
+
+// Returns the current adapter on the dataset
+func (td *TruncateDataset) SetDialect(dialect SQLDialect) *TruncateDataset {
+ cd := td.copy(td.GetClauses())
+ cd.dialect = dialect
+ return cd
+}
+
+func (td *TruncateDataset) Expression() exp.Expression {
+ return td
+}
+
+// Clones the dataset
+func (td *TruncateDataset) Clone() exp.Expression {
+ return td.copy(td.clauses)
+}
+
+// Returns the current clauses on the dataset.
+func (td *TruncateDataset) GetClauses() exp.TruncateClauses {
+ return td.clauses
+}
+
+// used interally to copy the dataset
+func (td *TruncateDataset) copy(clauses exp.TruncateClauses) *TruncateDataset {
+ return &TruncateDataset{
+ dialect: td.dialect,
+ clauses: clauses,
+ isPrepared: td.isPrepared,
+ queryFactory: td.queryFactory,
+ err: td.err,
+ }
+}
+
+// Adds a FROM clause. This return a new dataset with the original sources replaced. See examples.
+// You can pass in the following.
+// string: Will automatically be turned into an identifier
+// IdentifierExpression
+// LiteralExpression: (See Literal) Will use the literal SQL
+func (td *TruncateDataset) Table(table ...interface{}) *TruncateDataset {
+ return td.copy(td.clauses.SetTable(exp.NewColumnListExpression(table...)))
+}
+
+// Adds a CASCADE clause
+func (td *TruncateDataset) Cascade() *TruncateDataset {
+ opts := td.clauses.Options()
+ opts.Cascade = true
+ return td.copy(td.clauses.SetOptions(opts))
+}
+
+// Clears the CASCADE clause
+func (td *TruncateDataset) NoCascade() *TruncateDataset {
+ opts := td.clauses.Options()
+ opts.Cascade = false
+ return td.copy(td.clauses.SetOptions(opts))
+}
+
+// Adds a RESTRICT clause
+func (td *TruncateDataset) Restrict() *TruncateDataset {
+ opts := td.clauses.Options()
+ opts.Restrict = true
+ return td.copy(td.clauses.SetOptions(opts))
+}
+
+// Clears the RESTRICT clause
+func (td *TruncateDataset) NoRestrict() *TruncateDataset {
+ opts := td.clauses.Options()
+ opts.Restrict = false
+ return td.copy(td.clauses.SetOptions(opts))
+}
+
+// Add a IDENTITY clause (e.g. RESTART)
+func (td *TruncateDataset) Identity(identity string) *TruncateDataset {
+ opts := td.clauses.Options()
+ opts.Identity = identity
+ return td.copy(td.clauses.SetOptions(opts))
+}
+
+// Get any error that has been set or nil if no error has been set.
+func (td *TruncateDataset) Error() error {
+ return td.err
+}
+
+// Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
+// or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
+// track those separately.
+func (td *TruncateDataset) SetError(err error) *TruncateDataset {
+ if td.err == nil {
+ td.err = err
+ }
+
+ return td
+}
+
+// Generates a TRUNCATE sql statement, if Prepared has been called with true then the parameters will not be interpolated.
+// See examples.
+//
+// Errors:
+// * There is an error generating the SQL
+func (td *TruncateDataset) ToSQL() (sql string, params []interface{}, err error) {
+ return td.truncateSQLBuilder().ToSQL()
+}
+
+// Generates the TRUNCATE sql, and returns an Exec struct with the sql set to the TRUNCATE statement
+// db.From("test").Truncate().Executor().Exec()
+func (td *TruncateDataset) Executor() exec.QueryExecutor {
+ return td.queryFactory.FromSQLBuilder(td.truncateSQLBuilder())
+}
+
+func (td *TruncateDataset) truncateSQLBuilder() sb.SQLBuilder {
+ buf := sb.NewSQLBuilder(td.isPrepared.Bool())
+ if td.err != nil {
+ return buf.SetError(td.err)
+ }
+ td.dialect.ToTruncateSQL(buf, td.clauses)
+ return buf
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/update_dataset.go b/vendor/github.com/doug-martin/goqu/v9/update_dataset.go
new file mode 100644
index 000000000..e2eaa53bb
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/update_dataset.go
@@ -0,0 +1,245 @@
+package goqu
+
+import (
+ "github.com/doug-martin/goqu/v9/exec"
+ "github.com/doug-martin/goqu/v9/exp"
+ "github.com/doug-martin/goqu/v9/internal/errors"
+ "github.com/doug-martin/goqu/v9/internal/sb"
+)
+
+type UpdateDataset struct {
+ dialect SQLDialect
+ clauses exp.UpdateClauses
+ isPrepared prepared
+ queryFactory exec.QueryFactory
+ err error
+}
+
+var ErrUnsupportedUpdateTableType = errors.New("unsupported table type, a string or identifier expression is required")
+
+// used internally by database to create a database with a specific adapter
+func newUpdateDataset(d string, queryFactory exec.QueryFactory) *UpdateDataset {
+ return &UpdateDataset{
+ clauses: exp.NewUpdateClauses(),
+ dialect: GetDialect(d),
+ queryFactory: queryFactory,
+ }
+}
+
+func Update(table interface{}) *UpdateDataset {
+ return newUpdateDataset("default", nil).Table(table)
+}
+
+// Set the parameter interpolation behavior. See examples
+//
+// prepared: If true the dataset WILL NOT interpolate the parameters.
+func (ud *UpdateDataset) Prepared(prepared bool) *UpdateDataset {
+ ret := ud.copy(ud.clauses)
+ ret.isPrepared = preparedFromBool(prepared)
+ return ret
+}
+
+func (ud *UpdateDataset) IsPrepared() bool {
+ return ud.isPrepared.Bool()
+}
+
+// Sets the adapter used to serialize values and create the SQL statement
+func (ud *UpdateDataset) WithDialect(dl string) *UpdateDataset {
+ ds := ud.copy(ud.GetClauses())
+ ds.dialect = GetDialect(dl)
+ return ds
+}
+
+// Returns the current adapter on the dataset
+func (ud *UpdateDataset) Dialect() SQLDialect {
+ return ud.dialect
+}
+
+// Returns the current adapter on the dataset
+func (ud *UpdateDataset) SetDialect(dialect SQLDialect) *UpdateDataset {
+ cd := ud.copy(ud.GetClauses())
+ cd.dialect = dialect
+ return cd
+}
+
+func (ud *UpdateDataset) Expression() exp.Expression {
+ return ud
+}
+
+// Clones the dataset
+func (ud *UpdateDataset) Clone() exp.Expression {
+ return ud.copy(ud.clauses)
+}
+
+// Returns the current clauses on the dataset.
+func (ud *UpdateDataset) GetClauses() exp.UpdateClauses {
+ return ud.clauses
+}
+
+// used internally to copy the dataset
+func (ud *UpdateDataset) copy(clauses exp.UpdateClauses) *UpdateDataset {
+ return &UpdateDataset{
+ dialect: ud.dialect,
+ clauses: clauses,
+ isPrepared: ud.isPrepared,
+ queryFactory: ud.queryFactory,
+ err: ud.err,
+ }
+}
+
+// Creates a WITH clause for a common table expression (CTE).
+//
+// The name will be available to use in the UPDATE from in the associated query; and can optionally
+// contain a list of column names "name(col1, col2, col3)".
+//
+// The name will refer to the results of the specified subquery.
+func (ud *UpdateDataset) With(name string, subquery exp.Expression) *UpdateDataset {
+ return ud.copy(ud.clauses.CommonTablesAppend(exp.NewCommonTableExpression(false, name, subquery)))
+}
+
+// Creates a WITH RECURSIVE clause for a common table expression (CTE)
+//
+// The name will be available to use in the UPDATE from in the associated query; and must
+// contain a list of column names "name(col1, col2, col3)" for a recursive clause.
+//
+// The name will refer to the results of the specified subquery. The subquery for
+// a recursive query will always end with a UNION or UNION ALL with a clause that
+// refers to the CTE by name.
+func (ud *UpdateDataset) WithRecursive(name string, subquery exp.Expression) *UpdateDataset {
+ return ud.copy(ud.clauses.CommonTablesAppend(exp.NewCommonTableExpression(true, name, subquery)))
+}
+
+// Sets the table to update.
+func (ud *UpdateDataset) Table(table interface{}) *UpdateDataset {
+ switch t := table.(type) {
+ case exp.Expression:
+ return ud.copy(ud.clauses.SetTable(t))
+ case string:
+ return ud.copy(ud.clauses.SetTable(exp.ParseIdentifier(t)))
+ default:
+ panic(ErrUnsupportedUpdateTableType)
+ }
+}
+
+// Sets the values to use in the SET clause. See examples.
+func (ud *UpdateDataset) Set(values interface{}) *UpdateDataset {
+ return ud.copy(ud.clauses.SetSetValues(values))
+}
+
+// Allows specifying other tables to reference in your update (If your dialect supports it). See examples.
+func (ud *UpdateDataset) From(tables ...interface{}) *UpdateDataset {
+ return ud.copy(ud.clauses.SetFrom(exp.NewColumnListExpression(tables...)))
+}
+
+// Adds a WHERE clause. See examples.
+func (ud *UpdateDataset) Where(expressions ...exp.Expression) *UpdateDataset {
+ return ud.copy(ud.clauses.WhereAppend(expressions...))
+}
+
+// Removes the WHERE clause. See examples.
+func (ud *UpdateDataset) ClearWhere() *UpdateDataset {
+ return ud.copy(ud.clauses.ClearWhere())
+}
+
+// Adds a ORDER clause. If the ORDER is currently set it replaces it. See examples.
+func (ud *UpdateDataset) Order(order ...exp.OrderedExpression) *UpdateDataset {
+ return ud.copy(ud.clauses.SetOrder(order...))
+}
+
+// Adds a more columns to the current ORDER BY clause. If no order has be previously specified it is the same as
+// calling Order. See examples.
+func (ud *UpdateDataset) OrderAppend(order ...exp.OrderedExpression) *UpdateDataset {
+ return ud.copy(ud.clauses.OrderAppend(order...))
+}
+
+// Adds a more columns to the beginning of the current ORDER BY clause. If no order has be previously specified it is the same as
+// calling Order. See examples.
+func (ud *UpdateDataset) OrderPrepend(order ...exp.OrderedExpression) *UpdateDataset {
+ return ud.copy(ud.clauses.OrderPrepend(order...))
+}
+
+// Removes the ORDER BY clause. See examples.
+func (ud *UpdateDataset) ClearOrder() *UpdateDataset {
+ return ud.copy(ud.clauses.ClearOrder())
+}
+
+// Adds a LIMIT clause. If the LIMIT is currently set it replaces it. See examples.
+func (ud *UpdateDataset) Limit(limit uint) *UpdateDataset {
+ if limit > 0 {
+ return ud.copy(ud.clauses.SetLimit(limit))
+ }
+ return ud.copy(ud.clauses.ClearLimit())
+}
+
+// Adds a LIMIT ALL clause. If the LIMIT is currently set it replaces it. See examples.
+func (ud *UpdateDataset) LimitAll() *UpdateDataset {
+ return ud.copy(ud.clauses.SetLimit(L("ALL")))
+}
+
+// Removes the LIMIT clause.
+func (ud *UpdateDataset) ClearLimit() *UpdateDataset {
+ return ud.copy(ud.clauses.ClearLimit())
+}
+
+// Adds a RETURNING clause to the dataset if the adapter supports it. See examples.
+func (ud *UpdateDataset) Returning(returning ...interface{}) *UpdateDataset {
+ return ud.copy(ud.clauses.SetReturning(exp.NewColumnListExpression(returning...)))
+}
+
+// Get any error that has been set or nil if no error has been set.
+func (ud *UpdateDataset) Error() error {
+ return ud.err
+}
+
+// Set an error on the dataset if one has not already been set. This error will be returned by a future call to Error
+// or as part of ToSQL. This can be used by end users to record errors while building up queries without having to
+// track those separately.
+func (ud *UpdateDataset) SetError(err error) *UpdateDataset {
+ if ud.err == nil {
+ ud.err = err
+ }
+
+ return ud
+}
+
+// Generates an UPDATE sql statement, if Prepared has been called with true then the parameters will not be interpolated.
+// See examples.
+//
+// Errors:
+// * There is an error generating the SQL
+func (ud *UpdateDataset) ToSQL() (sql string, params []interface{}, err error) {
+ return ud.updateSQLBuilder().ToSQL()
+}
+
+// Appends this Dataset's UPDATE statement to the SQLBuilder
+// This is used internally when using updates in CTEs
+func (ud *UpdateDataset) AppendSQL(b sb.SQLBuilder) {
+ if ud.err != nil {
+ b.SetError(ud.err)
+ return
+ }
+ ud.dialect.ToUpdateSQL(b, ud.GetClauses())
+}
+
+func (ud *UpdateDataset) GetAs() exp.IdentifierExpression {
+ return nil
+}
+
+func (ud *UpdateDataset) ReturnsColumns() bool {
+ return ud.clauses.HasReturning()
+}
+
+// Generates the UPDATE sql, and returns an exec.QueryExecutor with the sql set to the UPDATE statement
+// db.Update("test").Set(Record{"name":"Bob", update: time.Now()}).Executor()
+func (ud *UpdateDataset) Executor() exec.QueryExecutor {
+ return ud.queryFactory.FromSQLBuilder(ud.updateSQLBuilder())
+}
+
+func (ud *UpdateDataset) updateSQLBuilder() sb.SQLBuilder {
+ buf := sb.NewSQLBuilder(ud.isPrepared.Bool())
+ if ud.err != nil {
+ return buf.SetError(ud.err)
+ }
+ ud.dialect.ToUpdateSQL(buf, ud.clauses)
+ return buf
+}
diff --git a/vendor/github.com/doug-martin/goqu/v9/wait-for-it.sh b/vendor/github.com/doug-martin/goqu/v9/wait-for-it.sh
new file mode 100644
index 000000000..92cbdbb3c
--- /dev/null
+++ b/vendor/github.com/doug-martin/goqu/v9/wait-for-it.sh
@@ -0,0 +1,182 @@
+#!/usr/bin/env bash
+# Use this script to test if a given TCP host/port are available
+
+WAITFORIT_cmdname=${0##*/}
+
+echoerr() { if [[ $WAITFORIT_QUIET -ne 1 ]]; then echo "$@" 1>&2; fi }
+
+usage()
+{
+ cat << USAGE >&2
+Usage:
+ $WAITFORIT_cmdname host:port [-s] [-t timeout] [-- command args]
+ -h HOST | --host=HOST Host or IP under test
+ -p PORT | --port=PORT TCP port under test
+ Alternatively, you specify the host and port as host:port
+ -s | --strict Only execute subcommand if the test succeeds
+ -q | --quiet Don't output any status messages
+ -t TIMEOUT | --timeout=TIMEOUT
+ Timeout in seconds, zero for no timeout
+ -- COMMAND ARGS Execute command with args after the test finishes
+USAGE
+ exit 1
+}
+
+wait_for()
+{
+ if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
+ echoerr "$WAITFORIT_cmdname: waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
+ else
+ echoerr "$WAITFORIT_cmdname: waiting for $WAITFORIT_HOST:$WAITFORIT_PORT without a timeout"
+ fi
+ WAITFORIT_start_ts=$(date +%s)
+ while :
+ do
+ if [[ $WAITFORIT_ISBUSY -eq 1 ]]; then
+ nc -z $WAITFORIT_HOST $WAITFORIT_PORT
+ WAITFORIT_result=$?
+ else
+ (echo > /dev/tcp/$WAITFORIT_HOST/$WAITFORIT_PORT) >/dev/null 2>&1
+ WAITFORIT_result=$?
+ fi
+ if [[ $WAITFORIT_result -eq 0 ]]; then
+ WAITFORIT_end_ts=$(date +%s)
+ echoerr "$WAITFORIT_cmdname: $WAITFORIT_HOST:$WAITFORIT_PORT is available after $((WAITFORIT_end_ts - WAITFORIT_start_ts)) seconds"
+ break
+ fi
+ sleep 1
+ done
+ return $WAITFORIT_result
+}
+
+wait_for_wrapper()
+{
+ # In order to support SIGINT during timeout: http://unix.stackexchange.com/a/57692
+ if [[ $WAITFORIT_QUIET -eq 1 ]]; then
+ timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --quiet --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
+ else
+ timeout $WAITFORIT_BUSYTIMEFLAG $WAITFORIT_TIMEOUT $0 --child --host=$WAITFORIT_HOST --port=$WAITFORIT_PORT --timeout=$WAITFORIT_TIMEOUT &
+ fi
+ WAITFORIT_PID=$!
+ trap "kill -INT -$WAITFORIT_PID" INT
+ wait $WAITFORIT_PID
+ WAITFORIT_RESULT=$?
+ if [[ $WAITFORIT_RESULT -ne 0 ]]; then
+ echoerr "$WAITFORIT_cmdname: timeout occurred after waiting $WAITFORIT_TIMEOUT seconds for $WAITFORIT_HOST:$WAITFORIT_PORT"
+ fi
+ return $WAITFORIT_RESULT
+}
+
+# process arguments
+while [[ $# -gt 0 ]]
+do
+ case "$1" in
+ *:* )
+ WAITFORIT_hostport=(${1//:/ })
+ WAITFORIT_HOST=${WAITFORIT_hostport[0]}
+ WAITFORIT_PORT=${WAITFORIT_hostport[1]}
+ shift 1
+ ;;
+ --child)
+ WAITFORIT_CHILD=1
+ shift 1
+ ;;
+ -q | --quiet)
+ WAITFORIT_QUIET=1
+ shift 1
+ ;;
+ -s | --strict)
+ WAITFORIT_STRICT=1
+ shift 1
+ ;;
+ -h)
+ WAITFORIT_HOST="$2"
+ if [[ $WAITFORIT_HOST == "" ]]; then break; fi
+ shift 2
+ ;;
+ --host=*)
+ WAITFORIT_HOST="${1#*=}"
+ shift 1
+ ;;
+ -p)
+ WAITFORIT_PORT="$2"
+ if [[ $WAITFORIT_PORT == "" ]]; then break; fi
+ shift 2
+ ;;
+ --port=*)
+ WAITFORIT_PORT="${1#*=}"
+ shift 1
+ ;;
+ -t)
+ WAITFORIT_TIMEOUT="$2"
+ if [[ $WAITFORIT_TIMEOUT == "" ]]; then break; fi
+ shift 2
+ ;;
+ --timeout=*)
+ WAITFORIT_TIMEOUT="${1#*=}"
+ shift 1
+ ;;
+ --)
+ shift
+ WAITFORIT_CLI=("$@")
+ break
+ ;;
+ --help)
+ usage
+ ;;
+ *)
+ echoerr "Unknown argument: $1"
+ usage
+ ;;
+ esac
+done
+
+if [[ "$WAITFORIT_HOST" == "" || "$WAITFORIT_PORT" == "" ]]; then
+ echoerr "Error: you need to provide a host and port to test."
+ usage
+fi
+
+WAITFORIT_TIMEOUT=${WAITFORIT_TIMEOUT:-15}
+WAITFORIT_STRICT=${WAITFORIT_STRICT:-0}
+WAITFORIT_CHILD=${WAITFORIT_CHILD:-0}
+WAITFORIT_QUIET=${WAITFORIT_QUIET:-0}
+
+# Check to see if timeout is from busybox?
+WAITFORIT_TIMEOUT_PATH=$(type -p timeout)
+WAITFORIT_TIMEOUT_PATH=$(realpath $WAITFORIT_TIMEOUT_PATH 2>/dev/null || readlink -f $WAITFORIT_TIMEOUT_PATH)
+
+WAITFORIT_BUSYTIMEFLAG=""
+if [[ $WAITFORIT_TIMEOUT_PATH =~ "busybox" ]]; then
+ WAITFORIT_ISBUSY=1
+ # Check if busybox timeout uses -t flag
+ # (recent Alpine versions don't support -t anymore)
+ if timeout &>/dev/stdout | grep -q -e '-t '; then
+ WAITFORIT_BUSYTIMEFLAG="-t"
+ fi
+else
+ WAITFORIT_ISBUSY=0
+fi
+
+if [[ $WAITFORIT_CHILD -gt 0 ]]; then
+ wait_for
+ WAITFORIT_RESULT=$?
+ exit $WAITFORIT_RESULT
+else
+ if [[ $WAITFORIT_TIMEOUT -gt 0 ]]; then
+ wait_for_wrapper
+ WAITFORIT_RESULT=$?
+ else
+ wait_for
+ WAITFORIT_RESULT=$?
+ fi
+fi
+
+if [[ $WAITFORIT_CLI != "" ]]; then
+ if [[ $WAITFORIT_RESULT -ne 0 && $WAITFORIT_STRICT -eq 1 ]]; then
+ echoerr "$WAITFORIT_cmdname: strict mode, refusing to execute subprocess"
+ exit $WAITFORIT_RESULT
+ fi
+ exec "${WAITFORIT_CLI[@]}"
+else
+ exit $WAITFORIT_RESULT
+fi
\ No newline at end of file
diff --git a/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go b/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go
index 2b5fff3c0..0f8f75dc7 100644
--- a/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go
+++ b/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser.go
@@ -181,6 +181,7 @@ func (p *parser) parseListOfRules(context ruleContext) []css_ast.Rule {
if context.isTopLevel {
atRuleContext.charsetValidity = atRuleValid
atRuleContext.importValidity = atRuleValid
+ atRuleContext.isTopLevel = true
}
rules := []css_ast.Rule{}
didFindAtImport := false
@@ -271,9 +272,9 @@ loop:
}
if context.parseSelectors {
- rules = append(rules, p.parseSelectorRuleFrom(p.index, parseSelectorOpts{}))
+ rules = append(rules, p.parseSelectorRuleFrom(p.index, parseSelectorOpts{isTopLevel: context.isTopLevel}))
} else {
- rules = append(rules, p.parseQualifiedRuleFrom(p.index, false /* isAlreadyInvalid */))
+ rules = append(rules, p.parseQualifiedRuleFrom(p.index, parseQualifiedRuleOpts{isTopLevel: context.isTopLevel}))
}
}
@@ -681,6 +682,24 @@ var specialAtRules = map[string]atRuleKind{
// Reference: https://drafts.csswg.org/css-nesting-1/
"nest": atRuleDeclarations,
+
+ // Reference: https://drafts.csswg.org/css-fonts-4/#font-palette-values
+ "font-palette-values": atRuleDeclarations,
+
+ // Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@counter-style
+ // Reference: https://drafts.csswg.org/css-counter-styles/#the-counter-style-rule
+ "counter-style": atRuleDeclarations,
+
+ // Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-feature-values
+ // Reference: https://drafts.csswg.org/css-fonts/#font-feature-values
+ "font-feature-values": atRuleDeclarations,
+ "annotation": atRuleDeclarations,
+ "character-variant": atRuleDeclarations,
+ "historical-forms": atRuleDeclarations,
+ "ornaments": atRuleDeclarations,
+ "styleset": atRuleDeclarations,
+ "stylistic": atRuleDeclarations,
+ "swash": atRuleDeclarations,
}
type atRuleValidity uint8
@@ -697,6 +716,7 @@ type atRuleContext struct {
importValidity atRuleValidity
isDeclarationList bool
allowNesting bool
+ isTopLevel bool
}
func (p *parser) parseAtRule(context atRuleContext) css_ast.Rule {
@@ -912,7 +932,11 @@ abortRuleParser:
p.eat(css_lexer.TWhitespace)
if kind := p.current().Kind; kind != css_lexer.TSemicolon && kind != css_lexer.TOpenBrace &&
kind != css_lexer.TCloseBrace && kind != css_lexer.TEndOfFile {
- return p.parseSelectorRuleFrom(preludeStart-1, parseSelectorOpts{atNestRange: atRange, allowNesting: context.allowNesting})
+ return p.parseSelectorRuleFrom(preludeStart-1, parseSelectorOpts{
+ atNestRange: atRange,
+ allowNesting: context.allowNesting,
+ isTopLevel: context.isTopLevel,
+ })
}
case "layer":
@@ -1466,10 +1490,18 @@ func (p *parser) parseSelectorRuleFrom(preludeStart int, opts parseSelectorOpts)
}
// Otherwise, parse a generic qualified rule
- return p.parseQualifiedRuleFrom(preludeStart, true /* isAlreadyInvalid */)
+ return p.parseQualifiedRuleFrom(preludeStart, parseQualifiedRuleOpts{
+ isAlreadyInvalid: true,
+ isTopLevel: opts.isTopLevel,
+ })
}
-func (p *parser) parseQualifiedRuleFrom(preludeStart int, isAlreadyInvalid bool) css_ast.Rule {
+type parseQualifiedRuleOpts struct {
+ isAlreadyInvalid bool
+ isTopLevel bool
+}
+
+func (p *parser) parseQualifiedRuleFrom(preludeStart int, opts parseQualifiedRuleOpts) css_ast.Rule {
preludeLoc := p.tokens[preludeStart].Range.Loc
loop:
@@ -1478,6 +1510,12 @@ loop:
case css_lexer.TOpenBrace, css_lexer.TEndOfFile:
break loop
+ case css_lexer.TCloseBrace:
+ if !opts.isTopLevel {
+ break loop
+ }
+ p.parseComponentValue()
+
default:
p.parseComponentValue()
}
@@ -1490,7 +1528,7 @@ loop:
if p.eat(css_lexer.TOpenBrace) {
qualified.Rules = p.parseListOfDeclarations()
p.expect(css_lexer.TCloseBrace)
- } else if !isAlreadyInvalid {
+ } else if !opts.isAlreadyInvalid {
p.expect(css_lexer.TOpenBrace)
}
diff --git a/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser_selector.go b/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser_selector.go
index 43b14f1ca..8acb298e1 100644
--- a/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser_selector.go
+++ b/vendor/github.com/evanw/esbuild/internal/css_parser/css_parser_selector.go
@@ -51,6 +51,7 @@ func (p *parser) parseSelectorList(opts parseSelectorOpts) (list []css_ast.Compl
type parseSelectorOpts struct {
atNestRange logger.Range
allowNesting bool
+ isTopLevel bool
}
func (p *parser) parseComplexSelector(opts parseSelectorOpts) (result css_ast.ComplexSelector, ok bool, hasNestPrefix bool) {
diff --git a/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go b/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go
index 0f9fee0a5..9c0de4a27 100644
--- a/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go
+++ b/vendor/github.com/evanw/esbuild/internal/js_printer/js_printer.go
@@ -2580,6 +2580,7 @@ func (p *printer) isCallExprSuperfluous(value *js_ast.ECall) bool {
}
var ref *js_ast.Ref
+ isAnonymousFnOrClass := false
switch e := value.Args[0].Data.(type) {
case *js_ast.EIdentifier:
// "__name(foo, 'foo')"
@@ -2589,12 +2590,16 @@ func (p *printer) isCallExprSuperfluous(value *js_ast.ECall) bool {
// "__name(function foo() {}, 'foo')"
if e.Fn.Name != nil {
ref = &e.Fn.Name.Ref
+ } else {
+ isAnonymousFnOrClass = true
}
case *js_ast.EClass:
// "__name(class foo {}, 'foo')"
if e.Class.Name != nil {
ref = &e.Class.Name.Ref
+ } else {
+ isAnonymousFnOrClass = true
}
}
@@ -2604,7 +2609,7 @@ func (p *printer) isCallExprSuperfluous(value *js_ast.ECall) bool {
// let foo = __name(function() {}, "foo");
// let bar = __name(class {}, "bar");
//
- if ref == nil && p.keepNamesAssignTarget == value {
+ if ref == nil && p.keepNamesAssignTarget == value && isAnonymousFnOrClass {
ref = &p.keepNamesRef
}
diff --git a/vendor/github.com/golang-jwt/jwt/v4/claims.go b/vendor/github.com/golang-jwt/jwt/v4/claims.go
index b2dc6b2dd..9d95cad2b 100644
--- a/vendor/github.com/golang-jwt/jwt/v4/claims.go
+++ b/vendor/github.com/golang-jwt/jwt/v4/claims.go
@@ -9,10 +9,7 @@ import (
// Claims must just have a Valid method that determines
// if the token is invalid for any supported reason
type Claims interface {
- // Valid implements claim validation. The opts are function style options that can
- // be used to fine-tune the validation. The type used for the options is intentionally
- // un-exported, since its API and its naming is subject to change.
- Valid(opts ...validationOption) error
+ Valid() error
}
// RegisteredClaims are a structured version of the JWT Claims Set,
@@ -51,13 +48,13 @@ type RegisteredClaims struct {
// There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
-func (c RegisteredClaims) Valid(opts ...validationOption) error {
+func (c RegisteredClaims) Valid() error {
vErr := new(ValidationError)
now := TimeFunc()
// The claims below are optional, by default, so if they are set to the
// default value in Go, let's not fail the verification for them.
- if !c.VerifyExpiresAt(now, false, opts...) {
+ if !c.VerifyExpiresAt(now, false) {
delta := now.Sub(c.ExpiresAt.Time)
vErr.Inner = fmt.Errorf("%s by %s", ErrTokenExpired, delta)
vErr.Errors |= ValidationErrorExpired
@@ -68,7 +65,7 @@ func (c RegisteredClaims) Valid(opts ...validationOption) error {
vErr.Errors |= ValidationErrorIssuedAt
}
- if !c.VerifyNotBefore(now, false, opts...) {
+ if !c.VerifyNotBefore(now, false) {
vErr.Inner = ErrTokenNotValidYet
vErr.Errors |= ValidationErrorNotValidYet
}
@@ -88,16 +85,12 @@ func (c *RegisteredClaims) VerifyAudience(cmp string, req bool) bool {
// VerifyExpiresAt compares the exp claim against cmp (cmp < exp).
// If req is false, it will return true, if exp is unset.
-func (c *RegisteredClaims) VerifyExpiresAt(cmp time.Time, req bool, opts ...validationOption) bool {
- validator := validator{}
- for _, o := range opts {
- o(&validator)
- }
+func (c *RegisteredClaims) VerifyExpiresAt(cmp time.Time, req bool) bool {
if c.ExpiresAt == nil {
- return verifyExp(nil, cmp, req, validator.leeway)
+ return verifyExp(nil, cmp, req)
}
- return verifyExp(&c.ExpiresAt.Time, cmp, req, validator.leeway)
+ return verifyExp(&c.ExpiresAt.Time, cmp, req)
}
// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).
@@ -112,16 +105,12 @@ func (c *RegisteredClaims) VerifyIssuedAt(cmp time.Time, req bool) bool {
// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
// If req is false, it will return true, if nbf is unset.
-func (c *RegisteredClaims) VerifyNotBefore(cmp time.Time, req bool, opts ...validationOption) bool {
- validator := validator{}
- for _, o := range opts {
- o(&validator)
- }
+func (c *RegisteredClaims) VerifyNotBefore(cmp time.Time, req bool) bool {
if c.NotBefore == nil {
- return verifyNbf(nil, cmp, req, validator.leeway)
+ return verifyNbf(nil, cmp, req)
}
- return verifyNbf(&c.NotBefore.Time, cmp, req, validator.leeway)
+ return verifyNbf(&c.NotBefore.Time, cmp, req)
}
// VerifyIssuer compares the iss claim against cmp.
@@ -152,13 +141,13 @@ type StandardClaims struct {
// Valid validates time based claims "exp, iat, nbf". There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
-func (c StandardClaims) Valid(opts ...validationOption) error {
+func (c StandardClaims) Valid() error {
vErr := new(ValidationError)
now := TimeFunc().Unix()
// The claims below are optional, by default, so if they are set to the
// default value in Go, let's not fail the verification for them.
- if !c.VerifyExpiresAt(now, false, opts...) {
+ if !c.VerifyExpiresAt(now, false) {
delta := time.Unix(now, 0).Sub(time.Unix(c.ExpiresAt, 0))
vErr.Inner = fmt.Errorf("%s by %s", ErrTokenExpired, delta)
vErr.Errors |= ValidationErrorExpired
@@ -169,7 +158,7 @@ func (c StandardClaims) Valid(opts ...validationOption) error {
vErr.Errors |= ValidationErrorIssuedAt
}
- if !c.VerifyNotBefore(now, false, opts...) {
+ if !c.VerifyNotBefore(now, false) {
vErr.Inner = ErrTokenNotValidYet
vErr.Errors |= ValidationErrorNotValidYet
}
@@ -189,17 +178,13 @@ func (c *StandardClaims) VerifyAudience(cmp string, req bool) bool {
// VerifyExpiresAt compares the exp claim against cmp (cmp < exp).
// If req is false, it will return true, if exp is unset.
-func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool, opts ...validationOption) bool {
- validator := validator{}
- for _, o := range opts {
- o(&validator)
- }
+func (c *StandardClaims) VerifyExpiresAt(cmp int64, req bool) bool {
if c.ExpiresAt == 0 {
- return verifyExp(nil, time.Unix(cmp, 0), req, validator.leeway)
+ return verifyExp(nil, time.Unix(cmp, 0), req)
}
t := time.Unix(c.ExpiresAt, 0)
- return verifyExp(&t, time.Unix(cmp, 0), req, validator.leeway)
+ return verifyExp(&t, time.Unix(cmp, 0), req)
}
// VerifyIssuedAt compares the iat claim against cmp (cmp >= iat).
@@ -215,17 +200,13 @@ func (c *StandardClaims) VerifyIssuedAt(cmp int64, req bool) bool {
// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
// If req is false, it will return true, if nbf is unset.
-func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool, opts ...validationOption) bool {
- validator := validator{}
- for _, o := range opts {
- o(&validator)
- }
+func (c *StandardClaims) VerifyNotBefore(cmp int64, req bool) bool {
if c.NotBefore == 0 {
- return verifyNbf(nil, time.Unix(cmp, 0), req, validator.leeway)
+ return verifyNbf(nil, time.Unix(cmp, 0), req)
}
t := time.Unix(c.NotBefore, 0)
- return verifyNbf(&t, time.Unix(cmp, 0), req, validator.leeway)
+ return verifyNbf(&t, time.Unix(cmp, 0), req)
}
// VerifyIssuer compares the iss claim against cmp.
@@ -259,11 +240,11 @@ func verifyAud(aud []string, cmp string, required bool) bool {
return result
}
-func verifyExp(exp *time.Time, now time.Time, required bool, skew time.Duration) bool {
+func verifyExp(exp *time.Time, now time.Time, required bool) bool {
if exp == nil {
return !required
}
- return now.Before((*exp).Add(+skew))
+ return now.Before(*exp)
}
func verifyIat(iat *time.Time, now time.Time, required bool) bool {
@@ -273,12 +254,11 @@ func verifyIat(iat *time.Time, now time.Time, required bool) bool {
return now.After(*iat) || now.Equal(*iat)
}
-func verifyNbf(nbf *time.Time, now time.Time, required bool, skew time.Duration) bool {
+func verifyNbf(nbf *time.Time, now time.Time, required bool) bool {
if nbf == nil {
return !required
}
- t := (*nbf).Add(-skew)
- return now.After(t) || now.Equal(t)
+ return now.After(*nbf) || now.Equal(*nbf)
}
func verifyIss(iss string, cmp string, required bool) bool {
diff --git a/vendor/github.com/golang-jwt/jwt/v4/map_claims.go b/vendor/github.com/golang-jwt/jwt/v4/map_claims.go
index e4a080792..2700d64a0 100644
--- a/vendor/github.com/golang-jwt/jwt/v4/map_claims.go
+++ b/vendor/github.com/golang-jwt/jwt/v4/map_claims.go
@@ -34,7 +34,7 @@ func (m MapClaims) VerifyAudience(cmp string, req bool) bool {
// VerifyExpiresAt compares the exp claim against cmp (cmp <= exp).
// If req is false, it will return true, if exp is unset.
-func (m MapClaims) VerifyExpiresAt(cmp int64, req bool, opts ...validationOption) bool {
+func (m MapClaims) VerifyExpiresAt(cmp int64, req bool) bool {
cmpTime := time.Unix(cmp, 0)
v, ok := m["exp"]
@@ -42,22 +42,17 @@ func (m MapClaims) VerifyExpiresAt(cmp int64, req bool, opts ...validationOption
return !req
}
- validator := validator{}
- for _, o := range opts {
- o(&validator)
- }
-
switch exp := v.(type) {
case float64:
if exp == 0 {
- return verifyExp(nil, cmpTime, req, validator.leeway)
+ return verifyExp(nil, cmpTime, req)
}
- return verifyExp(&newNumericDateFromSeconds(exp).Time, cmpTime, req, validator.leeway)
+ return verifyExp(&newNumericDateFromSeconds(exp).Time, cmpTime, req)
case json.Number:
v, _ := exp.Float64()
- return verifyExp(&newNumericDateFromSeconds(v).Time, cmpTime, req, validator.leeway)
+ return verifyExp(&newNumericDateFromSeconds(v).Time, cmpTime, req)
}
return false
@@ -91,7 +86,7 @@ func (m MapClaims) VerifyIssuedAt(cmp int64, req bool) bool {
// VerifyNotBefore compares the nbf claim against cmp (cmp >= nbf).
// If req is false, it will return true, if nbf is unset.
-func (m MapClaims) VerifyNotBefore(cmp int64, req bool, opts ...validationOption) bool {
+func (m MapClaims) VerifyNotBefore(cmp int64, req bool) bool {
cmpTime := time.Unix(cmp, 0)
v, ok := m["nbf"]
@@ -99,22 +94,17 @@ func (m MapClaims) VerifyNotBefore(cmp int64, req bool, opts ...validationOption
return !req
}
- validator := validator{}
- for _, o := range opts {
- o(&validator)
- }
-
switch nbf := v.(type) {
case float64:
if nbf == 0 {
- return verifyNbf(nil, cmpTime, req, validator.leeway)
+ return verifyNbf(nil, cmpTime, req)
}
- return verifyNbf(&newNumericDateFromSeconds(nbf).Time, cmpTime, req, validator.leeway)
+ return verifyNbf(&newNumericDateFromSeconds(nbf).Time, cmpTime, req)
case json.Number:
v, _ := nbf.Float64()
- return verifyNbf(&newNumericDateFromSeconds(v).Time, cmpTime, req, validator.leeway)
+ return verifyNbf(&newNumericDateFromSeconds(v).Time, cmpTime, req)
}
return false
@@ -131,11 +121,11 @@ func (m MapClaims) VerifyIssuer(cmp string, req bool) bool {
// There is no accounting for clock skew.
// As well, if any of the above claims are not in the token, it will still
// be considered a valid claim.
-func (m MapClaims) Valid(opts ...validationOption) error {
+func (m MapClaims) Valid() error {
vErr := new(ValidationError)
now := TimeFunc().Unix()
- if !m.VerifyExpiresAt(now, false, opts...) {
+ if !m.VerifyExpiresAt(now, false) {
// TODO(oxisto): this should be replaced with ErrTokenExpired
vErr.Inner = errors.New("Token is expired")
vErr.Errors |= ValidationErrorExpired
@@ -147,7 +137,7 @@ func (m MapClaims) Valid(opts ...validationOption) error {
vErr.Errors |= ValidationErrorIssuedAt
}
- if !m.VerifyNotBefore(now, false, opts...) {
+ if !m.VerifyNotBefore(now, false) {
// TODO(oxisto): this should be replaced with ErrTokenNotValidYet
vErr.Inner = errors.New("Token is not valid yet")
vErr.Errors |= ValidationErrorNotValidYet
diff --git a/vendor/github.com/golang-jwt/jwt/v4/parser.go b/vendor/github.com/golang-jwt/jwt/v4/parser.go
index 6c9128e8b..2f61a69d7 100644
--- a/vendor/github.com/golang-jwt/jwt/v4/parser.go
+++ b/vendor/github.com/golang-jwt/jwt/v4/parser.go
@@ -22,8 +22,6 @@ type Parser struct {
//
// Deprecated: In future releases, this field will not be exported anymore and should be set with an option to NewParser instead.
SkipClaimsValidation bool
-
- validationOptions []validationOption
}
// NewParser creates a new Parser with the specified options
@@ -84,7 +82,8 @@ func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyf
// Validate Claims
if !p.SkipClaimsValidation {
- if err := token.Claims.Valid(p.validationOptions...); err != nil {
+ if err := token.Claims.Valid(); err != nil {
+
// If the Claims Valid returned an error, check if it is a validation error,
// If it was another error type, create a ValidationError with a generic ClaimsInvalid flag set
if e, ok := err.(*ValidationError); !ok {
diff --git a/vendor/github.com/golang-jwt/jwt/v4/parser_option.go b/vendor/github.com/golang-jwt/jwt/v4/parser_option.go
index a79766453..6ea6f9527 100644
--- a/vendor/github.com/golang-jwt/jwt/v4/parser_option.go
+++ b/vendor/github.com/golang-jwt/jwt/v4/parser_option.go
@@ -1,7 +1,5 @@
package jwt
-import "time"
-
// ParserOption is used to implement functional-style options that modify the behavior of the parser. To add
// new options, just create a function (ideally beginning with With or Without) that returns an anonymous function that
// takes a *Parser type as input and manipulates its configuration accordingly.
@@ -29,10 +27,3 @@ func WithoutClaimsValidation() ParserOption {
p.SkipClaimsValidation = true
}
}
-
-// WithLeeway returns the ParserOption for specifying the leeway window.
-func WithLeeway(d time.Duration) ParserOption {
- return func(p *Parser) {
- p.validationOptions = append(p.validationOptions, withLeeway(d))
- }
-}
diff --git a/vendor/github.com/golang-jwt/jwt/v4/validator_option.go b/vendor/github.com/golang-jwt/jwt/v4/validator_option.go
deleted file mode 100644
index eb29dc305..000000000
--- a/vendor/github.com/golang-jwt/jwt/v4/validator_option.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package jwt
-
-import "time"
-
-// validationOption is used to implement functional-style options that modify the behavior of the parser. To add
-// new options, just create a function (ideally beginning with With or Without) that returns an anonymous function that
-// takes a *validator type as input and manipulates its configuration accordingly.
-//
-// Note that this struct is (currently) un-exported, its naming is subject to change and will only be exported once
-// the API is more stable.
-type validationOption func(*validator)
-
-// validator represents options that can be used for claims validation
-//
-// Note that this struct is (currently) un-exported, its naming is subject to change and will only be exported once
-// the API is more stable.
-type validator struct {
- leeway time.Duration // Leeway to provide when validating time values
-}
-
-// withLeeway is an option to set the clock skew (leeway) window
-//
-// Note that this function is (currently) un-exported, its naming is subject to change and will only be exported once
-// the API is more stable.
-func withLeeway(d time.Duration) validationOption {
- return func(v *validator) {
- v.leeway = d
- }
-}
diff --git a/vendor/github.com/lann/builder/.gitignore b/vendor/github.com/lann/builder/.gitignore
deleted file mode 100644
index f54eb28f6..000000000
--- a/vendor/github.com/lann/builder/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*~
-\#*#
diff --git a/vendor/github.com/lann/builder/.travis.yml b/vendor/github.com/lann/builder/.travis.yml
deleted file mode 100644
index c8860f69b..000000000
--- a/vendor/github.com/lann/builder/.travis.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-language: go
-
-go:
- - '1.8'
- - '1.9'
- - '1.10'
- - tip
diff --git a/vendor/github.com/lann/builder/README.md b/vendor/github.com/lann/builder/README.md
deleted file mode 100644
index 3b18550bb..000000000
--- a/vendor/github.com/lann/builder/README.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Builder - fluent immutable builders for Go
-
-[](https://godoc.org/github.com/lann/builder)
-[](https://travis-ci.org/lann/builder)
-
-Builder was originally written for
-[Squirrel](https://github.com/lann/squirrel), a fluent SQL generator. It
-is probably the best example of Builder in action.
-
-Builder helps you write **fluent** DSLs for your libraries with method chaining:
-
-```go
-resp := ReqBuilder.
- Url("http://golang.org").
- Header("User-Agent", "Builder").
- Get()
-```
-
-Builder uses **immutable** persistent data structures
-([these](https://github.com/mndrix/ps), specifically)
-so that each step in your method chain can be reused:
-
-```go
-build := WordBuilder.AddLetters("Build")
-builder := build.AddLetters("er")
-building := build.AddLetters("ing")
-```
-
-Builder makes it easy to **build** structs using the **builder** pattern
-(*surprise!*):
-
-```go
-import "github.com/lann/builder"
-
-type Muppet struct {
- Name string
- Friends []string
-}
-
-type muppetBuilder builder.Builder
-
-func (b muppetBuilder) Name(name string) muppetBuilder {
- return builder.Set(b, "Name", name).(muppetBuilder)
-}
-
-func (b muppetBuilder) AddFriend(friend string) muppetBuilder {
- return builder.Append(b, "Friends", friend).(muppetBuilder)
-}
-
-func (b muppetBuilder) Build() Muppet {
- return builder.GetStruct(b).(Muppet)
-}
-
-var MuppetBuilder = builder.Register(muppetBuilder{}, Muppet{}).(muppetBuilder)
-```
-```go
-MuppetBuilder.
- Name("Beaker").
- AddFriend("Dr. Honeydew").
- Build()
-
-=> Muppet{Name:"Beaker", Friends:[]string{"Dr. Honeydew"}}
-```
-
-## License
-
-Builder is released under the
-[MIT License](http://www.opensource.org/licenses/MIT).
diff --git a/vendor/github.com/lann/builder/builder.go b/vendor/github.com/lann/builder/builder.go
deleted file mode 100644
index ff621406a..000000000
--- a/vendor/github.com/lann/builder/builder.go
+++ /dev/null
@@ -1,225 +0,0 @@
-// Package builder provides a method for writing fluent immutable builders.
-package builder
-
-import (
- "github.com/lann/ps"
- "go/ast"
- "reflect"
-)
-
-// Builder stores a set of named values.
-//
-// New types can be declared with underlying type Builder and used with the
-// functions in this package. See example.
-//
-// Instances of Builder should be treated as immutable. It is up to the
-// implementor to ensure mutable values set on a Builder are not mutated while
-// the Builder is in use.
-type Builder struct {
- builderMap ps.Map
-}
-
-var (
- EmptyBuilder = Builder{ps.NewMap()}
- emptyBuilderValue = reflect.ValueOf(EmptyBuilder)
-)
-
-func getBuilderMap(builder interface{}) ps.Map {
- b := convert(builder, Builder{}).(Builder)
-
- if b.builderMap == nil {
- return ps.NewMap()
- }
-
- return b.builderMap
-}
-
-// Set returns a copy of the given builder with a new value set for the given
-// name.
-//
-// Set (and all other functions taking a builder in this package) will panic if
-// the given builder's underlying type is not Builder.
-func Set(builder interface{}, name string, v interface{}) interface{} {
- b := Builder{getBuilderMap(builder).Set(name, v)}
- return convert(b, builder)
-}
-
-// Delete returns a copy of the given builder with the given named value unset.
-func Delete(builder interface{}, name string) interface{} {
- b := Builder{getBuilderMap(builder).Delete(name)}
- return convert(b, builder)
-}
-
-// Append returns a copy of the given builder with new value(s) appended to the
-// named list. If the value was previously unset or set with Set (even to a e.g.
-// slice values), the new value(s) will be appended to an empty list.
-func Append(builder interface{}, name string, vs ...interface{}) interface{} {
- return Extend(builder, name, vs)
-}
-
-// Extend behaves like Append, except it takes a single slice or array value
-// which will be concatenated to the named list.
-//
-// Unlike a variadic call to Append - which requires a []interface{} value -
-// Extend accepts slices or arrays of any type.
-//
-// Extend will panic if the given value is not a slice, array, or nil.
-func Extend(builder interface{}, name string, vs interface{}) interface{} {
- if vs == nil {
- return builder
- }
-
- maybeList, ok := getBuilderMap(builder).Lookup(name)
-
- var list ps.List
- if ok {
- list, ok = maybeList.(ps.List)
- }
- if !ok {
- list = ps.NewList()
- }
-
- forEach(vs, func(v interface{}) {
- list = list.Cons(v)
- })
-
- return Set(builder, name, list)
-}
-
-func listToSlice(list ps.List, arrayType reflect.Type) reflect.Value {
- size := list.Size()
- slice := reflect.MakeSlice(arrayType, size, size)
- for i := size - 1; i >= 0; i-- {
- val := reflect.ValueOf(list.Head())
- slice.Index(i).Set(val)
- list = list.Tail()
- }
- return slice
-}
-
-var anyArrayType = reflect.TypeOf([]interface{}{})
-
-// Get retrieves a single named value from the given builder.
-// If the value has not been set, it returns (nil, false). Otherwise, it will
-// return (value, true).
-//
-// If the named value was last set with Append or Extend, the returned value
-// will be a slice. If the given Builder has been registered with Register or
-// RegisterType and the given name is an exported field of the registered
-// struct, the returned slice will have the same type as that field. Otherwise
-// the slice will have type []interface{}. It will panic if the given name is a
-// registered struct's exported field and the value set on the Builder is not
-// assignable to the field.
-func Get(builder interface{}, name string) (interface{}, bool) {
- val, ok := getBuilderMap(builder).Lookup(name)
- if !ok {
- return nil, false
- }
-
- list, isList := val.(ps.List)
- if isList {
- arrayType := anyArrayType
-
- if ast.IsExported(name) {
- structType := getBuilderStructType(reflect.TypeOf(builder))
- if structType != nil {
- field, ok := (*structType).FieldByName(name)
- if ok {
- arrayType = field.Type
- }
- }
- }
-
- val = listToSlice(list, arrayType).Interface()
- }
-
- return val, true
-}
-
-// GetMap returns a map[string]interface{} of the values set in the given
-// builder.
-//
-// See notes on Get regarding returned slices.
-func GetMap(builder interface{}) map[string]interface{} {
- m := getBuilderMap(builder)
- structType := getBuilderStructType(reflect.TypeOf(builder))
-
- ret := make(map[string]interface{}, m.Size())
-
- m.ForEach(func(name string, val ps.Any) {
- list, isList := val.(ps.List)
- if isList {
- arrayType := anyArrayType
-
- if structType != nil {
- field, ok := (*structType).FieldByName(name)
- if ok {
- arrayType = field.Type
- }
- }
-
- val = listToSlice(list, arrayType).Interface()
- }
-
- ret[name] = val
- })
-
- return ret
-}
-
-// GetStruct builds a new struct from the given registered builder.
-// It will return nil if the given builder's type has not been registered with
-// Register or RegisterValue.
-//
-// All values set on the builder with names that start with an uppercase letter
-// (i.e. which would be exported if they were identifiers) are assigned to the
-// corresponding exported fields of the struct.
-//
-// GetStruct will panic if any of these "exported" values are not assignable to
-// their corresponding struct fields.
-func GetStruct(builder interface{}) interface{} {
- structVal := newBuilderStruct(reflect.TypeOf(builder))
- if structVal == nil {
- return nil
- }
- return scanStruct(builder, structVal)
-}
-
-// GetStructLike builds a new struct from the given builder with the same type
-// as the given struct.
-//
-// All values set on the builder with names that start with an uppercase letter
-// (i.e. which would be exported if they were identifiers) are assigned to the
-// corresponding exported fields of the struct.
-//
-// ScanStruct will panic if any of these "exported" values are not assignable to
-// their corresponding struct fields.
-func GetStructLike(builder interface{}, strct interface{}) interface{} {
- structVal := reflect.New(reflect.TypeOf(strct)).Elem()
- return scanStruct(builder, &structVal)
-}
-
-func scanStruct(builder interface{}, structVal *reflect.Value) interface{} {
- getBuilderMap(builder).ForEach(func(name string, val ps.Any) {
- if ast.IsExported(name) {
- field := structVal.FieldByName(name)
-
- var value reflect.Value
- switch v := val.(type) {
- case nil:
- switch field.Kind() {
- case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
- value = reflect.Zero(field.Type())
- }
- // nil is not valid for this Type; Set will panic
- case ps.List:
- value = listToSlice(v, field.Type())
- default:
- value = reflect.ValueOf(val)
- }
- field.Set(value)
- }
- })
-
- return structVal.Interface()
-}
diff --git a/vendor/github.com/lann/builder/reflect.go b/vendor/github.com/lann/builder/reflect.go
deleted file mode 100644
index 3b236e791..000000000
--- a/vendor/github.com/lann/builder/reflect.go
+++ /dev/null
@@ -1,24 +0,0 @@
-package builder
-
-import "reflect"
-
-func convert(from interface{}, to interface{}) interface{} {
- return reflect.
- ValueOf(from).
- Convert(reflect.TypeOf(to)).
- Interface()
-}
-
-func forEach(s interface{}, f func(interface{})) {
- val := reflect.ValueOf(s)
-
- kind := val.Kind()
- if kind != reflect.Slice && kind != reflect.Array {
- panic(&reflect.ValueError{Method: "builder.forEach", Kind: kind})
- }
-
- l := val.Len()
- for i := 0; i < l; i++ {
- f(val.Index(i).Interface())
- }
-}
diff --git a/vendor/github.com/lann/builder/registry.go b/vendor/github.com/lann/builder/registry.go
deleted file mode 100644
index 612845418..000000000
--- a/vendor/github.com/lann/builder/registry.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package builder
-
-import (
- "reflect"
- "sync"
-)
-
-var (
- registry = make(map[reflect.Type]reflect.Type)
- registryMux sync.RWMutex
-)
-
-// RegisterType maps the given builderType to a structType.
-// This mapping affects the type of slices returned by Get and is required for
-// GetStruct to work.
-//
-// Returns a Value containing an empty instance of the registered builderType.
-//
-// RegisterType will panic if builderType's underlying type is not Builder or
-// if structType's Kind is not Struct.
-func RegisterType(builderType reflect.Type, structType reflect.Type) *reflect.Value {
- registryMux.Lock()
- defer registryMux.Unlock()
- structType.NumField() // Panic if structType is not a struct
- registry[builderType] = structType
- emptyValue := emptyBuilderValue.Convert(builderType)
- return &emptyValue
-}
-
-// Register wraps RegisterType, taking instances instead of Types.
-//
-// Returns an empty instance of the registered builder type which can be used
-// as the initial value for builder expressions. See example.
-func Register(builderProto, structProto interface{}) interface{} {
- empty := RegisterType(
- reflect.TypeOf(builderProto),
- reflect.TypeOf(structProto),
- ).Interface()
- return empty
-}
-
-func getBuilderStructType(builderType reflect.Type) *reflect.Type {
- registryMux.RLock()
- defer registryMux.RUnlock()
- structType, ok := registry[builderType]
- if !ok {
- return nil
- }
- return &structType
-}
-
-func newBuilderStruct(builderType reflect.Type) *reflect.Value {
- structType := getBuilderStructType(builderType)
- if structType == nil {
- return nil
- }
- newStruct := reflect.New(*structType).Elem()
- return &newStruct
-}
diff --git a/vendor/github.com/lann/ps/LICENSE b/vendor/github.com/lann/ps/LICENSE
deleted file mode 100644
index 69f9ae8d5..000000000
--- a/vendor/github.com/lann/ps/LICENSE
+++ /dev/null
@@ -1,7 +0,0 @@
-Copyright (c) 2013 Michael Hendricks
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/lann/ps/README.md b/vendor/github.com/lann/ps/README.md
deleted file mode 100644
index 325a5b354..000000000
--- a/vendor/github.com/lann/ps/README.md
+++ /dev/null
@@ -1,10 +0,0 @@
-**This is a stable fork of https://github.com/mndrix/ps; it will not introduce breaking changes.**
-
-ps
-==
-
-Persistent data structures for Go. See the [full package documentation](http://godoc.org/github.com/lann/ps)
-
-Install with
-
- go get github.com/lann/ps
diff --git a/vendor/github.com/lann/ps/list.go b/vendor/github.com/lann/ps/list.go
deleted file mode 100644
index 48a1cebac..000000000
--- a/vendor/github.com/lann/ps/list.go
+++ /dev/null
@@ -1,93 +0,0 @@
-package ps
-
-// List is a persistent list of possibly heterogenous values.
-type List interface {
- // IsNil returns true if the list is empty
- IsNil() bool
-
- // Cons returns a new list with val as the head
- Cons(val Any) List
-
- // Head returns the first element of the list;
- // panics if the list is empty
- Head() Any
-
- // Tail returns a list with all elements except the head;
- // panics if the list is empty
- Tail() List
-
- // Size returns the list's length. This takes O(1) time.
- Size() int
-
- // ForEach executes a callback for each value in the list.
- ForEach(f func(Any))
-
- // Reverse returns a list whose elements are in the opposite order as
- // the original list.
- Reverse() List
-}
-
-// Immutable (i.e. persistent) list
-type list struct {
- depth int // the number of nodes after, and including, this one
- value Any
- tail *list
-}
-
-// An empty list shared by all lists
-var nilList = &list{}
-
-// NewList returns a new, empty list. The result is a singly linked
-// list implementation. All lists share an empty tail, so allocating
-// empty lists is efficient in time and memory.
-func NewList() List {
- return nilList
-}
-
-func (self *list) IsNil() bool {
- return self == nilList
-}
-
-func (self *list) Size() int {
- return self.depth
-}
-
-func (tail *list) Cons(val Any) List {
- var xs list
- xs.depth = tail.depth + 1
- xs.value = val
- xs.tail = tail
- return &xs
-}
-
-func (self *list) Head() Any {
- if self.IsNil() {
- panic("Called Head() on an empty list")
- }
-
- return self.value
-}
-
-func (self *list) Tail() List {
- if self.IsNil() {
- panic("Called Tail() on an empty list")
- }
-
- return self.tail
-}
-
-// ForEach executes a callback for each value in the list
-func (self *list) ForEach(f func(Any)) {
- if self.IsNil() {
- return
- }
- f(self.Head())
- self.Tail().ForEach(f)
-}
-
-// Reverse returns a list with elements in opposite order as this list
-func (self *list) Reverse() List {
- reversed := NewList()
- self.ForEach(func(v Any) { reversed = reversed.Cons(v) })
- return reversed
-}
diff --git a/vendor/github.com/lann/ps/map.go b/vendor/github.com/lann/ps/map.go
deleted file mode 100644
index 192daec8f..000000000
--- a/vendor/github.com/lann/ps/map.go
+++ /dev/null
@@ -1,311 +0,0 @@
-// Fully persistent data structures. A persistent data structure is a data
-// structure that always preserves the previous version of itself when
-// it is modified. Such data structures are effectively immutable,
-// as their operations do not update the structure in-place, but instead
-// always yield a new structure.
-//
-// Persistent
-// data structures typically share structure among themselves. This allows
-// operations to avoid copying the entire data structure.
-package ps
-
-import (
- "bytes"
- "fmt"
-)
-
-// Any is a shorthand for Go's verbose interface{} type.
-type Any interface{}
-
-// A Map associates unique keys (type string) with values (type Any).
-type Map interface {
- // IsNil returns true if the Map is empty
- IsNil() bool
-
- // Set returns a new map in which key and value are associated.
- // If the key didn't exist before, it's created; otherwise, the
- // associated value is changed.
- // This operation is O(log N) in the number of keys.
- Set(key string, value Any) Map
-
- // Delete returns a new map with the association for key, if any, removed.
- // This operation is O(log N) in the number of keys.
- Delete(key string) Map
-
- // Lookup returns the value associated with a key, if any. If the key
- // exists, the second return value is true; otherwise, false.
- // This operation is O(log N) in the number of keys.
- Lookup(key string) (Any, bool)
-
- // Size returns the number of key value pairs in the map.
- // This takes O(1) time.
- Size() int
-
- // ForEach executes a callback on each key value pair in the map.
- ForEach(f func(key string, val Any))
-
- // Keys returns a slice with all keys in this map.
- // This operation is O(N) in the number of keys.
- Keys() []string
-
- String() string
-}
-
-// Immutable (i.e. persistent) associative array
-const childCount = 8
-const shiftSize = 3
-
-type tree struct {
- count int
- hash uint64 // hash of the key (used for tree balancing)
- key string
- value Any
- children [childCount]*tree
-}
-
-var nilMap = &tree{}
-
-// Recursively set nilMap's subtrees to point at itself.
-// This eliminates all nil pointers in the map structure.
-// All map nodes are created by cloning this structure so
-// they avoid the problem too.
-func init() {
- for i := range nilMap.children {
- nilMap.children[i] = nilMap
- }
-}
-
-// NewMap allocates a new, persistent map from strings to values of
-// any type.
-// This is currently implemented as a path-copying binary tree.
-func NewMap() Map {
- return nilMap
-}
-
-func (self *tree) IsNil() bool {
- return self == nilMap
-}
-
-// clone returns an exact duplicate of a tree node
-func (self *tree) clone() *tree {
- var m tree
- m = *self
- return &m
-}
-
-// constants for FNV-1a hash algorithm
-const (
- offset64 uint64 = 14695981039346656037
- prime64 uint64 = 1099511628211
-)
-
-// hashKey returns a hash code for a given string
-func hashKey(key string) uint64 {
- hash := offset64
- for _, codepoint := range key {
- hash ^= uint64(codepoint)
- hash *= prime64
- }
- return hash
-}
-
-// Set returns a new map similar to this one but with key and value
-// associated. If the key didn't exist, it's created; otherwise, the
-// associated value is changed.
-func (self *tree) Set(key string, value Any) Map {
- hash := hashKey(key)
- return setLowLevel(self, hash, hash, key, value)
-}
-
-func setLowLevel(self *tree, partialHash, hash uint64, key string, value Any) *tree {
- if self.IsNil() { // an empty tree is easy
- m := self.clone()
- m.count = 1
- m.hash = hash
- m.key = key
- m.value = value
- return m
- }
-
- if hash != self.hash {
- m := self.clone()
- i := partialHash % childCount
- m.children[i] = setLowLevel(self.children[i], partialHash>>shiftSize, hash, key, value)
- recalculateCount(m)
- return m
- }
-
- // replacing a key's previous value
- m := self.clone()
- m.value = value
- return m
-}
-
-// modifies a map by recalculating its key count based on the counts
-// of its subtrees
-func recalculateCount(m *tree) {
- count := 0
- for _, t := range m.children {
- count += t.Size()
- }
- m.count = count + 1 // add one to count ourself
-}
-
-func (m *tree) Delete(key string) Map {
- hash := hashKey(key)
- newMap, _ := deleteLowLevel(m, hash, hash)
- return newMap
-}
-
-func deleteLowLevel(self *tree, partialHash, hash uint64) (*tree, bool) {
- // empty trees are easy
- if self.IsNil() {
- return self, false
- }
-
- if hash != self.hash {
- i := partialHash % childCount
- child, found := deleteLowLevel(self.children[i], partialHash>>shiftSize, hash)
- if !found {
- return self, false
- }
- newMap := self.clone()
- newMap.children[i] = child
- recalculateCount(newMap)
- return newMap, true // ? this wasn't in the original code
- }
-
- // we must delete our own node
- if self.isLeaf() { // we have no children
- return nilMap, true
- }
- /*
- if self.subtreeCount() == 1 { // only one subtree
- for _, t := range self.children {
- if t != nilMap {
- return t, true
- }
- }
- panic("Tree with 1 subtree actually had no subtrees")
- }
- */
-
- // find a node to replace us
- i := -1
- size := -1
- for j, t := range self.children {
- if t.Size() > size {
- i = j
- size = t.Size()
- }
- }
-
- // make chosen leaf smaller
- replacement, child := self.children[i].deleteLeftmost()
- newMap := replacement.clone()
- for j := range self.children {
- if j == i {
- newMap.children[j] = child
- } else {
- newMap.children[j] = self.children[j]
- }
- }
- recalculateCount(newMap)
- return newMap, true
-}
-
-// delete the leftmost node in a tree returning the node that
-// was deleted and the tree left over after its deletion
-func (m *tree) deleteLeftmost() (*tree, *tree) {
- if m.isLeaf() {
- return m, nilMap
- }
-
- for i, t := range m.children {
- if t != nilMap {
- deleted, child := t.deleteLeftmost()
- newMap := m.clone()
- newMap.children[i] = child
- recalculateCount(newMap)
- return deleted, newMap
- }
- }
- panic("Tree isn't a leaf but also had no children. How does that happen?")
-}
-
-// isLeaf returns true if this is a leaf node
-func (m *tree) isLeaf() bool {
- return m.Size() == 1
-}
-
-// returns the number of child subtrees we have
-func (m *tree) subtreeCount() int {
- count := 0
- for _, t := range m.children {
- if t != nilMap {
- count++
- }
- }
- return count
-}
-
-func (m *tree) Lookup(key string) (Any, bool) {
- hash := hashKey(key)
- return lookupLowLevel(m, hash, hash)
-}
-
-func lookupLowLevel(self *tree, partialHash, hash uint64) (Any, bool) {
- if self.IsNil() { // an empty tree is easy
- return nil, false
- }
-
- if hash != self.hash {
- i := partialHash % childCount
- return lookupLowLevel(self.children[i], partialHash>>shiftSize, hash)
- }
-
- // we found it
- return self.value, true
-}
-
-func (m *tree) Size() int {
- return m.count
-}
-
-func (m *tree) ForEach(f func(key string, val Any)) {
- if m.IsNil() {
- return
- }
-
- // ourself
- f(m.key, m.value)
-
- // children
- for _, t := range m.children {
- if t != nilMap {
- t.ForEach(f)
- }
- }
-}
-
-func (m *tree) Keys() []string {
- keys := make([]string, m.Size())
- i := 0
- m.ForEach(func(k string, v Any) {
- keys[i] = k
- i++
- })
- return keys
-}
-
-// make it easier to display maps for debugging
-func (m *tree) String() string {
- keys := m.Keys()
- buf := bytes.NewBufferString("{")
- for _, key := range keys {
- val, _ := m.Lookup(key)
- fmt.Fprintf(buf, "%s: %s, ", key, val)
- }
- fmt.Fprintf(buf, "}\n")
- return buf.String()
-}
diff --git a/vendor/github.com/lann/ps/profile.sh b/vendor/github.com/lann/ps/profile.sh
deleted file mode 100644
index f03df05a5..000000000
--- a/vendor/github.com/lann/ps/profile.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-go test -c
-./ps.test -test.run=none -test.bench=$2 -test.$1profile=$1.profile
diff --git a/vendor/golang.org/x/net/http2/go118.go b/vendor/golang.org/x/net/http2/go118.go
deleted file mode 100644
index aca4b2b31..000000000
--- a/vendor/golang.org/x/net/http2/go118.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.18
-// +build go1.18
-
-package http2
-
-import (
- "crypto/tls"
- "net"
-)
-
-func tlsUnderlyingConn(tc *tls.Conn) net.Conn {
- return tc.NetConn()
-}
diff --git a/vendor/golang.org/x/net/http2/not_go118.go b/vendor/golang.org/x/net/http2/not_go118.go
deleted file mode 100644
index eab532c96..000000000
--- a/vendor/golang.org/x/net/http2/not_go118.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2021 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build !go1.18
-// +build !go1.18
-
-package http2
-
-import (
- "crypto/tls"
- "net"
-)
-
-func tlsUnderlyingConn(tc *tls.Conn) net.Conn {
- return nil
-}
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 4f0989763..f135b0f75 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -735,6 +735,7 @@ func (cc *ClientConn) healthCheck() {
err := cc.Ping(ctx)
if err != nil {
cc.closeForLostPing()
+ cc.t.connPool().MarkDead(cc)
return
}
}
@@ -906,24 +907,6 @@ func (cc *ClientConn) onIdleTimeout() {
cc.closeIfIdle()
}
-func (cc *ClientConn) closeConn() error {
- t := time.AfterFunc(250*time.Millisecond, cc.forceCloseConn)
- defer t.Stop()
- return cc.tconn.Close()
-}
-
-// A tls.Conn.Close can hang for a long time if the peer is unresponsive.
-// Try to shut it down more aggressively.
-func (cc *ClientConn) forceCloseConn() {
- tc, ok := cc.tconn.(*tls.Conn)
- if !ok {
- return
- }
- if nc := tlsUnderlyingConn(tc); nc != nil {
- nc.Close()
- }
-}
-
func (cc *ClientConn) closeIfIdle() {
cc.mu.Lock()
if len(cc.streams) > 0 || cc.streamsReserved > 0 {
@@ -938,7 +921,7 @@ func (cc *ClientConn) closeIfIdle() {
if VerboseLogs {
cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2)
}
- cc.closeConn()
+ cc.tconn.Close()
}
func (cc *ClientConn) isDoNotReuseAndIdle() bool {
@@ -955,7 +938,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
return err
}
// Wait for all in-flight streams to complete or connection to close
- done := make(chan struct{})
+ done := make(chan error, 1)
cancelled := false // guarded by cc.mu
go func() {
cc.mu.Lock()
@@ -963,7 +946,7 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
for {
if len(cc.streams) == 0 || cc.closed {
cc.closed = true
- close(done)
+ done <- cc.tconn.Close()
break
}
if cancelled {
@@ -974,8 +957,8 @@ func (cc *ClientConn) Shutdown(ctx context.Context) error {
}()
shutdownEnterWaitStateHook()
select {
- case <-done:
- return cc.closeConn()
+ case err := <-done:
+ return err
case <-ctx.Done():
cc.mu.Lock()
// Free the goroutine above
@@ -1018,9 +1001,9 @@ func (cc *ClientConn) closeForError(err error) error {
for _, cs := range cc.streams {
cs.abortStreamLocked(err)
}
- cc.cond.Broadcast()
- cc.mu.Unlock()
- return cc.closeConn()
+ defer cc.cond.Broadcast()
+ defer cc.mu.Unlock()
+ return cc.tconn.Close()
}
// Close closes the client connection immediately.
@@ -1995,7 +1978,7 @@ func (cc *ClientConn) forgetStreamID(id uint32) {
cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, cc.nextStreamID-2)
}
cc.closed = true
- defer cc.closeConn()
+ defer cc.tconn.Close()
}
cc.mu.Unlock()
@@ -2042,8 +2025,8 @@ func isEOFOrNetReadError(err error) bool {
func (rl *clientConnReadLoop) cleanup() {
cc := rl.cc
- cc.t.connPool().MarkDead(cc)
- defer cc.closeConn()
+ defer cc.tconn.Close()
+ defer cc.t.connPool().MarkDead(cc)
defer close(cc.readerDone)
if cc.idleTimer != nil {
diff --git a/vendor/golang.org/x/sys/unix/ioctl_linux.go b/vendor/golang.org/x/sys/unix/ioctl_linux.go
index 884430b81..1dadead21 100644
--- a/vendor/golang.org/x/sys/unix/ioctl_linux.go
+++ b/vendor/golang.org/x/sys/unix/ioctl_linux.go
@@ -194,26 +194,3 @@ func ioctlIfreqData(fd int, req uint, value *ifreqData) error {
// identical so pass *IfreqData directly.
return ioctlPtr(fd, req, unsafe.Pointer(value))
}
-
-// IoctlKCMClone attaches a new file descriptor to a multiplexor by cloning an
-// existing KCM socket, returning a structure containing the file descriptor of
-// the new socket.
-func IoctlKCMClone(fd int) (*KCMClone, error) {
- var info KCMClone
- if err := ioctlPtr(fd, SIOCKCMCLONE, unsafe.Pointer(&info)); err != nil {
- return nil, err
- }
-
- return &info, nil
-}
-
-// IoctlKCMAttach attaches a TCP socket and associated BPF program file
-// descriptor to a multiplexor.
-func IoctlKCMAttach(fd int, info KCMAttach) error {
- return ioctlPtr(fd, SIOCKCMATTACH, unsafe.Pointer(&info))
-}
-
-// IoctlKCMUnattach unattaches a TCP socket file descriptor from a multiplexor.
-func IoctlKCMUnattach(fd int, info KCMUnattach) error {
- return ioctlPtr(fd, SIOCKCMUNATTACH, unsafe.Pointer(&info))
-}
diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh
index a03708748..a47b035f9 100644
--- a/vendor/golang.org/x/sys/unix/mkerrors.sh
+++ b/vendor/golang.org/x/sys/unix/mkerrors.sh
@@ -205,7 +205,6 @@ struct ltchars {
#include
#include
#include
-#include
#include
#include
#include
@@ -232,7 +231,6 @@ struct ltchars {
#include
#include
#include
-#include
#include
#include
#include
@@ -505,7 +503,6 @@ ccflags="$@"
$2 ~ /^O?XTABS$/ ||
$2 ~ /^TC[IO](ON|OFF)$/ ||
$2 ~ /^IN_/ ||
- $2 ~ /^KCM/ ||
$2 ~ /^LANDLOCK_/ ||
$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
@@ -600,7 +597,6 @@ ccflags="$@"
$2 ~ /^DEVLINK_/ ||
$2 ~ /^ETHTOOL_/ ||
$2 ~ /^LWTUNNEL_IP/ ||
- $2 ~ /^ITIMER_/ ||
$2 !~ "WMESGLEN" &&
$2 ~ /^W[A-Z0-9]+$/ ||
$2 ~/^PPPIOC/ ||
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 5f28f8fde..f432b0684 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -14,7 +14,6 @@ package unix
import (
"encoding/binary"
"syscall"
- "time"
"unsafe"
)
@@ -250,13 +249,6 @@ func Getwd() (wd string, err error) {
if n < 1 || n > len(buf) || buf[n-1] != 0 {
return "", EINVAL
}
- // In some cases, Linux can return a path that starts with the
- // "(unreachable)" prefix, which can potentially be a valid relative
- // path. To work around that, return ENOENT if path is not absolute.
- if buf[0] != '/' {
- return "", ENOENT
- }
-
return string(buf[0 : n-1]), nil
}
@@ -2322,56 +2314,11 @@ type RemoteIovec struct {
//sys shmdt(addr uintptr) (err error)
//sys shmget(key int, size int, flag int) (id int, err error)
-//sys getitimer(which int, currValue *Itimerval) (err error)
-//sys setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error)
-
-// MakeItimerval creates an Itimerval from interval and value durations.
-func MakeItimerval(interval, value time.Duration) Itimerval {
- return Itimerval{
- Interval: NsecToTimeval(interval.Nanoseconds()),
- Value: NsecToTimeval(value.Nanoseconds()),
- }
-}
-
-// A value which may be passed to the which parameter for Getitimer and
-// Setitimer.
-type ItimerWhich int
-
-// Possible which values for Getitimer and Setitimer.
-const (
- ItimerReal ItimerWhich = ITIMER_REAL
- ItimerVirtual ItimerWhich = ITIMER_VIRTUAL
- ItimerProf ItimerWhich = ITIMER_PROF
-)
-
-// Getitimer wraps getitimer(2) to return the current value of the timer
-// specified by which.
-func Getitimer(which ItimerWhich) (Itimerval, error) {
- var it Itimerval
- if err := getitimer(int(which), &it); err != nil {
- return Itimerval{}, err
- }
-
- return it, nil
-}
-
-// Setitimer wraps setitimer(2) to arm or disarm the timer specified by which.
-// It returns the previous value of the timer.
-//
-// If the Itimerval argument is the zero value, the timer will be disarmed.
-func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
- var prev Itimerval
- if err := setitimer(int(which), &it, &prev); err != nil {
- return Itimerval{}, err
- }
-
- return prev, nil
-}
-
/*
* Unimplemented
*/
// AfsSyscall
+// Alarm
// ArchPrctl
// Brk
// ClockNanosleep
@@ -2387,6 +2334,7 @@ func Setitimer(which ItimerWhich, it Itimerval) (Itimerval, error) {
// GetMempolicy
// GetRobustList
// GetThreadArea
+// Getitimer
// Getpmsg
// IoCancel
// IoDestroy
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_386.go b/vendor/golang.org/x/sys/unix/syscall_linux_386.go
index d44b8ad53..5f757e8aa 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_386.go
@@ -173,6 +173,14 @@ const (
_SENDMMSG = 20
)
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ fd, e := socketcall(_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), 0, 0, 0)
+ if e != 0 {
+ err = e
+ }
+ return
+}
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
fd, e := socketcall(_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
if e != 0 {
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go b/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go
deleted file mode 100644
index 08086ac6a..000000000
--- a/vendor/golang.org/x/sys/unix/syscall_linux_alarm.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2022 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build linux && (386 || amd64 || mips || mipsle || mips64 || mipsle || ppc64 || ppc64le || ppc || s390x || sparc64)
-// +build linux
-// +build 386 amd64 mips mipsle mips64 mipsle ppc64 ppc64le ppc s390x sparc64
-
-package unix
-
-// SYS_ALARM is not defined on arm or riscv, but is available for other GOARCH
-// values.
-
-//sys Alarm(seconds uint) (remaining uint, err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
index bd21d93bf..4299125aa 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_amd64.go
@@ -62,6 +62,7 @@ func Stat(path string, stat *Stat_t) (err error) {
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
index 343c91f6b..79edeb9cb 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm.go
@@ -27,6 +27,7 @@ func Seek(fd int, offset int64, whence int) (newoffset int64, err error) {
return newoffset, nil
}
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
index 8c5628684..862890de2 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_arm64.go
@@ -66,6 +66,7 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
index f0b138002..8932e34ad 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_mips64x.go
@@ -48,6 +48,7 @@ func Select(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timeval) (n int, err
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
index e6163c30f..7821c25d9 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_mipsx.go
@@ -41,6 +41,7 @@ func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr,
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
index 4740e80a8..c5053a0f0 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc.go
@@ -43,6 +43,7 @@ import (
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
//sys Truncate(path string, length int64) (err error) = SYS_TRUNCATE64
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
index 78bc9166e..25786c421 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_ppc64x.go
@@ -45,6 +45,7 @@ package unix
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys Truncate(path string, length int64) (err error)
//sys Ustat(dev int, ubuf *Ustat_t) (err error)
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
index 3d6c4eb06..6f9f71041 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_riscv64.go
@@ -65,6 +65,7 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
return ENOSYS
}
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
index 89ce84a41..6aa59cb27 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go
@@ -145,6 +145,15 @@ const (
netSendMMsg = 20
)
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (int, error) {
+ args := [3]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen))}
+ fd, _, err := Syscall(SYS_SOCKETCALL, netAccept, uintptr(unsafe.Pointer(&args)), 0)
+ if err != 0 {
+ return 0, err
+ }
+ return int(fd), nil
+}
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (int, error) {
args := [4]uintptr{uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags)}
fd, _, err := Syscall(SYS_SOCKETCALL, netAccept4, uintptr(unsafe.Pointer(&args)), 0)
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
index 35bdb098c..bbe8d174f 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux_sparc64.go
@@ -42,6 +42,7 @@ package unix
//sys Statfs(path string, buf *Statfs_t) (err error)
//sys SyncFileRange(fd int, off int64, n int64, flags int) (err error)
//sys Truncate(path string, length int64) (err error)
+//sys accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error)
//sys accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error)
//sys bind(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
//sys connect(s int, addr unsafe.Pointer, addrlen _Socklen) (err error)
diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go
index bc7c9d075..4e5420586 100644
--- a/vendor/golang.org/x/sys/unix/zerrors_linux.go
+++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go
@@ -38,8 +38,7 @@ const (
AF_KEY = 0xf
AF_LLC = 0x1a
AF_LOCAL = 0x1
- AF_MAX = 0x2e
- AF_MCTP = 0x2d
+ AF_MAX = 0x2d
AF_MPLS = 0x1c
AF_NETBEUI = 0xd
AF_NETLINK = 0x10
@@ -260,17 +259,6 @@ const (
BUS_USB = 0x3
BUS_VIRTUAL = 0x6
CAN_BCM = 0x2
- CAN_CTRLMODE_3_SAMPLES = 0x4
- CAN_CTRLMODE_BERR_REPORTING = 0x10
- CAN_CTRLMODE_CC_LEN8_DLC = 0x100
- CAN_CTRLMODE_FD = 0x20
- CAN_CTRLMODE_FD_NON_ISO = 0x80
- CAN_CTRLMODE_LISTENONLY = 0x2
- CAN_CTRLMODE_LOOPBACK = 0x1
- CAN_CTRLMODE_ONE_SHOT = 0x8
- CAN_CTRLMODE_PRESUME_ACK = 0x40
- CAN_CTRLMODE_TDC_AUTO = 0x200
- CAN_CTRLMODE_TDC_MANUAL = 0x400
CAN_EFF_FLAG = 0x80000000
CAN_EFF_ID_BITS = 0x1d
CAN_EFF_MASK = 0x1fffffff
@@ -348,7 +336,6 @@ const (
CAN_RTR_FLAG = 0x40000000
CAN_SFF_ID_BITS = 0xb
CAN_SFF_MASK = 0x7ff
- CAN_TERMINATION_DISABLED = 0x0
CAN_TP16 = 0x3
CAN_TP20 = 0x4
CAP_AUDIT_CONTROL = 0x1e
@@ -1280,14 +1267,9 @@ const (
IP_XFRM_POLICY = 0x11
ISOFS_SUPER_MAGIC = 0x9660
ISTRIP = 0x20
- ITIMER_PROF = 0x2
- ITIMER_REAL = 0x0
- ITIMER_VIRTUAL = 0x1
IUTF8 = 0x4000
IXANY = 0x800
JFFS2_SUPER_MAGIC = 0x72b6
- KCMPROTO_CONNECTED = 0x0
- KCM_RECV_DISABLE = 0x1
KEXEC_ARCH_386 = 0x30000
KEXEC_ARCH_68K = 0x40000
KEXEC_ARCH_AARCH64 = 0xb70000
@@ -2460,9 +2442,6 @@ const (
SIOCGSTAMPNS = 0x8907
SIOCGSTAMPNS_OLD = 0x8907
SIOCGSTAMP_OLD = 0x8906
- SIOCKCMATTACH = 0x89e0
- SIOCKCMCLONE = 0x89e2
- SIOCKCMUNATTACH = 0x89e1
SIOCOUTQNSD = 0x894b
SIOCPROTOPRIVATE = 0x89e0
SIOCRTMSG = 0x890d
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
index 30fa4055e..93edda4c4 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go
@@ -2032,23 +2032,3 @@ func shmget(key int, size int, flag int) (id int, err error) {
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func getitimer(which int, currValue *Itimerval) (err error) {
- _, _, e1 := Syscall(SYS_GETITIMER, uintptr(which), uintptr(unsafe.Pointer(currValue)), 0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func setitimer(which int, newValue *Itimerval, oldValue *Itimerval) (err error) {
- _, _, e1 := Syscall(SYS_SETITIMER, uintptr(which), uintptr(unsafe.Pointer(newValue)), uintptr(unsafe.Pointer(oldValue)))
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
index 2fc6271f4..ff90c81e7 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_386.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -l32 -tags linux,386 syscall_linux.go syscall_linux_386.go syscall_linux_alarm.go
+// go run mksyscall.go -l32 -tags linux,386 syscall_linux.go syscall_linux_386.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && 386
@@ -524,14 +524,3 @@ func utimes(path string, times *[2]Timeval) (err error) {
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
index 43d9f0128..fa7d3dbe4 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_amd64.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go syscall_linux_alarm.go
+// go run mksyscall.go -tags linux,amd64 syscall_linux.go syscall_linux_amd64.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && amd64
@@ -444,6 +444,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -680,14 +691,3 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
index 7df0cb179..654f91530 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm.go
@@ -46,6 +46,17 @@ func Tee(rfd int, wfd int, len int, flags int) (n int64, err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
index 076e8f1c5..e893f987f 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_arm64.go
@@ -389,6 +389,17 @@ func Truncate(path string, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
index 7b3c84746..6d1552885 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -b32 -arm -tags linux,mips syscall_linux.go syscall_linux_mipsx.go syscall_linux_alarm.go
+// go run mksyscall.go -b32 -arm -tags linux,mips syscall_linux.go syscall_linux_mipsx.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && mips
@@ -344,6 +344,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -691,14 +702,3 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
index 0d3c45fbd..1e20d72df 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags linux,mips64 syscall_linux.go syscall_linux_mips64x.go syscall_linux_alarm.go
+// go run mksyscall.go -tags linux,mips64 syscall_linux.go syscall_linux_mips64x.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && mips64
@@ -399,6 +399,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -685,14 +696,3 @@ func stat(path string, st *stat_t) (err error) {
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
index cb46b2aaa..82b5e2d9e 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mips64le.go
@@ -399,6 +399,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
index 21c9baa6a..a0440c1d4 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_mipsle.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -l32 -arm -tags linux,mipsle syscall_linux.go syscall_linux_mipsx.go syscall_linux_alarm.go
+// go run mksyscall.go -l32 -arm -tags linux,mipsle syscall_linux.go syscall_linux_mipsx.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && mipsle
@@ -344,6 +344,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -691,14 +702,3 @@ func setrlimit(resource int, rlim *rlimit32) (err error) {
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
index 02b8f0887..5864b9ca6 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -b32 -tags linux,ppc syscall_linux.go syscall_linux_ppc.go syscall_linux_alarm.go
+// go run mksyscall.go -b32 -tags linux,ppc syscall_linux.go syscall_linux_ppc.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && ppc
@@ -409,6 +409,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -696,14 +707,3 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
index ac8cb09ba..beeb49e34 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags linux,ppc64 syscall_linux.go syscall_linux_ppc64x.go syscall_linux_alarm.go
+// go run mksyscall.go -tags linux,ppc64 syscall_linux.go syscall_linux_ppc64x.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && ppc64
@@ -475,6 +475,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -742,14 +753,3 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
index bd08d887a..53139b82c 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_ppc64le.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags linux,ppc64le syscall_linux.go syscall_linux_ppc64x.go syscall_linux_alarm.go
+// go run mksyscall.go -tags linux,ppc64le syscall_linux.go syscall_linux_ppc64x.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && ppc64le
@@ -475,6 +475,17 @@ func Ustat(dev int, ubuf *Ustat_t) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -742,14 +753,3 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
index a834d2173..63b393b80 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_riscv64.go
@@ -369,6 +369,17 @@ func Truncate(path string, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
index 9e462a96f..202add37d 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_s390x.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags linux,s390x syscall_linux.go syscall_linux_s390x.go syscall_linux_alarm.go
+// go run mksyscall.go -tags linux,s390x syscall_linux.go syscall_linux_s390x.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && s390x
@@ -533,14 +533,3 @@ func kexecFileLoad(kernelFd int, initrdFd int, cmdlineLen int, cmdline string, f
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
index 96d340242..2ab268c34 100644
--- a/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
+++ b/vendor/golang.org/x/sys/unix/zsyscall_linux_sparc64.go
@@ -1,4 +1,4 @@
-// go run mksyscall.go -tags linux,sparc64 syscall_linux.go syscall_linux_sparc64.go syscall_linux_alarm.go
+// go run mksyscall.go -tags linux,sparc64 syscall_linux.go syscall_linux_sparc64.go
// Code generated by the command above; see README.md. DO NOT EDIT.
//go:build linux && sparc64
@@ -455,6 +455,17 @@ func Truncate(path string, length int64) (err error) {
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+func accept(s int, rsa *RawSockaddrAny, addrlen *_Socklen) (fd int, err error) {
+ r0, _, e1 := Syscall(SYS_ACCEPT, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)))
+ fd = int(r0)
+ if e1 != 0 {
+ err = errnoErr(e1)
+ }
+ return
+}
+
+// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
+
func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, err error) {
r0, _, e1 := Syscall6(SYS_ACCEPT4, uintptr(s), uintptr(unsafe.Pointer(rsa)), uintptr(unsafe.Pointer(addrlen)), uintptr(flags), 0, 0)
fd = int(r0)
@@ -686,14 +697,3 @@ func utimes(path string, times *[2]Timeval) (err error) {
}
return
}
-
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
-
-func Alarm(seconds uint) (remaining uint, err error) {
- r0, _, e1 := Syscall(SYS_ALARM, uintptr(seconds), 0, 0)
- remaining = uint(r0)
- if e1 != 0 {
- err = errnoErr(e1)
- }
- return
-}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go
index cbf32f718..66788f156 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go
@@ -24,11 +24,6 @@ type ItimerSpec struct {
Value Timespec
}
-type Itimerval struct {
- Interval Timeval
- Value Timeval
-}
-
const (
TIME_OK = 0x0
TIME_INS = 0x1
@@ -3771,8 +3766,6 @@ const (
ETHTOOL_A_TUNNEL_INFO_MAX = 0x2
)
-const SPEED_UNKNOWN = -0x1
-
type EthtoolDrvinfo struct {
Cmd uint32
Driver [32]byte
@@ -4072,91 +4065,3 @@ const (
NL_POLICY_TYPE_ATTR_MASK = 0xc
NL_POLICY_TYPE_ATTR_MAX = 0xc
)
-
-type CANBitTiming struct {
- Bitrate uint32
- Sample_point uint32
- Tq uint32
- Prop_seg uint32
- Phase_seg1 uint32
- Phase_seg2 uint32
- Sjw uint32
- Brp uint32
-}
-
-type CANBitTimingConst struct {
- Name [16]uint8
- Tseg1_min uint32
- Tseg1_max uint32
- Tseg2_min uint32
- Tseg2_max uint32
- Sjw_max uint32
- Brp_min uint32
- Brp_max uint32
- Brp_inc uint32
-}
-
-type CANClock struct {
- Freq uint32
-}
-
-type CANBusErrorCounters struct {
- Txerr uint16
- Rxerr uint16
-}
-
-type CANCtrlMode struct {
- Mask uint32
- Flags uint32
-}
-
-type CANDeviceStats struct {
- Bus_error uint32
- Error_warning uint32
- Error_passive uint32
- Bus_off uint32
- Arbitration_lost uint32
- Restarts uint32
-}
-
-const (
- CAN_STATE_ERROR_ACTIVE = 0x0
- CAN_STATE_ERROR_WARNING = 0x1
- CAN_STATE_ERROR_PASSIVE = 0x2
- CAN_STATE_BUS_OFF = 0x3
- CAN_STATE_STOPPED = 0x4
- CAN_STATE_SLEEPING = 0x5
- CAN_STATE_MAX = 0x6
-)
-
-const (
- IFLA_CAN_UNSPEC = 0x0
- IFLA_CAN_BITTIMING = 0x1
- IFLA_CAN_BITTIMING_CONST = 0x2
- IFLA_CAN_CLOCK = 0x3
- IFLA_CAN_STATE = 0x4
- IFLA_CAN_CTRLMODE = 0x5
- IFLA_CAN_RESTART_MS = 0x6
- IFLA_CAN_RESTART = 0x7
- IFLA_CAN_BERR_COUNTER = 0x8
- IFLA_CAN_DATA_BITTIMING = 0x9
- IFLA_CAN_DATA_BITTIMING_CONST = 0xa
- IFLA_CAN_TERMINATION = 0xb
- IFLA_CAN_TERMINATION_CONST = 0xc
- IFLA_CAN_BITRATE_CONST = 0xd
- IFLA_CAN_DATA_BITRATE_CONST = 0xe
- IFLA_CAN_BITRATE_MAX = 0xf
-)
-
-type KCMAttach struct {
- Fd int32
- Bpf_fd int32
-}
-
-type KCMUnattach struct {
- Fd int32
-}
-
-type KCMClone struct {
- Fd int32
-}
diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
index c426c3576..635880610 100644
--- a/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
+++ b/vendor/golang.org/x/sys/unix/ztypes_linux_s390x.go
@@ -210,8 +210,8 @@ type PtraceFpregs struct {
}
type PtracePer struct {
- Control_regs [3]uint64
- _ [8]byte
+ _ [0]uint64
+ _ [32]byte
Starting_addr uint64
Ending_addr uint64
Perc_atmid uint16
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 722057b37..e312c38e0 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -16,9 +16,6 @@ github.com/Masterminds/semver
# github.com/Masterminds/sprig v2.22.0+incompatible
## explicit
github.com/Masterminds/sprig
-# github.com/Masterminds/squirrel v1.5.2
-## explicit; go 1.14
-github.com/Masterminds/squirrel
# github.com/PaesslerAG/gval v1.1.2
## explicit; go 1.15
github.com/PaesslerAG/gval
@@ -82,7 +79,7 @@ github.com/disintegration/imaging
## explicit
github.com/dlclark/regexp2
github.com/dlclark/regexp2/syntax
-# github.com/dop251/goja v0.0.0-20220214123719-b09a6bfa842f
+# github.com/dop251/goja v0.0.0-20220324112439-a18ffb9c5866
## explicit; go 1.14
github.com/dop251/goja
github.com/dop251/goja/ast
@@ -92,10 +89,23 @@ github.com/dop251/goja/ftoa/internal/fast
github.com/dop251/goja/parser
github.com/dop251/goja/token
github.com/dop251/goja/unistring
+# github.com/doug-martin/goqu/v9 v9.18.0
+## explicit; go 1.12
+github.com/doug-martin/goqu/v9
+github.com/doug-martin/goqu/v9/dialect/mysql
+github.com/doug-martin/goqu/v9/dialect/postgres
+github.com/doug-martin/goqu/v9/dialect/sqlite3
+github.com/doug-martin/goqu/v9/exec
+github.com/doug-martin/goqu/v9/exp
+github.com/doug-martin/goqu/v9/internal/errors
+github.com/doug-martin/goqu/v9/internal/sb
+github.com/doug-martin/goqu/v9/internal/tag
+github.com/doug-martin/goqu/v9/internal/util
+github.com/doug-martin/goqu/v9/sqlgen
# github.com/edwvee/exiffix v0.0.0-20210922235313-0f6cbda5e58f
## explicit
github.com/edwvee/exiffix
-# github.com/evanw/esbuild v0.14.27
+# github.com/evanw/esbuild v0.14.28
## explicit; go 1.13
github.com/evanw/esbuild/internal/api_helpers
github.com/evanw/esbuild/internal/ast
@@ -183,8 +193,8 @@ github.com/goccy/go-json/internal/runtime
# github.com/golang-jwt/jwt v3.2.2+incompatible
## explicit
github.com/golang-jwt/jwt
-# github.com/golang-jwt/jwt/v4 v4.4.0
-## explicit; go 1.15
+# github.com/golang-jwt/jwt/v4 v4.4.1
+## explicit; go 1.16
github.com/golang-jwt/jwt/v4
# github.com/golang/mock v1.6.0
## explicit; go 1.11
@@ -249,12 +259,6 @@ github.com/json-iterator/go
# github.com/klauspost/cpuid v1.2.3
## explicit
github.com/klauspost/cpuid
-# github.com/lann/builder v0.0.0-20180802200727-47ae307949d0
-## explicit
-github.com/lann/builder
-# github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0
-## explicit
-github.com/lann/ps
# github.com/lestrrat-go/backoff/v2 v2.0.8
## explicit; go 1.16
github.com/lestrrat-go/backoff/v2
@@ -418,16 +422,12 @@ github.com/steinfletcher/apitest/difflib
github.com/steinfletcher/apitest-jsonpath
github.com/steinfletcher/apitest-jsonpath/http
github.com/steinfletcher/apitest-jsonpath/jsonpath
+# github.com/stretchr/objx v0.2.0
+## explicit; go 1.12
# github.com/stretchr/testify v1.7.1
## explicit; go 1.13
github.com/stretchr/testify/assert
github.com/stretchr/testify/require
-# github.com/tidwall/gjson v1.14.0
-## explicit; go 1.12
-# github.com/valyala/bytebufferpool v1.0.0
-## explicit
-# github.com/valyala/fasthttp v1.34.0
-## explicit; go 1.12
# go.uber.org/atomic v1.9.0
## explicit; go 1.13
go.uber.org/atomic
@@ -462,7 +462,7 @@ golang.org/x/image/bmp
golang.org/x/image/ccitt
golang.org/x/image/tiff
golang.org/x/image/tiff/lzw
-# golang.org/x/net v0.0.0-20220225172249-27dd8689420f
+# golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd
## explicit; go 1.17
golang.org/x/net/context
golang.org/x/net/context/ctxhttp
@@ -485,7 +485,7 @@ golang.org/x/oauth2/google/internal/externalaccount
golang.org/x/oauth2/internal
golang.org/x/oauth2/jws
golang.org/x/oauth2/jwt
-# golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9
+# golang.org/x/sys v0.0.0-20220114195835-da31bd327af9
## explicit; go 1.17
golang.org/x/sys/cpu
golang.org/x/sys/execabs