actn-db 0.0.3 → 0.0.4

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: 5ca2965b4c761b78728413b0c7a0fef06bbb1432
4
- data.tar.gz: 04739049558b259764222239754d5f35230ae0d1
3
+ metadata.gz: dd259d933b75cb3242fb249565474fc0148dd845
4
+ data.tar.gz: d62618f10c7f70e88666f1b3a92d3b11c7a8441f
5
5
  SHA512:
6
- metadata.gz: 01e20e754b6e96bcd1e796cab2dd167073d735ec8c44b1fe1b802fbd712720cc4a83e3f262a79cb42589d5c5c0d015de6a708a2d2f8d02989358745cb83106a1
7
- data.tar.gz: 570c971b36b4337645a7ff0bac4fb074848b1a065341bc4fcbabaeff20353edcc0f962af30c806f73a96273484cfd8b0178a6e147ad6a9ddd32e44b3b7eeb41f
6
+ metadata.gz: 87e5f43fb7a3e59e4c5f38fd0f58f8de1e19444602d1f5d09d3a7608577f95d944884d01a38811654da271bc0a4e8a8f275b666411a393a55124134a4596f7b1
7
+ data.tar.gz: 4b40c257fa8b7a2ed85401f8013742fe99ff16f462098bebd2eb8ab55d14dabc975d07ce783815ec8109d4232d3053a10e5f0e336550a223059d6f5deede406e
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in actn-db.gemspec
4
- gemspec
4
+ gemspec
data/Rakefile CHANGED
@@ -9,4 +9,4 @@ end
9
9
  task :default => :test
10
10
 
11
11
  ENV['DATABASE_URL'] ||= "postgres://localhost:5432/actn_#{ENV['RACK_ENV'] ||= "development"}"
12
- load "actn/db/tasks/db.rake"
12
+ load "actn/db/tasks/db.rake"
@@ -7,10 +7,8 @@ SELECT __create_table('core','models');
7
7
  SELECT __create_index('core','models', '{"cols": {"name": "text"},"unique": true}');
8
8
 
9
9
 
10
- CREATE or REPLACE FUNCTION model_callbacks() RETURNS trigger AS
11
- $$
10
+ CREATE or REPLACE FUNCTION model_callbacks() RETURNS trigger AS $$
12
11
  actn.funcs.model_callbacks(TG_OP, NEW, OLD);
13
-
14
12
  $$ LANGUAGE plv8 STABLE STRICT;
15
13
 
16
14
  CREATE TRIGGER core_models_callback_trigger
@@ -6,232 +6,150 @@ $$ LANGUAGE plv8 STABLE STRICT;
6
6
 
7
7
 
8
8
 
9
-
10
-
11
9
  CREATE or REPLACE FUNCTION __string(_data json, _key text) RETURNS TEXT AS $$
12
10
  return actn.funcs.__string(_data, _key);
13
-
14
11
  $$ LANGUAGE plv8 IMMUTABLE STRICT;
15
12
 
16
13
 
17
14
 
18
-
19
-
20
15
  CREATE or REPLACE FUNCTION __integer(_data json, _key text) RETURNS INT AS $$
21
16
  return actn.funcs.__integer(_data, _key);
22
-
23
17
  $$ LANGUAGE plv8 IMMUTABLE STRICT;
24
18
 
25
19
 
26
20
 
27
-
28
-
29
21
  CREATE or REPLACE FUNCTION __integer_array(_data json, _key text) RETURNS INT[] AS $$
30
22
  return actn.funcs.__integer_array(_data, _key);
31
-
32
23
  $$ LANGUAGE plv8 IMMUTABLE STRICT;
33
24
 
34
25
 
35
26
 
36
-
37
-
38
27
  CREATE or REPLACE FUNCTION __float(_data json, _key text) RETURNS DOUBLE PRECISION AS $$
39
28
  return actn.funcs.__float(_data, _key);
40
-
41
29
  $$ LANGUAGE plv8 IMMUTABLE STRICT;
42
30
 
43
31
 
44
32
 
45
-
46
-
47
33
  CREATE or REPLACE FUNCTION __bool(_data json, _key text) RETURNS BOOLEAN AS $$
48
34
  return actn.funcs.__bool(_data, _key);
49
-
50
35
  $$ LANGUAGE plv8 IMMUTABLE STRICT;
