Add config driven presets for insert, update and upsert

This commit is contained in:
Vikram Rangnekar 2019-10-30 03:27:11 -04:00
parent 8ae7210e70
commit b87ba1fcd0
7 changed files with 65 additions and 38 deletions

View File

@ -169,7 +169,7 @@ roles:
insert: insert:
filters: ["{ user_id: { eq: $user_id } }"] filters: ["{ user_id: { eq: $user_id } }"]
columns: ["id", "name", "description" ] columns: ["id", "name", "description" ]
set: presets:
- created_at: "now" - created_at: "now"
update: update:
@ -177,7 +177,7 @@ roles:
columns: columns:
- id - id
- name - name
set: presets:
- updated_at: "now" - updated_at: "now"
delete: delete:

View File

@ -1,5 +1,10 @@
package qcode package qcode
import (
"sort"
"strings"
)
type Config struct { type Config struct {
Blocklist []string Blocklist []string
KeepArgs bool KeepArgs bool
@ -15,13 +20,13 @@ type QueryConfig struct {
type InsertConfig struct { type InsertConfig struct {
Filters []string Filters []string
Columns []string Columns []string
Set map[string]string Presets map[string]string
} }
type UpdateConfig struct { type UpdateConfig struct {
Filters []string Filters []string
Columns []string Columns []string
Set map[string]string Presets map[string]string
} }
type DeleteConfig struct { type DeleteConfig struct {
@ -49,13 +54,15 @@ type trval struct {
insert struct { insert struct {
fil *Exp fil *Exp
cols map[string]struct{} cols map[string]struct{}
set map[string]string psmap map[string]string
pslist []string
} }
update struct { update struct {
fil *Exp fil *Exp
cols map[string]struct{} cols map[string]struct{}
set map[string]string psmap map[string]string
pslist []string
} }
delete struct { delete struct {
@ -97,3 +104,20 @@ func (trv *trval) filter(qt QType) *Exp {
return nil return nil
} }
func listToMap(list []string) map[string]struct{} {
m := make(map[string]struct{}, len(list))
for i := range list {
m[strings.ToLower(list[i])] = struct{}{}
}
return m
}
func mapToList(m map[string]string) []string {
list := []string{}
for k, _ := range m {
list = append(list, strings.ToLower(k))
}
sort.Strings(list)
return list
}

View File

@ -46,6 +46,8 @@ type Select struct {
Children []int32 Children []int32
Functions bool Functions bool
Allowed map[string]struct{} Allowed map[string]struct{}
PresetMap map[string]string
PresetList []string
} }
type Column struct { type Column struct {
@ -182,14 +184,6 @@ func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
var err error var err error
trv := &trval{} trv := &trval{}
toMap := func(cols []string) map[string]struct{} {
m := make(map[string]struct{}, len(cols))
for i := range cols {
m[strings.ToLower(cols[i])] = struct{}{}
}
return m
}
// query config // query config
trv.query.fil, err = compileFilter(trc.Query.Filters) trv.query.fil, err = compileFilter(trc.Query.Filters)
if err != nil { if err != nil {
@ -198,27 +192,30 @@ func (com *Compiler) AddRole(role, table string, trc TRConfig) error {
if trc.Query.Limit > 0 { if trc.Query.Limit > 0 {
trv.query.limit = strconv.Itoa(trc.Query.Limit) trv.query.limit = strconv.Itoa(trc.Query.Limit)
} }
trv.query.cols = toMap(trc.Query.Columns) trv.query.cols = listToMap(trc.Query.Columns)
trv.query.disable.funcs = trc.Query.DisableFunctions trv.query.disable.funcs = trc.Query.DisableFunctions
// insert config // insert config
if trv.insert.fil, err = compileFilter(trc.Insert.Filters); err != nil { if trv.insert.fil, err = compileFilter(trc.Insert.Filters); err != nil {
return err return err
} }
trv.insert.cols = toMap(trc.Insert.Columns) trv.insert.cols = listToMap(trc.Insert.Columns)
trv.insert.psmap = trc.Insert.Presets
trv.insert.pslist = mapToList(trv.insert.psmap)
// update config // update config
if trv.update.fil, err = compileFilter(trc.Update.Filters); err != nil { if trv.update.fil, err = compileFilter(trc.Update.Filters); err != nil {
return err return err
} }
trv.insert.cols = toMap(trc.Insert.Columns) trv.update.cols = listToMap(trc.Update.Columns)
trv.insert.set = trc.Insert.Set trv.update.psmap = trc.Update.Presets
trv.update.pslist = mapToList(trv.update.psmap)
// delete config // delete config
if trv.delete.fil, err = compileFilter(trc.Delete.Filters); err != nil { if trv.delete.fil, err = compileFilter(trc.Delete.Filters); err != nil {
return err return err
} }
trv.delete.cols = toMap(trc.Delete.Columns) trv.delete.cols = listToMap(trc.Delete.Columns)
singular := flect.Singularize(table) singular := flect.Singularize(table)
plural := flect.Pluralize(table) plural := flect.Pluralize(table)
@ -302,12 +299,18 @@ func (com *Compiler) compileQuery(qc *QCode, op *Operation, role string) error {
}) })
s := &selects[(len(selects) - 1)] s := &selects[(len(selects) - 1)]
if action == QTQuery { switch action {
case QTQuery:
s.Functions = !trv.query.disable.funcs s.Functions = !trv.query.disable.funcs
if len(trv.query.limit) != 0 {
s.Paging.Limit = trv.query.limit s.Paging.Limit = trv.query.limit
}
case QTInsert:
s.PresetMap = trv.insert.psmap
s.PresetList = trv.insert.pslist
case QTUpdate:
s.PresetMap = trv.update.psmap
s.PresetList = trv.update.pslist
} }
if s.ID != 0 { if s.ID != 0 {

View File

@ -117,14 +117,14 @@ type configRole struct {
Insert struct { Insert struct {
Filters []string Filters []string
Columns []string Columns []string
Set map[string]string Presets map[string]string
Block bool Block bool
} }
Update struct { Update struct {
Filters []string Filters []string
Columns []string Columns []string
Set map[string]string Presets map[string]string
Block bool Block bool
} }

View File

@ -48,7 +48,7 @@ func initCompilers(c *config) (*qcode.Compiler, *psql.Compiler, error) {
insert := qcode.InsertConfig{ insert := qcode.InsertConfig{
Filters: t.Insert.Filters, Filters: t.Insert.Filters,
Columns: t.Insert.Columns, Columns: t.Insert.Columns,
Set: t.Insert.Set, Presets: t.Insert.Presets,
} }
if t.Query.Block { if t.Query.Block {
@ -58,7 +58,7 @@ func initCompilers(c *config) (*qcode.Compiler, *psql.Compiler, error) {
update := qcode.UpdateConfig{ update := qcode.UpdateConfig{
Filters: t.Insert.Filters, Filters: t.Insert.Filters,
Columns: t.Insert.Columns, Columns: t.Insert.Columns,
Set: t.Insert.Set, Presets: t.Insert.Presets,
} }
if t.Query.Block { if t.Query.Block {

View File

@ -1,4 +1,4 @@
app_name: "Super Graph Development" app_name: "{{app_name}} Development"
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080
web_ui: true web_ui: true
@ -49,7 +49,7 @@ migrations_path: ./config/migrations
auth: auth:
# Can be 'rails' or 'jwt' # Can be 'rails' or 'jwt'
type: rails type: rails
cookie: _app_session cookie: _{{app_name_slug}}_session
# Comment this out if you want to disable setting # Comment this out if you want to disable setting
# the user_id via a header. Good for testing # the user_id via a header. Good for testing
@ -84,7 +84,7 @@ database:
type: postgres type: postgres
host: db host: db
port: 5432 port: 5432
dbname: app_development dbname: {{app_name_slug}}_development
user: postgres user: postgres
password: '' password: ''
@ -169,7 +169,7 @@ roles:
insert: insert:
filters: ["{ user_id: { eq: $user_id } }"] filters: ["{ user_id: { eq: $user_id } }"]
columns: ["id", "name", "description" ] columns: ["id", "name", "description" ]
set: presets:
- created_at: "now" - created_at: "now"
update: update:
@ -177,7 +177,7 @@ roles:
columns: columns:
- id - id
- name - name
set: presets:
- updated_at: "now" - updated_at: "now"
delete: delete:

View File

@ -2,7 +2,7 @@
# so I only need to overwrite some values # so I only need to overwrite some values
inherit: dev inherit: dev
app_name: "Super Graph Production" app_name: "{{app_name}} Production"
host_port: 0.0.0.0:8080 host_port: 0.0.0.0:8080
web_ui: false web_ui: false
@ -49,7 +49,7 @@ enable_tracing: true
auth: auth:
# Can be 'rails' or 'jwt' # Can be 'rails' or 'jwt'
type: rails type: rails
cookie: _app_session cookie: _{{app_name_slug}}_session
rails: rails:
# Rails version this is used for reading the # Rails version this is used for reading the