actn-db 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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