51
36
 
52
37
 
53
38
 
54
-
55
-
56
39
  CREATE or REPLACE FUNCTION __timestamp(_data json, _key text) RETURNS TIMESTAMP AS $$
57
40
  return actn.funcs.__timestamp(_data, _key);
58
-
59
41
  $$ LANGUAGE plv8 IMMUTABLE STRICT;
60
42
 
61
43
 
62
44
 
63
-
64
-
65
45
  CREATE or REPLACE FUNCTION __patch(_data json, _value json, _sync boolean) RETURNS JSON AS $$
66
46
  return actn.funcs.__patch(_data, _value, _sync);
67
-
68
47
  $$ LANGUAGE plv8 STABLE STRICT;
69
48
 
70
49
 
71
50
 
72
-
73
-
74
51
  CREATE or REPLACE FUNCTION __select(_data json, _fields text) RETURNS JSON AS $$
75
- return actn.funcs.__select(_data, _fields);
76
-
52
+ return actn.funcs.__select(_data, _fields);
77
53
  $$ LANGUAGE plv8 STABLE STRICT;
78
54
 
79
55
 
80
56
 
81
-
82
-
83
57
  CREATE or REPLACE FUNCTION __push(_data json, _key text, _value json) RETURNS JSON AS $$
84
58
  return actn.funcs.__push(_data, _key, _value);
85
-
86
-
87
59
  $$ LANGUAGE plv8 STABLE STRICT;
88
60
 
89
61
 
90
62
 
91
-
92
-
93
63
  CREATE or REPLACE FUNCTION __uuid() RETURNS JSON AS $$
94
- return actn.funcs.__uuid();
95
-
96
-
64
+ return actn.funcs.__uuid();
97
65
  $$ LANGUAGE plv8 STABLE STRICT;
98
66
 
99
67
 
100
68
 
101
-
102
-
103
-
104
69
  CREATE or REPLACE FUNCTION __defaults() RETURNS JSON AS $$
105
70
  return actn.funcs.__defaults();
106
-
107
71
  $$ LANGUAGE plv8 STABLE STRICT;
108
72
 
109
73
 
110
74
 
111
-
112
-
113
75
  CREATE or REPLACE FUNCTION __create_table(schema_name text, table_name text) RETURNS JSON AS $$
114
- return actn.funcs.__create_table(schema_name, table_name);
115
-
116
-
76
+ return actn.funcs.__create_table(schema_name, table_name);
117
77
  $$ LANGUAGE plv8 STABLE STRICT;
118
78
 
119
79
 
120
80
 
121
-
122
-
123
81
  CREATE or REPLACE FUNCTION __drop_table(schema_name text, table_name text) RETURNS JSON AS $$
124
- return actn.funcs.__drop_table(schema_name, table_name);
125
-
82
+ return actn.funcs.__drop_table(schema_name, table_name);
126
83
  $$ LANGUAGE plv8 STABLE STRICT;
127
84
 
128
85
 
129
86
 
130
-
131
-
132
87
  CREATE or REPLACE FUNCTION __create_index(schema_name text, table_name text, optns json) RETURNS JSON AS $$
133
-
134
88
  return actn.funcs.__create_index(schema_name, table_name, optns);
135
-
136
89
  $$ LANGUAGE plv8 STABLE STRICT;
137
90
 
138
91
 
139
92
 
140
-
141
-
142
93
  CREATE or REPLACE FUNCTION __drop_index(schema_name text, table_name text, optns json) RETURNS JSON AS $$
143
- return actn.funcs.__drop_index(schema_name, table_name, optns);
144
-
145
-
94
+ return actn.funcs.__drop_index(schema_name, table_name, optns);
146
95
  $$ LANGUAGE plv8 STABLE STRICT;
147
96
 
148
97
 
149
98
 
150
-
151
-
152
-
153
99
  -- ##
154
100
  -- # Select data
155
101
  -- # SELECT query(_schema_name, _table_name, {where: {uuid: "12345"}});
156
102
 
157
103
  CREATE or REPLACE FUNCTION __query(_schema_name text, _table_name text, _query json) RETURNS json AS $$
158
104
  return actn.funcs.__query(_schema_name, _table_name, _query);
