Commit 79071a5d4fc3720a184381f583e32a94181fec2b

Authored by Marko Tikvić
1 parent b3b60e8b60
Exists in master and in 1 other branch v2

Using database/sql package to make the package driver agnostic

Showing 3 changed files with 282 additions and 429 deletions   Show diff stats
1 package webutility 1 package webutility
2 2
3 import ( 3 import (
4 "database/sql"
4 "encoding/json" 5 "encoding/json"
5 "errors"
6 "fmt" 6 "fmt"
7 "io" 7 "io"
8 "net/http" 8 "net/http"
9 "os"
10 "sync" 9 "sync"
11 "time" 10 "time"
12 11
13 "git.to-net.rs/marko.tikvic/gologger" 12 "git.to-net.rs/marko.tikvic/gologger"
14
15 "gopkg.in/rana/ora.v4"
16 ) 13 )
17 14
18 var ( 15 var (
19 mu = &sync.Mutex{} 16 mu = &sync.Mutex{}
20 metadata = make(map[string]Payload) 17 metadata = make(map[string]Payload)
21 updateQue = make(map[string][]byte) 18 updateQue = make(map[string][]byte)
22 19
23 metadataDB *ora.Ses 20 metadataDB *sql.DB
24 activeProject string 21 activeProject string
25 22
26 inited bool 23 inited bool
27 ) 24 )
28 25
29 var logger *gologger.Logger 26 var logger *gologger.Logger
30 27
31 func init() { 28 func init() {
32 var err error 29 var err error
33 logger, err = gologger.New("metadata", gologger.MaxLogSize100KB) 30 logger, err = gologger.New("metadata", gologger.MaxLogSize100KB)
34 if err != nil { 31 if err != nil {
35 fmt.Printf("webutility: %s\n", err.Error()) 32 fmt.Printf("webutility: %s\n", err.Error())
36 } 33 }
37 } 34 }
38 35
39 type LangMap map[string]map[string]string 36 type LangMap map[string]map[string]string
40 37
41 type Field struct { 38 type Field struct {
42 Parameter string `json:"param"` 39 Parameter string `json:"param"`
43 Type string `json:"type"` 40 Type string `json:"type"`
44 Visible bool `json:"visible"` 41 Visible bool `json:"visible"`
45 Editable bool `json:"editable"` 42 Editable bool `json:"editable"`
46 } 43 }
47 44
48 type CorrelationField struct { 45 type CorrelationField struct {
49 Result string `json:"result"` 46 Result string `json:"result"`
50 Elements []string `json:"elements"` 47 Elements []string `json:"elements"`
51 Type string `json:"type"` 48 Type string `json:"type"`
52 } 49 }
53 50
54 type Translation struct { 51 type Translation struct {
55 Language string `json:"language"` 52 Language string `json:"language"`
56 FieldsLabels map[string]string `json:"fieldsLabels"` 53 FieldsLabels map[string]string `json:"fieldsLabels"`
57 } 54 }
58 55
59 type Payload struct { 56 type Payload struct {
60 Method string `json:"method"` 57 Method string `json:"method"`
61 Params map[string]string `json:"params"` 58 Params map[string]string `json:"params"`
62 Lang []Translation `json:"lang"` 59 Lang []Translation `json:"lang"`
63 Fields []Field `json:"fields"` 60 Fields []Field `json:"fields"`
64 Correlations []CorrelationField `json:"correlationFields"` 61 Correlations []CorrelationField `json:"correlationFields"`
65 IdField string `json:"idField"` 62 IdField string `json:"idField"`
66 63
67 // Data holds JSON payload. It can't be used for itteration. 64 // Data holds JSON payload. It can't be used for itteration.
68 Data interface{} `json:"data"` 65 Data interface{} `json:"data"`
69 } 66 }
70 67
68 // NewPayload returs a payload sceleton for entity described with etype.
69 func NewPayload(r *http.Request, etype string) Payload {
70 pload := metadata[etype]
71 pload.Method = r.Method + " " + r.RequestURI
72 return pload
73 }
74
75 // DecodeJSON decodes JSON data from r to v.
76 // Returns an error if it fails.
77 func DecodeJSON(r io.Reader, v interface{}) error {
78 return json.NewDecoder(r).Decode(v)
79 }
80
71 // LoadPayloadsdetaData loads all payloads' information into 'metadata' variable. 81 // LoadPayloadsdetaData loads all payloads' information into 'metadata' variable.
72 func LoadPayloadsMetadata(db *ora.Ses, project string) error { 82 func LoadPayloadsMetadata(db *sql.DB, project string) error {
73 metadataDB = db 83 metadataDB = db
74 activeProject = project 84 activeProject = project
75 85
76 mu.Lock() 86 mu.Lock()
77 defer mu.Unlock() 87 defer mu.Unlock()
78 err := initMetadata(project) 88 err := initMetadata(project)
79 if err != nil { 89 if err != nil {
80 return err 90 return err
81 } 91 }
82 inited = true 92 inited = true
83 93
84 return nil 94 return nil
85 } 95 }
86 96
87 func EnableHotloading(interval int) { 97 func EnableHotloading(interval int) {
88 if interval > 0 { 98 if interval > 0 {
89 go hotload(interval) 99 go hotload(interval)
90 } 100 }
91 } 101 }
92 102
93 func GetMetadataForAllEntities() map[string]Payload { 103 func GetMetadataForAllEntities() map[string]Payload {
94 return metadata 104 return metadata
95 } 105 }
96 106
97 func GetMetadataForEntity(t string) (Payload, bool) { 107 func GetMetadataForEntity(t string) (Payload, bool) {
98 p, ok := metadata[t] 108 p, ok := metadata[t]
99 return p, ok 109 return p, ok
100 } 110 }
101 111
102 func QueEntityModelUpdate(entityType string, v interface{}) { 112 func QueEntityModelUpdate(entityType string, v interface{}) {
103 updateQue[entityType], _ = json.Marshal(v) 113 updateQue[entityType], _ = json.Marshal(v)
104 } 114 }
105 115
116 func initMetadata(project string) error {
117 rows, err := metadataDB.Query(`select
118 entity_type,
119 metadata
120 from entities
121 where projekat = ` + fmt.Sprintf("'%s'", project))
122 if err != nil {
123 return err
124 }
125 defer rows.Close()
126
127 count := 0
128 success := 0
129 if len(metadata) > 0 {
130 metadata = nil
131 }
132 metadata = make(map[string]Payload)
133 for rows.Next() {
134 var name, load string
135 rows.Scan(&name, &load)
136
137 p := Payload{}
138 err := json.Unmarshal([]byte(load), &p)
139 if err != nil {
140 logger.Log("couldn't init: '%s' metadata: %s\n%s\n", name, err.Error(), load)
141 } else {
142 success++
143 metadata[name] = p
144 }
145 count++
146 }
147 perc := float32(success/count) * 100.0
148 logger.Log("loaded %d/%d (%.1f%%) entities\n", success, count, perc)
149
150 return nil
151 }
152
153 func hotload(n int) {
154 entityScan := make(map[string]int64)
155 firstCheck := true
156 for {
157 time.Sleep(time.Duration(n) * time.Second)
158 rows, err := metadataDB.Query(`select
159 ora_rowscn,
160 entity_type
161 from entities where projekat = ` + fmt.Sprintf("'%s'", activeProject))
162 if err != nil {
163 logger.Log("hotload failed: %v\n", err)
164 time.Sleep(time.Duration(n) * time.Second)
165 continue
166 }
167
168 var toRefresh []string
169 for rows.Next() {
170 var scanID int64
171 var entity string
172 rows.Scan(&scanID, &entity)
173 oldID, ok := entityScan[entity]
174 if !ok || oldID != scanID {
175 entityScan[entity] = scanID
176 toRefresh = append(toRefresh, entity)
177 }
178 }
179 rows.Close()
180
181 if rows.Err() != nil {
182 logger.Log("hotload rset error: %v\n", rows.Err())
183 time.Sleep(time.Duration(n) * time.Second)
184 continue
185 }
186
187 if len(toRefresh) > 0 && !firstCheck {
188 mu.Lock()
189 refreshMetadata(toRefresh)
190 mu.Unlock()
191 }
192 if firstCheck {
193 firstCheck = false
194 }
195 }
196 }
197
198 func refreshMetadata(entities []string) {
199 for _, e := range entities {
200 fmt.Printf("refreshing %s\n", e)
201 rows, err := metadataDB.Query(`select
202 metadata
203 from entities
204 where projekat = ` + fmt.Sprintf("'%s'", activeProject) +
205 ` and entity_type = ` + fmt.Sprintf("'%s'", e))
206
207 if err != nil {
208 logger.Log("webutility: refresh: prep: %v\n", err)
209 rows.Close()
210 continue
211 }
212
213 for rows.Next() {
214 var load string
215 rows.Scan(&load)
216 p := Payload{}
217 err := json.Unmarshal([]byte(load), &p)
218 if err != nil {
219 logger.Log("couldn't refresh: '%s' metadata: %s\n%s\n", e, err.Error(), load)
220 } else {
221 metadata[e] = p
222 }
223 }
224 rows.Close()
225 }
226 }
227
228 /*
106 func UpdateEntityModels(command string) (total, upd, add int, err error) { 229 func UpdateEntityModels(command string) (total, upd, add int, err error) {
107 if command != "force" && command != "missing" { 230 if command != "force" && command != "missing" {
108 return total, 0, 0, errors.New("uknown command: " + command) 231 return total, 0, 0, errors.New("uknown command: " + command)
109 } 232 }
110 233
111 if !inited { 234 if !inited {
112 return 0, 0, 0, errors.New("webutil: metadata not initialized but update was tried.") 235 return 0, 0, 0, errors.New("webutil: metadata not initialized but update was tried.")
113 } 236 }
114 237
115 total = len(updateQue) 238 total = len(updateQue)
116 239
117 forUpdate := make([]string, 0) 240 forUpdate := make([]string, 0)
118 forAdd := make([]string, 0) 241 forAdd := make([]string, 0)
119 242
120 for k, _ := range updateQue { 243 for k, _ := range updateQue {
121 if _, exists := metadata[k]; exists { 244 if _, exists := metadata[k]; exists {
122 if command == "force" { 245 if command == "force" {
123 forUpdate = append(forUpdate, k) 246 forUpdate = append(forUpdate, k)
124 } 247 }
125 } else { 248 } else {
126 forAdd = append(forAdd, k) 249 forAdd = append(forAdd, k)
127 } 250 }
128 } 251 }
129 252
130 for _, k := range forUpdate { 253 for _, k := range forUpdate {
131 _, err := metadataDB.PrepAndExe(`update entities set 254 _, err := metadataDB.PrepAndExe(`update entities set
132 entity_model = :1 255 entity_model = :1
133 where entity_type = :2`, 256 where entity_type = :2`,
134 string(updateQue[k]), 257 string(updateQue[k]),
135 k) 258 k)
136 259
137 if err != nil { 260 if err != nil {
138 logger.Log("webutility: update metadata: prep and exe: %v\n", err) 261 logger.Log("webutility: update metadata: prep and exe: %v\n", err)
139 continue 262 continue
140 } 263 }
141 upd++ 264 upd++
142 logger.Log("webutility: updated %s payload model\n", k) 265 logger.Log("webutility: updated %s payload model\n", k)
143 } 266 }
144 267
145 blankPayload, _ := json.Marshal(Payload{}) 268 blankPayload, _ := json.Marshal(Payload{})
146 for _, k := range forAdd { 269 for _, k := range forAdd {
147 _, err := metadataDB.PrepAndExe(`insert into entities 270 _, err := metadataDB.PrepAndExe(`insert into entities
148 (projekat, metadata, entity_type, entity_model) 271 (projekat, metadata, entity_type, entity_model)
149 values(:1, :2, :3, :4)`, 272 values(:1, :2, :3, :4)`,
150 activeProject, 273 activeProject,
151 string(blankPayload), 274 string(blankPayload),
152 k, 275 k,
153 string(updateQue[k])) 276 string(updateQue[k]))
154 277
155 if err != nil { 278 if err != nil {
156 logger.Log("webutility: add metadata: prep and exe: %v\n", err) 279 logger.Log("webutility: add metadata: prep and exe: %v\n", err)
157 continue 280 continue
158 } 281 }
159 metadata[k] = Payload{} 282 metadata[k] = Payload{}
160 add++ 283 add++
161 logger.Log("webutility: added %s to the payload models\n", k) 284 logger.Log("webutility: added %s to the payload models\n", k)
162 285
163 } 286 }
164 287
165 return total, upd, add, nil 288 return total, upd, add, nil
166 } 289 }
167 290
168 func ModifyMetadataForEntity(entityType string, p *Payload) error { 291 func ModifyMetadataForEntity(entityType string, p *Payload) error {
169 md, err := json.Marshal(*p) 292 md, err := json.Marshal(*p)
170 if err != nil { 293 if err != nil {
171 return err 294 return err
172 } 295 }
173 296
174 mu.Lock() 297 mu.Lock()
175 defer mu.Unlock() 298 defer mu.Unlock()
176 _, err = metadataDB.PrepAndExe(`update entities set 299 _, err = metadataDB.PrepAndExe(`update entities set
177 metadata = :1 300 metadata = :1
178 where projekat = :2 301 where projekat = :2
179 and entity_type = :3`, 302 and entity_type = :3`,
180 string(md), 303 string(md),
181 activeProject, 304 activeProject,
182 entityType) 305 entityType)
183 if err != nil { 306 if err != nil {
184 return err 307 return err
185 } 308 }
186 return nil 309 return nil
187 } 310 }
188 311
189 func DeleteEntityModel(entityType string) error { 312 func DeleteEntityModel(entityType string) error {
190 _, err := metadataDB.PrepAndExe("delete from entities where entity_type = :1", entityType) 313 _, err := metadataDB.PrepAndExe("delete from entities where entity_type = :1", entityType)
191 if err == nil { 314 if err == nil {
192 mu.Lock() 315 mu.Lock()
193 delete(metadata, entityType) 316 delete(metadata, entityType)
194 mu.Unlock() 317 mu.Unlock()
195 } 318 }
196 return err 319 return err
197 } 320 }
198 321 */
199 // NewPayload returs a payload sceleton for entity described with etype.
200 func NewPayload(r *http.Request, etype string) Payload {
201 pload := metadata[etype]
202 pload.Method = r.Method + " " + r.RequestURI
203 return pload
204 }
205
206 // DecodeJSON decodes JSON data from r to v.
207 // Returns an error if it fails.
208 func DecodeJSON(r io.Reader, v interface{}) error {
209 return json.NewDecoder(r).Decode(v)
210 }
211
212 func initMetadata(project string) error {
213 metadataDB.SetCfg(metadataDB.Cfg().SetClob(ora.S))
214 stmt, err := metadataDB.Prep(`select
215 entity_type,
216 metadata
217 from entities
218 where projekat = `+fmt.Sprintf("'%s'", project),
219 ora.S,
220 ora.S)
1 package webutility 1 package webutility
2 2
3 import "gopkg.in/rana/ora.v4" 3 import (
4 "database/sql"
5 "fmt"
6 )
4 7
5 type ListOptions struct { 8 type ListOptions struct {
6 GlobalFilter bool `json:"globalFilter"` 9 GlobalFilter bool `json:"globalFilter"`
7 LocalFilters bool `json:"localFilters"` 10 LocalFilters bool `json:"localFilters"`
8 RemoteFilters bool `json:"remoteFilters"` 11 RemoteFilters bool `json:"remoteFilters"`
9 Pagination bool `json:"pagination"` 12 Pagination bool `json:"pagination"`
10 PageSize uint64 `json:"pageSize"` 13 PageSize uint32 `json:"pageSize"`
11 Pivot bool `json:"pivot"` 14 Pivot bool `json:"pivot"`
12 Detail bool `json:"detail"` 15 Detail bool `json:"detail"`
13 Total bool `json:"total"` 16 Total bool `json:"total"`
14 } 17 }
15 18
16 type ListFilter struct { 19 type ListFilter struct {
17 Position uint32 `json:"-"` 20 Position uint32 `json:"-"`
18 ObjectType string `json:"-"` 21 ObjectType string `json:"-"`
19 FiltersField string `json:"filtersField"` 22 FiltersField string `json:"filtersField"`
20 DefaultValues string `json:"defaultValues"` 23 DefaultValues string `json:"defaultValues"`
21 FiltersType string `json:"filtersType"` 24 FiltersType string `json:"filtersType"`
22 FiltersLabel string `json:"filtersLabel"` 25 FiltersLabel string `json:"filtersLabel"`
23 DropdownConfig Dropdown `json:"dropdownConfig"` 26 DropdownConfig Dropdown `json:"dropdownConfig"`
24 } 27 }
25 28
26 type Dropdown struct { 29 type Dropdown struct {
27 ObjectType string `json:"objectType"` 30 ObjectType string `json:"objectType"`
28 FiltersField string `json:"filtersField"` 31 FiltersField string `json:"filtersField"`
29 IDField string `json:"idField"` 32 IDField string `json:"idField"`
30 LabelField string `json:"labelField"` 33 LabelField string `json:"labelField"`
31 } 34 }
32 35
33 type ListGraph struct { 36 type ListGraph struct {
34 ObjectType string `json:"objectType"` 37 ObjectType string `json:"objectType"`
35 X string `json:"xField"` 38 X string `json:"xField"`
36 Y string `json:"yField"` 39 Y string `json:"yField"`
37 GroupField string `json:"groupField"` 40 GroupField string `json:"groupField"`
38 Label string `json:"label"` 41 Label string `json:"label"`
39 } 42 }
40 43
41 type ListActions struct { 44 type ListActions struct {
42 Create bool `json:"create"` 45 Create bool `json:"create"`
43 Update bool `json:"update"` 46 Update bool `json:"update"`
44 Delete bool `json:"delete"` 47 Delete bool `json:"delete"`
45 Export bool `json:"export"` 48 Export bool `json:"export"`
46 Print bool `json:"print"` 49 Print bool `json:"print"`
47 Graph bool `json:"graph"` 50 Graph bool `json:"graph"`
48 } 51 }
49 52
50 type ListNavNode struct { 53 type ListNavNode struct {
51 ObjectType string `json:"objectType"` 54 ObjectType string `json:"objectType"`
52 LabelField string `json:"label"` 55 LabelField string `json:"label"`
53 Icon string `json:"icon"` 56 Icon string `json:"icon"`
54 ParentObjectType string `json:"parentObjectType"` 57 ParentObjectType string `json:"parentObjectType"`
55 ParentIDField string `json:"parentIdField"` 58 ParentIDField string `json:"parentIdField"`
56 ParentFilterField string `json:"parentFilterField"` 59 ParentFilterField string `json:"parentFilterField"`
57 } 60 }
58 61
59 type ListParentNode struct { 62 type ListParentNode struct {
60 ObjectType string `json:"objectType"` 63 ObjectType string `json:"objectType"`
61 LabelField string `json:"labelField"` 64 LabelField string `json:"labelField"`
62 FilterField string `json:"filterField"` 65 FilterField string `json:"filterField"`
63 } 66 }
64 67
65 type ListPivot struct { 68 type ListPivot struct {
66 ObjectType string `json:"objectType"` 69 ObjectType string `json:"objectType"`
67 GroupField string `json:"groupField"` 70 GroupField string `json:"groupField"`
68 DistinctField string `json:"distinctField"` 71 DistinctField string `json:"distinctField"`
69 Value string `json:"valueField"` 72 Value string `json:"valueField"`
70 } 73 }
71 74
72 type ListDetails struct { 75 type ListDetails struct {
73 ObjectType string `json:"objectType"` 76 ObjectType string `json:"objectType"`
74 ParentObjectType string `json:"parentObjectType"` 77 ParentObjectType string `json:"parentObjectType"`
75 ParentFilterField string `json:"parentFilterField"` 78 ParentFilterField string `json:"parentFilterField"`
76 SingleDetail bool `json:"singleDetail"` 79 SingleDetail bool `json:"singleDetail"`
77 } 80 }
78 81
79 type ListConfig struct { 82 type ListConfig struct {
80 ObjectType string `json:"objectType"` 83 ObjectType string `json:"objectType"`
81 Title string `json:"title"` 84 Title string `json:"title"`
82 LazyLoad bool `json:"lazyLoad"` 85 LazyLoad bool `json:"lazyLoad"`
83 InlineEdit bool `json:"inlineEdit"` 86 InlineEdit bool `json:"inlineEdit"`
84 Options ListOptions `json:"options"` 87 Options ListOptions `json:"options"`
85 Filters []ListFilter `json:"defaultFilters"` 88 Filters []ListFilter `json:"defaultFilters"`
86 Graphs []ListGraph `json:"graphs"` 89 Graphs []ListGraph `json:"graphs"`
87 Actions ListActions `json:"actions"` 90 Actions ListActions `json:"actions"`
88 Parent []ListParentNode `json:"parent"` 91 Parent []ListParentNode `json:"parent"`
89 Navigation []ListNavNode `json:"navigation"` 92 Navigation []ListNavNode `json:"navigation"`
90 Pivots []ListPivot `json:"pivots"` 93 Pivots []ListPivot `json:"pivots"`
91 Details ListDetails `json:"details"` 94 Details ListDetails `json:"details"`
92 } 95 }
93 96
94 // GetListConfig returns list configuration for the provided object type for the front-end application 97 // GetListConfig returns list configuration for the provided object type for the front-end application
95 // or an error if it fails. 98 // or an error if it fails.
96 func GetListConfig(db *ora.Ses, objType string) (ListConfig, error) { 99 func GetListConfig(db *sql.DB, objType string) (ListConfig, error) {
97 resp := newDefaultList(objType) 100 resp := newDefaultList(objType)
98 var err error 101 var err error
99 102
100 err = setListParams(db, &resp, objType) 103 err = setListParams(db, &resp, objType)
101 resp.Navigation, err = getListNavigation(db, objType) 104 resp.Navigation, err = getListNavigation(db, objType)
102 resp.Actions, err = getListActions(db, objType) 105 resp.Actions, err = getListActions(db, objType)
103 resp.Filters, err = getListFilters(db, objType) 106 resp.Filters, err = getListFilters(db, objType)
104 resp.Options, err = getListOptions(db, objType) 107 resp.Options, err = getListOptions(db, objType)
105 resp.Parent, err = getListParent(db, objType) 108 resp.Parent, err = getListParent(db, objType)
106 resp.Graphs, err = getListGraph(db, objType) 109 resp.Graphs, err = getListGraph(db, objType)
107 resp.Pivots, err = getListPivot(db, objType) 110 resp.Pivots, err = getListPivot(db, objType)
108 resp.Details, err = getListDetails(db, objType) 111 resp.Details, err = getListDetails(db, objType)
109 112
110 if err != nil { 113 if err != nil {
111 return ListConfig{}, err 114 return ListConfig{}, err
112 } 115 }
113 116
114 return resp, nil 117 return resp, nil
115 } 118 }
116 119
117 // GetListConfigObjectIDField takes in database connection and an object type and it returns the 120 // GetListConfigObjectIDField takes in database connection and an object type and it returns the
118 // ID field name for the provided object type. 121 // ID field name for the provided object type.
119 func GetListConfigObjectIDField(db *ora.Ses, otype string) string { 122 func GetListConfigObjectIDField(db *sql.DB, otype string) string {
120 var resp string 123 var resp string
121 var err error
122 var stmt *ora.Stmt
123 124
124 stmt, err = db.Prep(`SELECT 125 rows, err := db.Query(`SELECT
125 ID_FIELD 126 ID_FIELD
126 FROM LIST_CONFIG_ID_FIELD 127 FROM LIST_CONFIG_ID_FIELD
127 WHERE OBJECT_TYPE = '`+otype+`'`, 128 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", otype))
128 ora.S)
129
130 defer stmt.Close()
131
132 if err != nil { 129 if err != nil {
133 return "" 130 return ""
134 } 131 }
132 defer rows.Close()
135 133
136 rset, err := stmt.Qry() 134 if rows.Next() {
137 if rset.Next() { 135 rows.Scan(&resp)
138 resp = rset.Row[0].(string)
139 } 136 }
140 137
141 if rset.Err() != nil { 138 if rows.Err() != nil {
142 return "" 139 return ""
143 } 140 }
144 141
145 return resp 142 return resp
146 } 143 }
147 144
148 // newDefaultList returns default configuration for the provided object type. 145 // newDefaultList returns default configuration for the provided object type.
149 func newDefaultList(objType string) ListConfig { 146 func newDefaultList(objType string) ListConfig {
150 list := ListConfig{ 147 list := ListConfig{
151 ObjectType: objType, 148 ObjectType: objType,
152 Title: objType, 149 Title: objType,
153 LazyLoad: false, 150 LazyLoad: false,
154 Options: ListOptions{ 151 Options: ListOptions{
155 GlobalFilter: true, 152 GlobalFilter: true,
156 LocalFilters: true, 153 LocalFilters: true,
157 RemoteFilters: false, 154 RemoteFilters: false,
158 Pagination: true, 155 Pagination: true,
159 PageSize: 20, 156 PageSize: 20,
160 }, 157 },
161 Filters: nil, 158 Filters: nil,
162 Actions: ListActions{ 159 Actions: ListActions{
163 Create: false, 160 Create: false,
164 Update: false, 161 Update: false,
165 Delete: false, 162 Delete: false,
166 Export: false, 163 Export: false,
167 Print: false, 164 Print: false,
168 Graph: false, 165 Graph: false,
169 }, 166 },
170 Parent: nil, 167 Parent: nil,
171 Navigation: nil, 168 Navigation: nil,
172 } 169 }
173 170
174 return list 171 return list
175 } 172 }
176 173
177 // setListParams sets the default parameters of the provided configuration list for the provided object type. 174 // setListParams sets the default parameters of the provided configuration list for the provided object type.
178 func setListParams(db *ora.Ses, list *ListConfig, objType string) error { 175 func setListParams(db *sql.DB, list *ListConfig, objType string) error {
179 var err error 176 rows, err := db.Query(`SELECT
180 var stmt *ora.Stmt
181 query := `SELECT
182 OBJECT_TYPE, TITLE, LAZY_LOAD, INLINE_EDIT 177 OBJECT_TYPE, TITLE, LAZY_LOAD, INLINE_EDIT
183 FROM LIST_CONFIG 178 FROM LIST_CONFIG
184 WHERE OBJECT_TYPE = '` + objType + `'` 179 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
185
186 stmt, err = db.Prep(query, ora.S, ora.S, ora.U32, ora.U32)
187 if err != nil { 180 if err != nil {
188 return err 181 return err
189 } 182 }
190 defer stmt.Close() 183 defer rows.Close()
184 if rows.Next() {
185 otype, title := "", ""
186 lazyLoad, inlineEdit := 0, 0
187 rows.Scan(&otype, &title, &lazyLoad, &inlineEdit)
191 188
192 rset, err := stmt.Qry()
193 if err != nil {
194 return err
195 }
196 if rset.Next() {
197 otype := rset.Row[0].(string)
198 if otype != "" { 189 if otype != "" {
199 list.ObjectType = otype 190 list.ObjectType = otype
200 } 191 }
201
202 title := rset.Row[1].(string)
203 if title != "" { 192 if title != "" {
204 list.Title = title 193 list.Title = title
205 } 194 }
206 list.LazyLoad = rset.Row[2].(uint32) != 0 195 list.LazyLoad = lazyLoad != 0
207 list.InlineEdit = rset.Row[3].(uint32) != 0 196 list.InlineEdit = inlineEdit != 0
208 } 197 }
209 if rset.Err() != nil { 198 if rows.Err() != nil {
210 return rset.Err() 199 return rows.Err()
211 } 200 }
212 return nil 201 return nil
213 } 202 }
214 203
215 // getListNavigation returns list navigation node slice for the provided objectType. 204 // getListNavigation returns list navigation node slice for the provided objectType.
216 func getListNavigation(db *ora.Ses, listObjType string) ([]ListNavNode, error) { 205 func getListNavigation(db *sql.DB, listObjType string) ([]ListNavNode, error) {
217 resp := make([]ListNavNode, 0) 206 resp := make([]ListNavNode, 0)
218 var err error 207 rows, err := db.Query(`SELECT
219 var stmt *ora.Stmt 208 a.OBJECT_TYPE, a.PARENT_OBJECT_TYPE, a.LABEL, a.ICON, a.PARENT_FILTER_FIELD, b.PARENT_ID_FIELD
220 query := `SELECT
221 a.OBJECT_TYPE, a.PARENT_OBJECT_TYPE, a.LABEL, a.ICON, a.PARENT_FILTER_FIELD, b.PARENT_ID_FIELD, b.RB
222 FROM LIST_CONFIG_NAVIGATION b 209 FROM LIST_CONFIG_NAVIGATION b
223 JOIN LIST_CONFIG_CHILD a ON b.PARENT_CHILD_ID = a.PARENT_CHILD_ID 210 JOIN LIST_CONFIG_CHILD a ON b.PARENT_CHILD_ID = a.PARENT_CHILD_ID
224 WHERE b.LIST_OBJECT_TYPE = '` + listObjType + `' 211 WHERE b.LIST_OBJECT_TYPE = ` + fmt.Sprintf("'%s'", listObjType) +
225 ORDER BY b.RB ASC` 212 ` ORDER BY b.RB ASC`)
226
227 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S)
228 if err != nil { 213 if err != nil {
229 return resp, err 214 return resp, err
230 } 215 }
231 defer stmt.Close() 216 defer rows.Close()
232 217
233 rset, err := stmt.Qry() 218 var node ListNavNode
234 if err != nil { 219 for rows.Next() {
235 return resp, err 220 rows.Scan(&node.ObjectType, &node.ParentObjectType, &node.LabelField, &node.Icon,
236 } 221 &node.ParentFilterField, &node.ParentIDField)
237 for rset.Next() { 222 resp = append(resp, node)
238 resp = append(resp, ListNavNode{
239 ObjectType: rset.Row[0].(string),
240 ParentObjectType: rset.Row[1].(string),
241 LabelField: rset.Row[2].(string),
242 Icon: rset.Row[3].(string),
243 ParentFilterField: rset.Row[4].(string),
244 ParentIDField: rset.Row[5].(string),
245 // RB is ignored
246 })
247 } 223 }
248 if rset.Err() != nil { 224 if rows.Err() != nil {
249 return nil, rset.Err() 225 return nil, rows.Err()
250 } 226 }
251 227
252 return resp, nil 228 return resp, nil
253 } 229 }
254 230
255 // getListActions returns list actions for the provided object type. 231 // getListActions returns list actions for the provided object type.
256 func getListActions(db *ora.Ses, objType string) (ListActions, error) { 232 func getListActions(db *sql.DB, objType string) (ListActions, error) {
257 var resp ListActions 233 var resp ListActions
258 var err error 234 rows, err := db.Query(`SELECT
259 var stmt *ora.Stmt
260 query := `SELECT
261 ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE, ACTION_EXPORT, 235 ACTION_CREATE, ACTION_UPDATE, ACTION_DELETE, ACTION_EXPORT,
262 ACTION_PRINT, ACTION_GRAPH 236 ACTION_PRINT, ACTION_GRAPH
263 FROM LIST_CONFIG 237 FROM LIST_CONFIG
264 WHERE OBJECT_TYPE = '` + objType + `'` 238 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
265
266 stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32,
267 ora.U32, ora.U32)
268 if err != nil { 239 if err != nil {
269 return ListActions{}, err 240 return ListActions{}, err
270 } 241 }
271 defer stmt.Close() 242 defer rows.Close()
272 243
273 rset, err := stmt.Qry() 244 var create, update, delete, export, print, graph uint32
274 if err != nil { 245 if rows.Next() {
275 return ListActions{}, err 246 rows.Scan(&create, &update, &delete, &export, &print, &graph)
247 resp.Create = create != 0
248 resp.Update = update != 0
249 resp.Delete = delete != 0
250 resp.Export = export != 0
251 resp.Print = print != 0
252 resp.Graph = graph != 0
276 } 253 }
277 if rset.Next() { 254 if rows.Err() != nil {
278 resp.Create = rset.Row[0].(uint32) != 0 255 return ListActions{}, rows.Err()
279 resp.Update = rset.Row[1].(uint32) != 0
280 resp.Delete = rset.Row[2].(uint32) != 0
281 resp.Export = rset.Row[3].(uint32) != 0
282 resp.Print = rset.Row[4].(uint32) != 0
283 resp.Graph = rset.Row[5].(uint32) != 0
284 }
285 if rset.Err() != nil {
286 return ListActions{}, rset.Err()
287 } 256 }
288 return resp, nil 257 return resp, nil
289 } 258 }
290 259
291 // getListFiters returns list filter slice for the provided object type. 260 // getListFiters returns list filter slice for the provided object type.
292 func getListFilters(db *ora.Ses, objType string) ([]ListFilter, error) { 261 func getListFilters(db *sql.DB, objType string) ([]ListFilter, error) {
293 resp := make([]ListFilter, 0) 262 resp := make([]ListFilter, 0)
294 filtersFields, err := getFilterFieldsAndPosition(db, objType) 263 filtersFields, err := getFilterFieldsAndPosition(db, objType)
295 if err != nil { 264 if err != nil {
296 return nil, err 265 return nil, err
297 } 266 }
298 for field, pos := range filtersFields { 267 for field, pos := range filtersFields {
299 filters, _ := getFiltersByFilterField(db, field) 268 filters, _ := getFiltersByFilterField(db, field)
300 for _, filter := range filters { 269 for _, filter := range filters {
301 var f ListFilter 270 var f ListFilter
302 f.Position = pos 271 f.Position = pos
303 f.ObjectType = objType 272 f.ObjectType = objType
304 f.FiltersField = field 273 f.FiltersField = field
305 f.DefaultValues = filter.DefaultValues 274 f.DefaultValues = filter.DefaultValues
306 f.FiltersLabel = filter.Label 275 f.FiltersLabel = filter.Label
307 f.FiltersType = filter.Type 276 f.FiltersType = filter.Type
308 if filter.Type == "dropdown" { 277 if filter.Type == "dropdown" {
309 f.DropdownConfig, err = getFilterDropdownConfig(db, field) 278 f.DropdownConfig, err = getFilterDropdownConfig(db, field)
310 if err != nil { 279 if err != nil {
311 return nil, err 280 return nil, err
312 } 281 }
313 } 282 }
314 resp = append(resp, f) 283 resp = append(resp, f)
315 } 284 }
316 } 285 }
317 286
318 sortFilters(resp) 287 sortFilters(resp)
319 288
320 return resp, nil 289 return resp, nil
321 } 290 }
322 291
323 // getFilterFieldsAndPosition returns a map of filter fields and their respective position in the menu. 292 // getFilterFieldsAndPosition returns a map of filter fields and their respective position in the menu.
324 func getFilterFieldsAndPosition(db *ora.Ses, objType string) (map[string]uint32, error) { 293 func getFilterFieldsAndPosition(db *sql.DB, objType string) (map[string]uint32, error) {
325 filtersField := make(map[string]uint32, 0) 294 filtersField := make(map[string]uint32, 0)
326 var err error 295 rows, err := db.Query(`SELECT
327 var stmt *ora.Stmt
328 query := `SELECT
329 FILTERS_FIELD, RB 296 FILTERS_FIELD, RB
330 FROM LIST_CONFIG_FILTERS 297 FROM LIST_CONFIG_FILTERS
331 WHERE OBJECT_TYPE = '` + objType + `'` 298 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
332
333 stmt, err = db.Prep(query, ora.S, ora.U32)
334 if err != nil { 299 if err != nil {
335 return nil, err 300 return nil, err
336 } 301 }
337 defer stmt.Close() 302 defer rows.Close()
338 303
339 rset, err := stmt.Qry() 304 for rows.Next() {
340 if err != nil { 305 var field string
341 return nil, err 306 var rb uint32
342 } 307 rows.Scan(&field, &rb)
343 for rset.Next() { 308 filtersField[field] = rb
344 filtersField[rset.Row[0].(string)] = rset.Row[1].(uint32)
345 } 309 }
346 if rset.Err() != nil { 310 if rows.Err() != nil {
347 return nil, rset.Err() 311 return nil, rows.Err()
348 } 312 }
349 return filtersField, nil 313 return filtersField, nil
350 } 314 }
351 315
352 type _filter struct { 316 type _filter struct {
353 DefaultValues string 317 DefaultValues string
354 Label string 318 Label string
355 Type string 319 Type string
356 } 320 }
357 321
358 // getFiltersByFilterField returns filter slice for the provided filter field. 322 // getFiltersByFilterField returns filter slice for the provided filter field.
359 func getFiltersByFilterField(db *ora.Ses, filtersField string) ([]_filter, error) { 323 func getFiltersByFilterField(db *sql.DB, filtersField string) ([]_filter, error) {
360 resp := make([]_filter, 0) 324 resp := make([]_filter, 0)
361 var err error 325 rows, err := db.Query(`SELECT
362 var stmt *ora.Stmt
363 query := `SELECT
364 FILTERS_TYPE, FILTERS_LABEL, DEFAULT_VALUES 326 FILTERS_TYPE, FILTERS_LABEL, DEFAULT_VALUES
365 FROM LIST_FILTERS_FIELD 327 FROM LIST_FILTERS_FIELD
366 WHERE FILTERS_FIELD = '` + filtersField + `'` 328 WHERE FILTERS_FIELD = ` + fmt.Sprintf("'%s'", filtersField))
367
368 stmt, err = db.Prep(query, ora.S, ora.S, ora.S)
369 if err != nil { 329 if err != nil {
370 return resp, err 330 return resp, err
371 } 331 }
372 defer stmt.Close() 332 defer rows.Close()
373 333
374 rset, err := stmt.Qry() 334 var f _filter
375 if err != nil { 335 for rows.Next() {
376 return resp, err 336 rows.Scan(&f.Type, &f.Label, &f.DefaultValues)
337 resp = append(resp, f)
377 } 338 }
378 for rset.Next() { 339 if rows.Err() != nil {
379 resp = append(resp, _filter{ 340 return resp, rows.Err()
380 Type: rset.Row[0].(string),
381 Label: rset.Row[1].(string),
382 DefaultValues: rset.Row[2].(string),
383 })
384 }
385 if rset.Err() != nil {
386 return resp, rset.Err()
387 } 341 }
388 return resp, nil 342 return resp, nil
389 } 343 }
390 344
391 // getFilterDropdownConfig returns dropdown menu for the provided filter field. 345 // getFilterDropdownConfig returns dropdown menu for the provided filter field.
392 func getFilterDropdownConfig(db *ora.Ses, filtersField string) (Dropdown, error) { 346 func getFilterDropdownConfig(db *sql.DB, filtersField string) (Dropdown, error) {
393 var resp Dropdown 347 var resp Dropdown
394 var err error 348 rows, err := db.Query(`SELECT
395 var stmt *ora.Stmt
396 query := `SELECT
397 FILTERS_FIELD, OBJECT_TYPE, ID_FIELD, LABEL_FIELD 349 FILTERS_FIELD, OBJECT_TYPE, ID_FIELD, LABEL_FIELD
398 FROM LIST_DROPDOWN_FILTER 350 FROM LIST_DROPDOWN_FILTER
399 WHERE FILTERS_FIELD = '` + filtersField + `'` 351 WHERE FILTERS_FIELD = ` + fmt.Sprintf("'%s'", filtersField))
400
401 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S)
402 if err != nil { 352 if err != nil {
403 return resp, err 353 return resp, err
404 } 354 }
405 defer stmt.Close() 355 defer rows.Close()
406 356 if rows.Next() {
407 rset, err := stmt.Qry() 357 rows.Scan(&resp.FiltersField, &resp.ObjectType, &resp.IDField, &resp.LabelField)
408 if err != nil {
409 return resp, err
410 } 358 }
411 if rset.Next() { 359 if rows.Err() != nil {
412 resp.FiltersField = rset.Row[0].(string) 360 return resp, rows.Err()
413 resp.ObjectType = rset.Row[1].(string)
414 resp.IDField = rset.Row[2].(string)
415 resp.LabelField = rset.Row[3].(string)
416 }
417 if rset.Err() != nil {
418 return resp, rset.Err()
419 } 361 }
420 return resp, nil 362 return resp, nil
421 } 363 }
422 364
423 // sortFilters bubble sorts provided filters slice by position field. 365 // sortFilters bubble sorts provided filters slice by position field.
424 func sortFilters(filters []ListFilter) { 366 func sortFilters(filters []ListFilter) {
425 done := false 367 done := false
426 var temp ListFilter 368 var temp ListFilter
427 for !done { 369 for !done {
428 done = true 370 done = true
429 for i := 0; i < len(filters)-1; i++ { 371 for i := 0; i < len(filters)-1; i++ {
430 if filters[i].Position > filters[i+1].Position { 372 if filters[i].Position > filters[i+1].Position {
431 done = false 373 done = false
432 temp = filters[i] 374 temp = filters[i]
433 filters[i] = filters[i+1] 375 filters[i] = filters[i+1]
434 filters[i+1] = temp 376 filters[i+1] = temp
435 } 377 }
436 } 378 }
437 } 379 }
438 } 380 }
439 381
440 // getListGraph return list graph slice for the provided object type. 382 // getListGraph return list graph slice for the provided object type.
441 func getListGraph(db *ora.Ses, objType string) ([]ListGraph, error) { 383 func getListGraph(db *sql.DB, objType string) ([]ListGraph, error) {
442 resp := make([]ListGraph, 0) 384 resp := make([]ListGraph, 0)
443 var err error 385 rows, err := db.Query(`SELECT
444 var stmt *ora.Stmt
445 query := `SELECT
446 OBJECT_TYPE, X_FIELD, Y_FIELD, GROUP_FIELD, LABEL 386 OBJECT_TYPE, X_FIELD, Y_FIELD, GROUP_FIELD, LABEL
447 FROM LIST_GRAPHS 387 FROM LIST_GRAPHS
448 WHERE OBJECT_TYPE = '` + objType + `'` 388 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
449
450 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S)
451 if err != nil { 389 if err != nil {
452 return resp, err 390 return resp, err
453 } 391 }
454 defer stmt.Close() 392 defer rows.Close()
455 393
456 rset, err := stmt.Qry() 394 var lg ListGraph
457 if err != nil { 395 for rows.Next() {
458 return resp, err 396 rows.Scan(&lg.ObjectType, &lg.X, &lg.Y, &lg.GroupField, &lg.Label)
459 } 397 resp = append(resp, lg)
460 for rset.Next() {
461 resp = append(resp, ListGraph{
462 ObjectType: rset.Row[0].(string),
463 X: rset.Row[1].(string),
464 Y: rset.Row[2].(string),
465 GroupField: rset.Row[3].(string),
466 Label: rset.Row[4].(string),
467 })
468 } 398 }
469 if rset.Err() != nil { 399 if rows.Err() != nil {
470 return resp, rset.Err() 400 return resp, rows.Err()
471 } 401 }
472 return resp, nil 402 return resp, nil
473 } 403 }
474 404
475 // getListOptions returns list options for the provided object type. 405 // getListOptions returns list options for the provided object type.
476 func getListOptions(db *ora.Ses, objType string) (ListOptions, error) { 406 func getListOptions(db *sql.DB, objType string) (ListOptions, error) {
477 var resp ListOptions 407 var resp ListOptions
478 var err error 408 rows, err := db.Query(`SELECT
479 var stmt *ora.Stmt
480 query := `SELECT
481 GLOBAL_FILTER, LOCAL_FILTER, REMOTE_FILTER, PAGINATION, 409 GLOBAL_FILTER, LOCAL_FILTER, REMOTE_FILTER, PAGINATION,
482 PAGE_SIZE, PIVOT, DETAIL, TOTAL 410 PAGE_SIZE, PIVOT, DETAIL, TOTAL
483 FROM LIST_CONFIG 411 FROM LIST_CONFIG
484 WHERE OBJECT_TYPE = '` + objType + `'` 412 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
485
486 stmt, err = db.Prep(query, ora.U32, ora.U32, ora.U32, ora.U32,
487 ora.U64, ora.U64, ora.U32, ora.U32)
488 if err != nil {
489 return ListOptions{}, err
490 }
491 defer stmt.Close()
492
493 rset, err := stmt.Qry()
494 if err != nil { 413 if err != nil {
495 return ListOptions{}, err 414 return ListOptions{}, err
496 } 415 }
497 if rset.Next() { 416 defer rows.Close()
498 resp.GlobalFilter = rset.Row[0].(uint32) != 0 417 if rows.Next() {
499 resp.LocalFilters = rset.Row[1].(uint32) != 0 418 var gfilter, lfilters, rfilters, pagination, pageSize, pivot, detail, total uint32
500 resp.RemoteFilters = rset.Row[2].(uint32) != 0 419 rows.Scan(&gfilter, &lfilters, &rfilters, &pagination, &pageSize, &pivot, &detail, &total)
501 resp.Pagination = rset.Row[3].(uint32) != 0 420 resp.GlobalFilter = gfilter != 0
502 resp.PageSize = rset.Row[4].(uint64) 421 resp.LocalFilters = lfilters != 0
503 resp.Pivot = rset.Row[5].(uint64) != 0 422 resp.RemoteFilters = rfilters != 0
504 resp.Detail = rset.Row[6].(uint32) != 0 423 resp.Pagination = pagination != 0
505 resp.Total = rset.Row[7].(uint32) != 0 424 resp.PageSize = pageSize
506 } 425 resp.Pivot = pivot != 0
507 if rset.Err() != nil { 426 resp.Detail = detail != 0
508 return ListOptions{}, rset.Err() 427 resp.Total = total != 0
428 }
429 if rows.Err() != nil {
430 return ListOptions{}, rows.Err()
509 } 431 }
510 return resp, nil 432 return resp, nil
511 } 433 }
512 434
513 // getListParent returns list parent node slice for the provided object type. 435 // getListParent returns list parent node slice for the provided object type.
514 func getListParent(db *ora.Ses, objType string) ([]ListParentNode, error) { 436 func getListParent(db *sql.DB, objType string) ([]ListParentNode, error) {
515 resp := make([]ListParentNode, 0) 437 resp := make([]ListParentNode, 0)
516 var err error 438 rows, err := db.Query(`SELECT
517 var stmt *ora.Stmt
518 query := `SELECT
519 PARENT_OBJECT_TYPE, PARENT_LABEL_FIELD, PARENT_FILTER_FIELD 439 PARENT_OBJECT_TYPE, PARENT_LABEL_FIELD, PARENT_FILTER_FIELD
520 FROM LIST_CONFIG_CHILD 440 FROM LIST_CONFIG_CHILD
521 WHERE OBJECT_TYPE = '` + objType + `'` 441 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
522
523 stmt, err = db.Prep(query, ora.S, ora.S, ora.S)
524 if err != nil { 442 if err != nil {
525 return resp, err 443 return resp, err
526 } 444 }
527 defer stmt.Close() 445 defer rows.Close()
528 446
529 rset, err := stmt.Qry() 447 var pnode ListParentNode
530 if err != nil { 448 for rows.Next() {
531 return resp, err 449 rows.Scan(&pnode.ObjectType, &pnode.LabelField, &pnode.FilterField)
532 } 450 resp = append(resp, pnode)
533 for rset.Next() {
534 resp = append(resp, ListParentNode{
535 ObjectType: rset.Row[0].(string),
536 LabelField: rset.Row[1].(string),
537 FilterField: rset.Row[2].(string),
538 })
539 } 451 }
540 if rset.Err() != nil { 452 if rows.Err() != nil {
541 return nil, rset.Err() 453 return nil, rows.Err()
542 } 454 }
543 455
544 return resp, nil 456 return resp, nil
545 } 457 }
546 458
547 // getListPivot list pivot slice for the provided object type. 459 // getListPivot list pivot slice for the provided object type.
548 func getListPivot(db *ora.Ses, objType string) ([]ListPivot, error) { 460 func getListPivot(db *sql.DB, objType string) ([]ListPivot, error) {
549 resp := make([]ListPivot, 0) 461 resp := make([]ListPivot, 0)
550 var err error 462 rows, err := db.Query(`SELECT
551 var stmt *ora.Stmt
552 query := `SELECT
553 OBJECT_TYPE, GROUP_FIELD, DISTINCT_FIELD, VALUE_FIELD 463 OBJECT_TYPE, GROUP_FIELD, DISTINCT_FIELD, VALUE_FIELD
554 FROM LIST_PIVOTS 464 FROM LIST_PIVOTS
555 WHERE OBJECT_TYPE = '` + objType + `'` 465 WHERE OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
556
557 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S)
558 if err != nil { 466 if err != nil {
559 return resp, err 467 return resp, err
560 } 468 }
561 defer stmt.Close() 469 defer rows.Close()
562 470
563 rset, err := stmt.Qry() 471 var p ListPivot
564 if err != nil { 472 for rows.Next() {
565 return resp, err 473 rows.Scan(&p.ObjectType, &p.GroupField, &p.DistinctField, &p.Value)
474 resp = append(resp, p)
566 } 475 }
567 for rset.Next() { 476 if rows.Err() != nil {
568 resp = append(resp, ListPivot{ 477 return nil, rows.Err()
569 ObjectType: rset.Row[0].(string),
570 GroupField: rset.Row[1].(string),
571 DistinctField: rset.Row[2].(string),
572 Value: rset.Row[3].(string),
573 })
574 }
575 if rset.Err() != nil {
576 return nil, rset.Err()
577 } 478 }
578 479
579 return resp, nil 480 return resp, nil
580 } 481 }
581 482
582 // getListDetails returns list details for the provided object type. 483 // getListDetails returns list details for the provided object type.
583 func getListDetails(db *ora.Ses, objType string) (ListDetails, error) { 484 func getListDetails(db *sql.DB, objType string) (ListDetails, error) {
584 var resp ListDetails 485 var resp ListDetails
585 var err error 486 rows, err := db.Query(`SELECT
586 var stmt *ora.Stmt
587 query := `SELECT
588 OBJECT_TYPE, PARENT_OBJECT_TYPE, PARENT_FILTER_FIELD, SINGLE_DETAIL 487 OBJECT_TYPE, PARENT_OBJECT_TYPE, PARENT_FILTER_FIELD, SINGLE_DETAIL
589 FROM LIST_CONFIG_DETAIL 488 FROM LIST_CONFIG_DETAIL
590 WHERE PARENT_OBJECT_TYPE = '` + objType + `'` 489 WHERE PARENT_OBJECT_TYPE = ` + fmt.Sprintf("'%s'", objType))
591
592 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.U32)
593 if err != nil {
594 return resp, err
595 }
1 package webutility 1 package webutility
2 2
3 import "gopkg.in/rana/ora.v4" 3 import "database/sql"
4 4
5 type SelectConfig struct { 5 type SelectConfig struct {
6 ListObjType string `json:"listObjectType"` 6 ListObjType string `json:"listObjectType"`
7 ObjType string `json:"objectType"` 7 ObjType string `json:"objectType"`
8 Type string `json:"type"` 8 Type string `json:"type"`
9 IdField string `json:"idField"` 9 IdField string `json:"idField"`
10 LabelField string `json:"labelField"` 10 LabelField string `json:"labelField"`
11 ValueField string `json:"valueField"` 11 ValueField string `json:"valueField"`
12 } 12 }
13 13
14 // GetSelectConfig returns select configuration slice for the given object type. 14 // GetSelectConfig returns select configuration slice for the given object type.
15 func GetSelectConfig(db *ora.Ses, otype string) ([]SelectConfig, error) { 15 func GetSelectConfig(db *sql.DB, otype string) ([]SelectConfig, error) {
16 resp := make([]SelectConfig, 0) 16 resp := make([]SelectConfig, 0)
17 var err error 17 rows, err := db.Query(`SELECT
18 var stmt *ora.Stmt
19 query := `SELECT
20 a.LIST_OBJECT_TYPE, 18 a.LIST_OBJECT_TYPE,
21 a.OBJECT_TYPE, 19 a.OBJECT_TYPE,
22 a.ID_FIELD, 20 a.ID_FIELD,
23 a.LABEL_FIELD, 21 a.LABEL_FIELD,
24 a.TYPE, 22 a.TYPE,
25 b.FIELD 23 b.FIELD
26 FROM LIST_SELECT_CONFIG a, LIST_VALUE_FIELD b 24 FROM LIST_SELECT_CONFIG a, LIST_VALUE_FIELD b
27 WHERE a.LIST_OBJECT_TYPE` + otype + ` 25 WHERE a.LIST_OBJECT_TYPE` + otype + `
28 AND b.LIST_TYPE = a.LIST_OBJECT_TYPE 26 AND b.LIST_TYPE = a.LIST_OBJECT_TYPE
29 AND b.OBJECT_TYPE = a.OBJECT_TYPE` 27 AND b.OBJECT_TYPE = a.OBJECT_TYPE`)
30
31 stmt, err = db.Prep(query, ora.S, ora.S, ora.S, ora.S, ora.S, ora.S)
32 defer stmt.Close()
33 if err != nil { 28 if err != nil {
34 return nil, err 29 return nil, err
35 } 30 }
31 defer rows.Close()
36 32
37 rset, err := stmt.Qry() 33 var sc SelectConfig
38 if err != nil { 34 for rows.Next() {
39 return nil, err 35 rows.Scan(&sc.ListObjType, &sc.ObjType, &sc.IdField, &sc.LabelField, &sc.Type, &sc.ValueField)
40 } 36 resp = append(resp, sc)
41 for rset.Next() {
42 resp = append(resp, SelectConfig{
43 ListObjType: rset.Row[0].(string),
44 ObjType: rset.Row[1].(string),
45 IdField: rset.Row[2].(string),
46 LabelField: rset.Row[3].(string),
47 Type: rset.Row[4].(string),
48 ValueField: rset.Row[5].(string),
49 })
50 } 37 }
51 if rset.Err() != nil { 38 if rows.Err() != nil {
52 return nil, rset.Err() 39 return nil, rows.Err()
53 } 40 }
54 41
55 return resp, nil 42 return resp, nil
56 } 43 }