actn-db 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b41ff0c4461fa9cde659fe55e7ac9b2cd974350d
4
- data.tar.gz: 94e83df6646636f8ec9eb822ccbe3675189a6538
3
+ metadata.gz: 78790d807155696e6200a2960c1b62aadc023e69
4
+ data.tar.gz: 166115166e1ce296e5bceb66ba1c2cbe1da15be7
5
5
  SHA512:
6
- metadata.gz: e1972c75f05e55e51c5ccabb2ab5a29bf4e748f206c675cae168b798d75a7ca41ea14d06ec906ad0496249c5762c3fc1494aef2af1793f21129333caced63bdc
7
- data.tar.gz: 1d6c1ceaf715844dd3dbd893df4bb273362307dbe0432c50173820ac1a1d6711c28c6e256b558a0af92bb23a424818ed8347c1cfdf938466f3ee3b3b87ee5dbd
6
+ metadata.gz: 93d076700b159bf0784768cbb2e20df9c83b97ef68f4f0e1e34bb43b8b06f31e43ec59a2b9a1f29beabe02679ccfe5319d1d917adacfd7c8d606b25eeccf06c8
7
+ data.tar.gz: 3dd3b93c9d37b4cc8243709b85bc9156e3a6699f7b5a92cc4498ccfedf92dca67b389455acbe6f1d4e65040f6c857bea382c926baf15e852e89df4b9e454157e
data/db/1_db.sql CHANGED
@@ -9,45 +9,9 @@ SELECT __create_index('core','models', '{"cols": {"name": "text"},"unique": true
9
9
 
10
10
  CREATE or REPLACE FUNCTION model_callbacks() RETURNS trigger AS
11
11
  $$
12
- table_name = (NEW?.data?.name or OLD?.data?.name)?.tableize()
13
- table_schema = (NEW?.data?.table_schema or OLD?.data?.table_schema) or "public"
14
-
15
- return if table_schema is "core"
16
-
17
- # plv8.elog(NOTICE,"MODEL CALLBACKS",table_schema,JSON.stringify(NEW?.data or OLD?.data))
18
-
19
- mapper = (ind) -> _.keys(ind.cols)
20
- differ = (_ind) ->
21
- (ind) ->
22
- _.isEmpty( _.difference( _.keys(ind.cols), _.flatten( _.map( _ind.data?.indexes, mapper ) ) ) )
23
-
24
- switch TG_OP
25
- when "INSERT"
26
- plv8.execute "SELECT __create_table($1,$2)",[table_schema , table_name]
27
-
28
- plv8.execute "SELECT __create_index($1,$2,$3)", [table_schema, table_name, {cols: {path: "text" }}]
29
-
30
- for indopts in NEW?.data?.indexes or []
31
- plv8.execute "SELECT __create_index($1,$2,$3)", [table_schema, table_name, indopts]
32
-
33
- when "UPDATE"
34
-
35
- diff = _.reject( OLD?.data?.indexes, differ(NEW) )
36
-
37
- for indopts in diff
38
- plv8.execute "SELECT __drop_index($1,$2,$3)", [table_schema, table_name, indopts]
39
-
40
- diff = _.reject( NEW?.data?.indexes, differ(OLD) )
41
-
42
- for indopts in diff
43
- plv8.execute "SELECT __create_index($1,$2,$3)", [table_schema, table_name, indopts]
44
-
45
- when "DELETE"
46
- for indopts in Old?.data?.indexes or []
47
- plv8.execute "SELECT __drop_index($1,$2,$3)", [table_schema, table_name, indopts]
48
- plv8.execute "SELECT __drop_table($1,$2)",[table_schema , table_name]
12
+ actn.funcs.model_callbacks(TG_OP, NEW, OLD);
49
13
 
50
- $$ LANGUAGE plcoffee STABLE STRICT;
14
+ $$ LANGUAGE plv8 STABLE STRICT;
51
15
 
52
16
  CREATE TRIGGER core_models_callback_trigger
53
17
  AFTER INSERT OR UPDATE OR DELETE ON core.models
data/db/__functions.sql CHANGED
@@ -1,161 +1,100 @@
1
1
  -- PLV8 Functions
2
2
 
3
3
  CREATE or REPLACE FUNCTION __json(_data json, _key text) RETURNS JSON AS $$
4
- ret = actn.valueAt(_data,_key)
5
- return null unless ret?
6
- return JSON.stringify(ret)
7
-
8
- $$ LANGUAGE plcoffee STABLE STRICT;
4
+ return actn.funcs.__json(_data, _key);
5
+ $$ LANGUAGE plv8 STABLE STRICT;
9
6
 
10
7
 
11
8
 
12
9
 
13
10
 
14
11
  CREATE or REPLACE FUNCTION __string(_data json, _key text) RETURNS TEXT AS $$
15
- ret = actn.valueAt(_data,_key)
16
- return null unless ret?
17
- return ret.toString()
12
+ return actn.funcs.__string(_data, _key);
18
13
 
19
- $$ LANGUAGE plcoffee IMMUTABLE STRICT;
14
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
20
15
 
21
16
 
22
17
 
23
18
 
24
19
 
25
20
  CREATE or REPLACE FUNCTION __integer(_data json, _key text) RETURNS INT AS $$
26
- ret = actn.valueAt(_data,_key)
27
- return null unless ret?
28
- return parseInt(ret)
21
+ return actn.funcs.__integer(_data, _key);
29
22
 
30
- $$ LANGUAGE plcoffee IMMUTABLE STRICT;
23
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
31
24
 
32
25
 
33
26
 
34
27
 
35
28
 
36
29
  CREATE or REPLACE FUNCTION __integer_array(_data json, _key text) RETURNS INT[] AS $$
37
- ret = actn.valueAt(_data,_key)
38
- return null unless ret?
39
- return (if ret instanceof Array then ret else [ret])
30
+ return actn.funcs.__integer_array(_data, _key);
40
31
 
41
- $$ LANGUAGE plcoffee IMMUTABLE STRICT;
32
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
42
33
 
43
34
 
44
35
 
45
36
 
46
37
 
47
38
  CREATE or REPLACE FUNCTION __float(_data json, _key text) RETURNS DOUBLE PRECISION AS $$
48
- ret = actn.valueAt(_data,_key)
49
- return null unless ret?
50
- return parseFloat(ret)
39
+ return actn.funcs.__float(_data, _key);
51
40
 
52
- $$ LANGUAGE plcoffee IMMUTABLE STRICT;
41
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
53
42
 
54
43
 
55
44
 
56
45
 
57
46
 
58
47
  CREATE or REPLACE FUNCTION __bool(_data json, _key text) RETURNS BOOLEAN AS $$
59
- ret = actn.valueAt(_data,_key)
60
- return null unless ret?
61
- return !!ret
48
+ return actn.funcs.__bool(_data, _key);
62
49
 
63
- $$ LANGUAGE plcoffee IMMUTABLE STRICT;
50
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
64
51
 
65
52
 
66
53
 
67
54
 
68
55
 
69
56
  CREATE or REPLACE FUNCTION __timestamp(_data json, _key text) RETURNS TIMESTAMP AS $$
70
- ret = actn.valueAt(_data,_key)
71
- return null unless ret?
72
- return new Date(ret)
57
+ return actn.funcs.__timestamp(_data, _key);
73
58
 
74
- $$ LANGUAGE plcoffee IMMUTABLE STRICT;
59
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
75
60
 
76
61
 
77
62
 
78
63
 
79
64
 
80
65
  CREATE or REPLACE FUNCTION __patch(_data json, _value json, _sync boolean) RETURNS JSON AS $$
66
+ return actn.funcs.__patch(_data, _value, _sync);
81
67
 
82
- data = _data
83
- changes = _value
84
- isObject = false
85
-
86
- sync = if _sync? then _sync else true
87
-
88
- defaults = _.pick( data, _.keys( JSON.parse( plv8.find_function('__defaults')() ) ) )
89
-
90
- for k of changes
91
- if data.hasOwnProperty(k)
92
- isObject = typeof (data[k]) is "object" and typeof (changes[k]) is "object"
93
- data[k] = if isObject and sync then _.extend(data[k], changes[k]) else changes[k]
94
- else
95
- data[k] = changes[k]
96
-
97
- unless sync
98
- for k of data
99
- delete data[k] unless changes[k]?
100
-
101
- _.extend(data, defaults)
102
-
103
- return JSON.stringify(data)
104
-
105
- $$ LANGUAGE plcoffee STABLE STRICT;
68
+ $$ LANGUAGE plv8 STABLE STRICT;
106
69
 
107
70
 
108
71
 
109
72
 
110
73
 
111
74
  CREATE or REPLACE FUNCTION __select(_data json, _fields text) RETURNS JSON AS $$
112
-
113
- data = _data
114
- fields = _fields
115
- ret = _.pick(data,fields.split(","))
116
-
117
- return JSON.stringify(ret)
75
+ return actn.funcs.__select(_data, _fields);
118
76
 
119
- $$ LANGUAGE plcoffee STABLE STRICT;
77
+ $$ LANGUAGE plv8 STABLE STRICT;
120
78
 
121
79
 
122
80
 
123
81
 
124
82
 
125
83
  CREATE or REPLACE FUNCTION __push(_data json, _key text, _value json) RETURNS JSON AS $$
84
+ return actn.funcs.__push(_data, _key, _value);
85
+
126
86
 
127
- data = _data
128
- value = _value
129
- keys = _key.split(".")
130
- len = keys.length
131
- last_field = data
132
- field = data
133
- i = 0
134
-
135
- while i < len
136
- last_field = field
137
- field = field[keys[i]] if field
138
- ++i
139
- if field
140
- field.push value
141
- else
142
- value = [value] unless value instanceof Array
143
- last_field[keys.pop()] = value
144
-
145
- return JSON.stringify(data)
146
-
147
- $$ LANGUAGE plcoffee STABLE STRICT;
87
+ $$ LANGUAGE plv8 STABLE STRICT;
148
88
 
149
89
 
150
90
 
151
91
 
152
92
 
153
93
  CREATE or REPLACE FUNCTION __uuid() RETURNS JSON AS $$
94
+ return actn.funcs.__uuid();
95
+
154
96
 
155
- ary = plv8.execute 'SELECT uuid_generate_v4() as uuid;'
156
- return JSON.stringify(ary[0])
157
-
158
- $$ LANGUAGE plcoffee STABLE STRICT;
97
+ $$ LANGUAGE plv8 STABLE STRICT;
159
98
 
160
99
 
161
100
 
@@ -163,41 +102,28 @@ $$ LANGUAGE plcoffee STABLE STRICT;
163
102
 
164
103
 
165
104
  CREATE or REPLACE FUNCTION __defaults() RETURNS JSON AS $$
105
+ return actn.funcs.__defaults();
166
106
 
167
- uuid = JSON.parse(plv8.find_function('__uuid')())
168
- timestamp = new Date()
169
- return JSON.stringify({uuid: uuid.uuid, created_at: timestamp, updated_at: timestamp})
170
-
171
- $$ LANGUAGE plcoffee STABLE STRICT;
107
+ $$ LANGUAGE plv8 STABLE STRICT;
172
108
 
173
109
 
174
110
 
175
111
 
176
112
 
177
113
  CREATE or REPLACE FUNCTION __create_table(schema_name text, table_name text) RETURNS JSON AS $$
178
-
179
- plv8.execute """
180
- CREATE TABLE #{schema_name}.#{table_name} (
181
- id serial NOT NULL,
182
- data json DEFAULT __uuid() NOT NULL,
183
- CONSTRAINT #{schema_name}_#{table_name}_pkey PRIMARY KEY (id));
184
-
185
- CREATE UNIQUE INDEX indx_#{schema_name}_#{table_name}_unique_uuid ON #{schema_name}.#{table_name} (__string(data,'uuid'));
186
- """
187
- return JSON.stringify(table_name)
114
+ return actn.funcs.__create_table(schema_name, table_name);
115
+
188
116
 
189
- $$ LANGUAGE plcoffee STABLE STRICT;
117
+ $$ LANGUAGE plv8 STABLE STRICT;
190
118
 
191
119
 
192
120
 
193
121
 
194
122
 
195
123
  CREATE or REPLACE FUNCTION __drop_table(schema_name text, table_name text) RETURNS JSON AS $$
196
-
197
- plv8.execute "DROP TABLE IF EXISTS #{schema_name}.#{table_name} CASCADE;"
198
- return JSON.stringify(table_name)
124
+ return actn.funcs.__drop_table(schema_name, table_name);
199
125
 
200
- $$ LANGUAGE plcoffee STABLE STRICT;
126
+ $$ LANGUAGE plv8 STABLE STRICT;
201
127
 
202
128
 
203
129
 
@@ -205,46 +131,19 @@ $$ LANGUAGE plcoffee STABLE STRICT;
205
131
 
206
132
  CREATE or REPLACE FUNCTION __create_index(schema_name text, table_name text, optns json) RETURNS JSON AS $$
207
133
 
208
- index_name = "indx_#{schema_name}_#{table_name}"
209
- for name, type of optns.cols
210
- index_name += "_#{name}"
211
-
212
- sql = ["CREATE"]
213
- sql.push "UNIQUE" if optns.unique
214
- sql.push "INDEX"
215
- sql.push "CONCURRENTLY" if optns.concurrently
216
- sql.push "#{index_name} on #{schema_name}.#{table_name}"
217
- sql.push "("
218
- cols = []
219
- for name, type of optns.cols
220
- meth = "__#{if type is 'text' then 'string' else type}"
221
- cols.push "#{meth}(data,'#{name}'::#{type})"
222
- sql.push cols.join(",")
223
- sql.push ")"
224
-
225
- sql = sql.join(" ")
226
-
227
- plv8.execute(sql)
228
-
229
- return JSON.stringify(index_name)
134
+ return actn.funcs.__create_index(schema_name, table_name, optns);
230
135
 
231
- $$ LANGUAGE plcoffee STABLE STRICT;
136
+ $$ LANGUAGE plv8 STABLE STRICT;
232
137
 
233
138
 
234
139
 
235
140
 
236
141
 
237
142
  CREATE or REPLACE FUNCTION __drop_index(schema_name text, table_name text, optns json) RETURNS JSON AS $$
238
-
239
- index_name = "indx_#{schema_name}_#{table_name}"
240
- for name, type of optns.cols
241
- index_name += "_#{name}"
242
-
243
- plv8.execute("DROP INDEX IF EXISTS #{index_name}")
143
+ return actn.funcs.__drop_index(schema_name, table_name, optns);
244
144
 
245
- return JSON.stringify(index_name)
246
145
 
247
- $$ LANGUAGE plcoffee STABLE STRICT;
146
+ $$ LANGUAGE plv8 STABLE STRICT;
248
147
 
249
148
 
250
149
 
@@ -256,26 +155,10 @@ $$ LANGUAGE plcoffee STABLE STRICT;
256
155
  -- # SELECT query(_schema_name, _table_name, {where: {uuid: "12345"}});
257
156
 
258
157
  CREATE or REPLACE FUNCTION __query(_schema_name text, _table_name text, _query json) RETURNS json AS $$
259
-
260
- search_path = if _schema_name is "public" then _schema_name else "#{_schema_name}, public"
261
-
262
- builder = new actn.Builder(_schema_name, _table_name, search_path, _query)
263
-
264
- [sql,params] = builder.build_select()
265
-
266
- rows = plv8.execute(sql,params)
158
+ return actn.funcs.__query(_schema_name, _table_name, _query);
267
159
 
268
- builder = null
269
-
270
- if _query?.select?.indexOf('COUNT') > -1
271
- result = rows
272
- else
273
- result = _.pluck(rows,'data')
274
-
275
-
276
- return JSON.stringify(result)
277
160
 
278
- $$ LANGUAGE plcoffee STABLE;
161
+ $$ LANGUAGE plv8 STABLE;
279
162
 
280
163
 
281
164
 
@@ -286,45 +169,9 @@ $$ LANGUAGE plcoffee STABLE;
286
169
  -- # SELECT upsert(validate('User', '{"name":"foo"}'));
287
170
 
288
171
  CREATE or REPLACE FUNCTION __upsert(_schema_name text, _table_name text, _data json) RETURNS json AS $$
289
-
290
- # plv8.elog(NOTICE,"UPSERT",JSON.stringify(_data))
291
-
292
- return JSON.stringify(_data) if _data.errors?
293
-
294
- data = _data
295
-
296
- search_path = if _schema_name is "public" then _schema_name else "#{_schema_name},public"
297
-
298
- if data.uuid?
299
-
300
- query = { where: { uuid: data.uuid } }
301
-
302
- builder = new actn.Builder(_schema_name, _table_name, search_path, query )
303
-
304
- [sql,params] = builder.build_update(data)
305
-
306
- else
307
-
308
- builder = new actn.Builder(_schema_name, _table_name, search_path, {})
309
-
310
- [sql,params] = builder.build_insert(data)
311
-
312
-
313
- # plan = plv8.prepare(sql, ['json','bool','text'])
314
-
315
- # plv8.elog(NOTICE,sql,JSON.stringify(params))
316
-
317
- rows = plv8.execute(sql, params)
318
-
319
- result = _.pluck(rows,'data')
320
-
321
- result = result[0] if result.length is 1
322
-
323
- builder = null
324
-
325
- return JSON.stringify(result)
172
+ return actn.funcs.__upsert(_schema_name, _table_name, _data);
326
173
 
327
- $$ LANGUAGE plcoffee STABLE STRICT;
174
+ $$ LANGUAGE plv8 STABLE STRICT;
328
175
 
329
176
 
330
177
 
@@ -335,24 +182,9 @@ $$ LANGUAGE plcoffee STABLE STRICT;
335
182
  -- # SELECT remove('users',uuid-1234567);
336
183
 
337
184
  CREATE or REPLACE FUNCTION __update(_schema_name text, _table_name text, _data json, _cond json) RETURNS json AS $$
338
-
339
- return JSON.stringify(_data) if _data.errors?
340
-
341
- search_path = if _schema_name is "public" then _schema_name else "#{_schema_name},public"
342
-
343
- builder = new actn.Builder(_schema_name, _table_name, search_path, {where: _cond})
344
-
345
- [sql,params] = builder.build_update(_data)
346
-
347
- rows = plv8.execute(sql,params)
348
- result = _.pluck(rows,'data')
349
- result = result[0] if result.length is 1
350
-
351
- builder = null
352
-
353
- return JSON.stringify(result)
185
+ return actn.funcs.__update(_schema_name, _table_name, _data, _cond);
354
186
 
355
- $$ LANGUAGE plcoffee STABLE STRICT;
187
+ $$ LANGUAGE plv8 STABLE STRICT;
356
188
 
357
189
 
358
190
 
@@ -363,24 +195,10 @@ $$ LANGUAGE plcoffee STABLE STRICT;
363
195
  -- # SELECT remove('users',uuid-1234567);
364
196
 
365
197
  CREATE or REPLACE FUNCTION __delete(_schema_name text, _table_name text, _cond json) RETURNS json AS $$
198
+ return actn.funcs.__delete(_schema_name, _table_name, _cond);
366
199
 
367
- search_path = if _schema_name is "public" then _schema_name else "#{_schema_name},public"
368
-
369
- builder = new actn.Builder(_schema_name, _table_name, search_path, {where: _cond})
370
-
371
- [sql,params] = builder.build_delete()
372
-
373
- # plv8.elog(NOTICE,"DELETE",sql,params)
374
-
375
- rows = plv8.execute(sql,params)
376
- result = _.pluck(rows,'data')
377
- result = result[0] if result.length is 1
378
-
379
- builder = null
380
-
381
- return JSON.stringify(result)
382
200
 
383
- $$ LANGUAGE plcoffee STABLE STRICT;
201
+ $$ LANGUAGE plv8 STABLE STRICT;
384
202
 
385
203
 
386
204
 
@@ -393,55 +211,10 @@ $$ LANGUAGE plcoffee STABLE STRICT;
393
211
  -- # SELECT validate(model_name, data);
394
212
 
395
213
  CREATE or REPLACE FUNCTION __validate(_name text, _data json) RETURNS json AS $$
396
-
397
- data = _data
214
+ return actn.funcs.__validate(_name, _data);
398
215
 
399
- # plv8.elog(NOTICE,"__VALIDATE",_name,JSON.stringify(_data))
400
-
401
- return data unless model = plv8.find_function('__find_model')(_name)
402
-
403
- model = JSON.parse(model)
404
-
405
- # plv8.elog(NOTICE,"__VALIDATE MODEL",_name,JSON.stringify(model))
406
-
407
- if model?.schema?
408
-
409
- errors = actn.jjv.validate(model.schema,data)
410
-
411
- plv8.elog(NOTICE,"VALVAL",JSON.stringify(model.schema))
412
-
413
- if data.uuid? and model.schema.readonly_attributes?
414
-
415
- data = _.omit(data,model.schema.readonly_attributes)
416
-
417
- # plv8.elog(NOTICE,"VALIDATE READONLY",JSON.stringify(data),JSON.stringify(model.schema.readonly_attributes))
418
-
419
-
420
- else if model.schema.unique_attributes?
421
-
422
- _schema = if _name is "Model" then "core" else "public"
423
- _table = model.name.tableize()
424
- __query = plv8.find_function("__query")
425
-
426
- for uniq_attr in model.schema.unique_attributes or []
427
- if data[uniq_attr]?
428
- where = {}
429
- where[uniq_attr] = data[uniq_attr]
430
- # plv8.elog(NOTICE,"VALIDATE WHERE",JSON.stringify({where: where}))
431
- found = JSON.parse(__query(_schema,_table,{where: where}))
432
- # plv8.elog(NOTICE,"VALIDATE FOUND",JSON.stringify(found))
433
- unless _.isEmpty(found)
434
- errors ?= {validation: {}}
435
- errors['validation'][uniq_attr] ?= {}
436
- errors['validation'][uniq_attr]["has already been taken"] = true
437
-
438
- data = {errors: errors} if errors?
439
-
440
- # plv8.elog(NOTICE,"__VALIDATE DATA",_name,JSON.stringify(data))
441
-
442
- return data
443
216
 
444
- $$ LANGUAGE plcoffee STABLE STRICT;
217
+ $$ LANGUAGE plv8 STABLE STRICT;
445
218
 
446
219
 
447
220
 
@@ -452,18 +225,10 @@ $$ LANGUAGE plcoffee STABLE STRICT;
452
225
  -- # SELECT __find_model(model_name);
453
226
 
454
227
  CREATE or REPLACE FUNCTION __find_model(_name text) RETURNS json AS $$
455
-
456
- rows = plv8.execute("""SET search_path TO core,public;
457
- SELECT data FROM core.models
458
- WHERE __string(data,'name'::text) = $1::text""", [_name])
228
+ return actn.funcs.__find_model(_name);
459
229
 
460
- return unless rows?
461
-
462
- result = _.pluck(rows,'data')[0]
463
-
464
- return JSON.stringify(result)
465
230
 
466
- $$ LANGUAGE plcoffee STABLE STRICT;
231
+ $$ LANGUAGE plv8 STABLE STRICT;
467
232
 
468
233
 
469
234