159
-
160
-
161
105
  $$ LANGUAGE plv8 STABLE;
162
106
 
163
107
 
164
108
 
165
-
166
-
167
109
  -- ##
168
110
  -- # Insert ot update row through validation!
169
111
  -- # SELECT upsert(validate('User', '{"name":"foo"}'));
170
112
 
171
113
  CREATE or REPLACE FUNCTION __upsert(_schema_name text, _table_name text, _data json) RETURNS json AS $$
172
- return actn.funcs.__upsert(_schema_name, _table_name, _data);
173
-
114
+ return actn.funcs.__upsert(_schema_name, _table_name, _data);
174
115
  $$ LANGUAGE plv8 STABLE STRICT;
175
116
 
176
117
 
177
118
 
178
-
179
-
180
119
  -- ##
181
120
  -- # Delete single row by uuid
182
121
  -- # SELECT remove('users',uuid-1234567);
183
122
 
184
123
  CREATE or REPLACE FUNCTION __update(_schema_name text, _table_name text, _data json, _cond json) RETURNS json AS $$
185
- return actn.funcs.__update(_schema_name, _table_name, _data, _cond);
186
-
124
+ return actn.funcs.__update(_schema_name, _table_name, _data, _cond);
187
125
  $$ LANGUAGE plv8 STABLE STRICT;
188
126
 
189
127
 
190
128
 
191
-
192
-
193
129
  -- ##
194
130
  -- # Delete single row by uuid
195
131
  -- # SELECT remove('users',uuid-1234567);
196
132
 
197
133
  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);
199
-
200
-
134
+ return actn.funcs.__delete(_schema_name, _table_name, _cond);
201
135
  $$ LANGUAGE plv8 STABLE STRICT;
202
136
 
203
137
 
204
138
 
205
-
206
-
207
-
208
-
209
139
  -- ##
210
140
  -- # Validate data by json schema
211
141
  -- # SELECT validate(model_name, data);
212
142
 
213
143
  CREATE or REPLACE FUNCTION __validate(_name text, _data json) RETURNS json AS $$
214
- return actn.funcs.__validate(_name, _data);
215
-
216
-
144
+ return actn.funcs.__validate(_name, _data);
217
145
  $$ LANGUAGE plv8 STABLE STRICT;
218
146
 
219
147
 
220
148
 
221
-
222
-
223
149
  -- ##
224
150
  -- # finds model with given name
225
151
  -- # SELECT __find_model(model_name);
226
152
 
227
153
  CREATE or REPLACE FUNCTION __find_model(_name text) RETURNS json AS $$
228
- return actn.funcs.__find_model(_name);
229
-
230
-
154
+ return actn.funcs.__find_model(_name);
231
155
  $$ LANGUAGE plv8 STABLE STRICT;
232
-
233
-
234
-
235
-
236
-
237
-
@@ -6,34 +6,25 @@ CREATE EXTENSION IF NOT EXISTS "plv8";
6
6
 
7
7
 
8
8
 
9
-
10
9
  -- Js Libs
11
10
 
12
11
  CREATE TABLE plv8_modules(modname text primary key, load_on_start boolean, code text);
13
12
 
14
13
  CREATE OR REPLACE FUNCTION plv8_startup() RETURNS void AS $$
15
14
 
16
- var code, load_module, r, rows;
17
-
18
- load_module = function(modname) {
19
- var code, r, rows;
20
- rows = plv8.execute("SELECT code from public.plv8_modules " + " where modname = $1", [modname]);
21
- r = 0;
22
- while (r < rows.length) {
23
- code = rows[r].code;
24
- eval("(function(){" + code + "})")();
25
- r++;
26
- }
27
- };
15
+ var code, r, rows;
28
16
 
29
- rows = plv8.execute("SELECT modname, code from public.plv8_modules where load_on_start");
17
+ code = "";
18
+
19
+ rows = plv8.execute("SELECT modname, code from public.plv8_modules order by modname");
30
20
 
31
21
  r = 0;
32
22
 
33
23
  while (r < rows.length) {
34
- code = rows[r].code;
35
- eval("(function(){" + code + "})")();
24
+ code += rows[r].code;
36
25
  r++;
37
26
  }
27
+
28
+ eval("(function(){" + code + "})")();
38
29
 
39
30
  $$ LANGUAGE plv8 STABLE STRICT;
@@ -734,6 +734,5 @@
734
734
  define(function () {return Environment;});
735
735
  else
736
736
  this.jjv = Environment;
737
- }).call(this);
738
-
739
- global.actn.jjv = jjv();
737
+
738
+ }).call(this);
@@ -0,0 +1,31 @@
1
+ // global = (function() {
2
+ // return this;
3
+ // }).call(null);
4
+
5
+ (function(){
6
+
7
+ var root = this,
8
+
9
+ Actn = (function() {
10
+ function Actn() {}
11
+
12
+ Actn.prototype.valueAt = function(data, key) {
13
+ var i, keys;
14
+ keys = key.split(".");
15
+ for (i in keys) {
16
+ if (data != null) {
17
+ data = data[keys[i]];
18
+ }
19
+ }
20
+ return data;
21
+ };
22
+
23
+ return Actn;
24
+
25
+ })();
26
+
27
+ root.actn = new Actn();
28
+
29
+ root.actn.jjv = jjv();
30
+
31
+ }).call(this);
@@ -0,0 +1,387 @@
1
+ (->
2
+ root = this
3
+
4
+ class Funcs
5
+
6
+ __json: (_data, _key) ->
7
+ ret = actn.valueAt(_data,_key)
8
+ return null unless ret?
9
+ return JSON.stringify(ret)
10
+
11
+ __string: (_data, _key) ->
12
+ ret = actn.valueAt(_data,_key)
13
+ return null unless ret?
14
+ return ret.toString()
15
+
16
+ __integer: (_data, _key) ->
17
+ ret = actn.valueAt(_data,_key)
18
+ return null unless ret?
19
+ return parseInt(ret)
20
+
21
+ __integer_array: (_data, _key) ->
22
+ ret = actn.valueAt(_data,_key)
23
+ return null unless ret?
24
+ return (if ret instanceof Array then ret else [ret])
25
+
26
+ __float: (_data, _key) ->
27
+ ret = actn.valueAt(_data,_key)
28
+ return null unless ret?
29
+ return parseFloat(ret)
30
+
31
+ __bool: (_data, _key) ->
32
+ ret = actn.valueAt(_data,_key)
33
+ return null unless ret?
34
+ return !!ret
35
+
36
+ __timestamp: (_data, _key) ->
37
+ ret = actn.valueAt(_data,_key)
38
+ return null unless ret?
39
+ return new Date(ret)
40
+
41
+ __patch: (_data, _value, _sync) ->
42
+
43
+ data = _data
44
+ changes = _value
45
+ isObject = false
46
+
47
+ sync = if _sync? then _sync else true
48
+
49
+ defaults = _.pick( data, _.keys( JSON.parse( plv8.find_function('__defaults')() ) ) )
50
+
51
+ for k of changes
52
+ if data.hasOwnProperty(k)
53
+ isObject = typeof (data[k]) is "object" and typeof (changes[k]) is "object"
54
+ data[k] = if isObject and sync then _.extend(data[k], changes[k]) else changes[k]
55
+ else
56
+ data[k] = changes[k]
57
+
58
+ unless sync
59
+ for k of data
60
+ delete data[k] unless changes[k]?
61
+
62
+ _.extend(data, defaults)
63
+
64
+ return JSON.stringify(data)
65
+
66
+ __select: (_data, _fields) ->
67
+ data = _data
68
+ fields = _fields
69
+ ret = _.pick(data,fields.split(","))
70
+
71
+ return JSON.stringify(ret)
72
+
73
+ __push: (_data, _key, _value) ->
74
+ data = _data
75
+ value = _value
76
+ keys = _key.split(".")
77
+ len = keys.length
78
+ last_field = data
79
+ field = data
80
+ i = 0
81
+
82
+ while i < len
83
+ last_field = field
84
+ field = field[keys[i]] if field
85
+ ++i
86
+ if field
87
+ field.push value
88
+ else
89
+ value = [value] unless value instanceof Array
90
+ last_field[keys.pop()] = value
91
+
92
+ return JSON.stringify(data)
93
+
94
+ __uuid: () ->
95
+ ary = plv8.execute 'SELECT uuid_generate_v4() as uuid;'
96
+ return JSON.stringify(ary[0])
97
+
98
+ __defaults: () ->
99
+ uuid = JSON.parse(plv8.find_function('__uuid')())
100
+ timestamp = new Date()
101
+ return JSON.stringify({uuid: uuid.uuid, created_at: timestamp, updated_at: timestamp})
102
+
103
+ __create_table: (schema_name, table_name) ->
104
+ plv8.execute """
105
+ CREATE TABLE #{schema_name}.#{table_name} (
106
+ id serial NOT NULL,
107
+ data json DEFAULT __uuid() NOT NULL,
108
+ CONSTRAINT #{schema_name}_#{table_name}_pkey PRIMARY KEY (id));
109
+
110
+ CREATE UNIQUE INDEX indx_#{schema_name}_#{table_name}_unique_uuid ON #{schema_name}.#{table_name} (__string(data,'uuid'));
111
+ """
112
+ return JSON.stringify(table_name)
113
+
114
+ __drop_table: (schema_name, table_name) ->
115
+ plv8.execute "DROP TABLE IF EXISTS #{schema_name}.#{table_name} CASCADE;"
116
+ return JSON.stringify(table_name)
117
+
118
+ __create_index: (schema_name, table_name, optns) ->
119
+ index_name = "indx_#{schema_name}_#{table_name}"
120
+ for name, type of optns.cols
121
+ index_name += "_#{name}"
122
+
123
+ sql = ["CREATE"]
124
+ sql.push "UNIQUE" if optns.unique
125
+ sql.push "INDEX"
126
+ sql.push "CONCURRENTLY" if optns.concurrently
127
+ sql.push "#{index_name} on #{schema_name}.#{table_name}"
128
+ sql.push "("
129
+ cols = []
130
+ for name, type of optns.cols
131
+ meth = "__#{if type is 'text' then 'string' else type}"
132
+ cols.push "#{meth}(data,'#{name}'::#{type})"
133
+ sql.push cols.join(",")
134
+ sql.push ")"
135
+
136
+ sql = sql.join(" ")
137
+
138
+ plv8.execute(sql)
139
+
140
+ return JSON.stringify(index_name)
141
+
142
+ __drop_index: (schema_name, table_name, optns) ->
143
+ index_name = "indx_#{schema_name}_#{table_name}"
144
+ for name, type of optns.cols
145
+ index_name += "_#{name}"
146
+
147
+ plv8.execute("DROP INDEX IF EXISTS #{index_name}")
148
+
149
+ return JSON.stringify(index_name)
150
+
151
+ __query: (_schema_name, _table_name, _query) ->
152
+ search_path = if _schema_name is "public" then _schema_name else "#{_schema_name}, public"
153
+
154
+ builder = new actn.Builder(_schema_name, _table_name, search_path, _query)
155
+
156
+ [sql,params] = builder.build_select()
157
+
158
+ rows = plv8.execute(sql,params)
159
+
160
+ builder = null
161
+
162
+ if _query?.select?.indexOf('COUNT') > -1
163
+ result = rows
164
+ else
165
+ result = _.pluck(rows,'data')
166
+
167
+
168
+ return JSON.stringify(result)
169
+
170
+ __upsert: (_schema_name, _table_name, _data) ->
171
+ # plv8.elog(NOTICE,"UPSERT",JSON.stringify(_data))
172
+
173
+ return JSON.stringify(_data) if _data.errors?
174
+
175
+ data = _data
176
+
177
+ search_path = if _schema_name is "public" then _schema_name else "#{_schema_name},public"
178
+
179
+ if data.uuid?
180
+
181
+ query = { where: { uuid: data.uuid } }
182
+
183
+ builder = new actn.Builder(_schema_name, _table_name, search_path, query )
184
+
185
+ [sql,params] = builder.build_update(data)
186
+
187
+ else
188
+
189
+ builder = new actn.Builder(_schema_name, _table_name, search_path, {})
190
+
191
+ [sql,params] = builder.build_insert(data)
192
+
193
+
194
+ # plan = plv8.prepare(sql, ['json','bool','text'])
195
+
196
+ # plv8.elog(NOTICE,sql,JSON.stringify(params))
197
+
198
+ rows = plv8.execute(sql, params)
199
+
200
+ result = _.pluck(rows,'data')
201
+
202
+ result = result[0] if result.length is 1
203
+
204
+ builder = null
205
+
206
+ return JSON.stringify(result)
207
+
208
+ __update: (_schema_name, _table_name, _data, _cond) ->
209
+ return JSON.stringify(_data) if _data.errors?
210
+
211
+ search_path = if _schema_name is "public" then _schema_name else "#{_schema_name},public"
212
+
213
+ builder = new actn.Builder(_schema_name, _table_name, search_path, {where: _cond})
214
+
215
+ [sql,params] = builder.build_update(_data)
216
+
217
+ rows = plv8.execute(sql,params)
218
+ result = _.pluck(rows,'data')
219
+ result = result[0] if result.length is 1
220
+
221
+ builder = null
222
+
223
+ return JSON.stringify(result)
224
+
225
+ __delete: (_schema_name, _table_name, _cond) ->
226
+ search_path = if _schema_name is "public" then _schema_name else "#{_schema_name},public"
227
+
228
+ builder = new actn.Builder(_schema_name, _table_name, search_path, {where: _cond})
229
+
230
+ [sql,params] = builder.build_delete()
231
+
232
+ # plv8.elog(NOTICE,"DELETE",sql,params)
233
+
234
+ rows = plv8.execute(sql,params)
235
+ result = _.pluck(rows,'data')
236
+ result = result[0] if result.length is 1
237
+
238
+ builder = null
239
+
240
+ return JSON.stringify(result)
241
+
242
+ __validate: (_name, _data) ->
243
+ data = _data
244
+
245
+ # plv8.elog(NOTICE,"__VALIDATE",_name,JSON.stringify(_data))
246
+
247
+ return data unless model = plv8.find_function('__find_model')(_name)
248
+
249
+ model = JSON.parse(model)
250
+
251
+ # plv8.elog(NOTICE,"__VALIDATE MODEL",_name,JSON.stringify(model))
252
+
253
+ if model?.schema?
254
+
255
+ errors = actn.jjv.validate(model.schema,data)
256
+
257
+ # plv8.elog(NOTICE,"VALVAL",JSON.stringify(model.schema))
258
+
259
+ if data.uuid? and model.schema.readonly_attributes?
260
+
261
+ data = _.omit(data,model.schema.readonly_attributes)
262
+
263
+ # plv8.elog(NOTICE,"VALIDATE READONLY",JSON.stringify(data),JSON.stringify(model.schema.readonly_attributes))
264
+
265
+
266
+ else if model.schema.unique_attributes?
267
+
268
+ _schema = if _name is "Model" then "core" else "public"
269
+ _table = model.name.tableize()
270
+ __query = plv8.find_function("__query")
271
+
272
+ for uniq_attr in model.schema.unique_attributes or []
273
+ if data[uniq_attr]?
274
+ where = {}
275
+ where[uniq_attr] = data[uniq_attr]
276
+ # plv8.elog(NOTICE,"VALIDATE WHERE",JSON.stringify({where: where}))
277
+ found = JSON.parse(__query(_schema,_table,{where: where}))
278
+ # plv8.elog(NOTICE,"VALIDATE FOUND",JSON.stringify(found))
279
+ unless _.isEmpty(found)
280
+ errors ?= {validation: {}}
281
+ errors['validation'][uniq_attr] ?= {}
282
+ errors['validation'][uniq_attr]["has already been taken"] = true
283
+
284
+ data = {errors: errors} if errors?
285
+
286
+ # plv8.elog(NOTICE,"__VALIDATE DATA",_name,JSON.stringify(data))
287
+
288
+ return data
289
+
290
+ __find_model: (_name) ->
291
+ rows = plv8.execute("""SET search_path TO core,public;
292
+ SELECT data FROM core.models
293
+ WHERE __string(data,'name'::text) = $1::text""", [_name])
294
+
295
+ return unless rows?
296
+
297
+ result = _.pluck(rows,'data')[0]
298
+
299
+ return JSON.stringify(result)
300
+
301
+ model_callbacks: (TG_OP, NEW, OLD) ->
302
+ table_name = (NEW?.data?.name or OLD?.data?.name)?.tableize()
303
+ table_schema = (NEW?.data?.table_schema or OLD?.data?.table_schema) or "public"
304
+
305
+ return if table_schema is "core"
306
+
307
+ # plv8.elog(NOTICE,"MODEL CALLBACKS",table_schema,JSON.stringify(NEW?.data or OLD?.data))
308
+
309
+ mapper = (ind) -> _.keys(ind.cols)
310
+ differ = (_ind) ->
311
+ (ind) ->
312
+ _.isEmpty( _.difference( _.keys(ind.cols), _.flatten( _.map( _ind.data?.indexes, mapper ) ) ) )
313
+
314
+ switch TG_OP
315
+ when "INSERT"
316
+ plv8.execute "SELECT __create_table($1,$2)",[table_schema , table_name]
317
+
318
+ plv8.execute "SELECT __create_index($1,$2,$3)", [table_schema, table_name, {cols: {path: "text" }}]
319
+
320
+ for indopts in NEW?.data?.indexes or []
321
+ plv8.execute "SELECT __create_index($1,$2,$3)", [table_schema, table_name, indopts]
322
+
323
+ when "UPDATE"
324
+
325
+ diff = _.reject( OLD?.data?.indexes, differ(NEW) )
326
+
327
+ for indopts in diff
328
+ plv8.execute "SELECT __drop_index($1,$2,$3)", [table_schema, table_name, indopts]
329
+
330
+ diff = _.reject( NEW?.data?.indexes, differ(OLD) )
331
+
332
+ for indopts in diff
333
+ plv8.execute "SELECT __create_index($1,$2,$3)", [table_schema, table_name, indopts]
334
+
335
+ when "DELETE"
336
+ for indopts in Old?.data?.indexes or []
337
+ plv8.execute "SELECT __drop_index($1,$2,$3)", [table_schema, table_name, indopts]
338
+ plv8.execute "SELECT __drop_table($1,$2)",[table_schema , table_name]
339
+
340
+ hook_trigger: (TG_TABLE_NAME, TG_OP, NEW, OLD) ->
341
+ upsert_func = plv8.find_function("__upsert")
342
+ model = JSON.parse(plv8.find_function("__find_model")(TG_TABLE_NAME.classify()))
343
+
344
+ callback = {
345
+ INSERT: "after_create"
346
+ UPDATE: "after_update"
347
+ DELETE: "after_destroy"
348
+ }[TG_OP]
349
+
350
+ # plv8.elog(NOTICE,"HOOK TRIGGER",JSON.stringify(model))
351
+
352
+ for hook in model?.hooks?[callback] or []
353
+ hook.run_at ?= new Date()
354
+ hook.callback = callback
355
+
356
+ job =
357
+ hook: hook
358
+ table_name: TG_TABLE_NAME
359
+ record_uuid: NEW?.data?.uuid or OLD?.data?.uuid
360
+ record: OLD.data if TG_OP is "DELETE"
361
+
362
+ res = upsert_func "core", "jobs", JSON.stringify(job)
363
+ plv8.execute "SELECT pg_notify('jobs', $1);", [res]
364
+
365
+ jobs_model_callbacks: (TG_TABLE_NAME, TG_OP, NEW, OLD) ->
366
+ table_name = (NEW?.data?.name or OLD?.data?.name).tableize()
367
+
368
+ table_schema = (NEW?.data?.table_schema or OLD?.data?.table_schema) or "public"
369
+
370
+ return if table_schema is "core"
371
+
372
+ if TG_OP is "DELETE"
373
+ plv8.execute "DELETE FROM core.jobs WHERE __string(data, 'table_name'::text) = $1;", [table_name]
374
+
375
+ # if TG_OP is "DELETE" and OLD.data.hooks? or TG_OP is "UPDATE" and NEW.data.hooks?
376
+ # plv8.execute "DROP TRIGGER IF EXISTS #{table_schema}_#{table_name}_hook_trigger ON #{table_schema}.#{table_name}"
377
+
378
+
379
+ if TG_OP is "INSERT" or TG_OP is "UPDATE" and NEW.data.hooks? and not OLD.data.hooks?
380
+ plv8.execute """CREATE TRIGGER #{table_schema}_#{table_name}_hook_trigger
381
+ AFTER INSERT OR UPDATE OR DELETE ON #{table_schema}.#{table_name}
382
+ FOR EACH ROW EXECUTE PROCEDURE hook_trigger();"""
383
+
384
+
385
+ root.actn.funcs = new Funcs
386
+
387
+ ).call this