audrey 0.2 → 0.3

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
  SHA256:
3
- metadata.gz: 61cf118da49fbae7bf7dbc82dbf03f1460fe26d9925b135374e97a930039d198
4
- data.tar.gz: ffc33814130bfcd6b24f70d3d4aebd5c71aff75922fa1cf9fb090789948d6fc9
3
+ metadata.gz: 0b9337b0db28e20ad953e7a75d36d9c10a4ed9e5a711dda30fd56a525e91b5ac
4
+ data.tar.gz: 704de739585df7193c7274f30b2f595e690d2077596160b55996e52e59640310
5
5
  SHA512:
6
- metadata.gz: b8e4a31b17b175e5c038ba1063bddafca7c9e68e59655a764fade27d6459b43232336fc263d32040e7b8e8f75f7c58066af6a433711b3a020efdffe111f9963f
7
- data.tar.gz: 8f015943ce4204efc60ba516bc6e259044d2be8b6b10d73c5873e042eaaecf1165425f5871afa2d251ea71e1deb3939528b9366f99e24ce11b0ec744a30e76a6
6
+ metadata.gz: 7b0bcc424857753a344a9b0f80df732a39b970dd798a3ddf99ec9366821923ad1c8121c8aac20649addc0b6777aa90a6100b08e438a05a59d2c3f847e3ea2453
7
+ data.tar.gz: fb6b761b19edcddea9980f3e3e4a6e40ef7532c2e0f43ade1e403ba1e9cae982dce685a774d825cce38d7e752b08249b3730f2b97fd595270cf30bca9a868caa
@@ -0,0 +1,573 @@
1
+ require 'sqlite3'
2
+
3
+ #===============================================================================
4
+ # Audrey::Engine::SQLite3::Init
5
+ #
6
+ module Audrey::Engine::SQLite3::Init
7
+ #---------------------------------------------------------------------------
8
+ # build
9
+ #
10
+ def self.build(p_dbh)
11
+ # create database file
12
+ # @dbh = SQLite3::Database.new(engine.path)
13
+ @dbh = p_dbh
14
+
15
+ # go into transaction
16
+ @dbh.transaction
17
+
18
+ # temp tables
19
+ # Audrey::Engine::SQLite3.session_tables @dbh
20
+
21
+ # create and populate tables
22
+ journal()
23
+ settings()
24
+ partitions()
25
+ objects()
26
+ relationships()
27
+ views()
28
+ sessions()
29
+
30
+ # commit
31
+ @dbh.commit
32
+ end
33
+ #
34
+ # build
35
+ #---------------------------------------------------------------------------
36
+
37
+
38
+ #---------------------------------------------------------------------------
39
+ # journal
40
+ #
41
+ def self.journal
42
+ # $tm.hrm
43
+
44
+ # build
45
+ @dbh.execute_batch <<-SQL
46
+ -- create table
47
+ create table journal (
48
+ pk integer primary key autoincrement,
49
+ ts datetime default current_timestamp,
50
+ tbl varchar(15) not null,
51
+ fpk varchar(36) not null,
52
+ action varchar(1) not null,
53
+ dsc json
54
+ );
55
+
56
+ -- cannot update journal
57
+ create trigger journal_bu
58
+ before update on journal
59
+ begin
60
+ select raise(abort, 'cannot-update-journal-record');
61
+ end;
62
+
63
+ -- cannot delete journal
64
+ create trigger journal_bd
65
+ before delete on journal
66
+ begin
67
+ select raise(abort, 'cannot-delete-journal-record');
68
+ end;
69
+ SQL
70
+ end
71
+ #
72
+ # journal
73
+ #---------------------------------------------------------------------------
74
+
75
+
76
+ #---------------------------------------------------------------------------
77
+ # settings
78
+ #
79
+ def self.settings
80
+ # $tm.hrm
81
+
82
+ # build
83
+ @dbh.execute_batch <<-SQL
84
+ -- create table
85
+ create table settings (
86
+ pk varchar(5) primary key,
87
+ value varchar(64) not null
88
+ );
89
+
90
+ -- cannot update pk
91
+ create trigger settings_bu_pk
92
+ before update of pk on settings
93
+ begin
94
+ select raise(abort, 'cannot-update-setting-pk');
95
+ end;
96
+
97
+ -- add setting for journaling
98
+ insert into settings(pk, value) values('journal', 1);
99
+
100
+ -- create version setting
101
+ insert into settings(pk, value) values('version', '0.1');
102
+
103
+ -- end sql
104
+ SQL
105
+ end
106
+ #
107
+ # settings
108
+ #---------------------------------------------------------------------------
109
+
110
+
111
+ #---------------------------------------------------------------------------
112
+ # partitions
113
+ #
114
+ def self.partitions
115
+ # $tm.hrm
116
+
117
+ # build
118
+ @dbh.execute_batch <<-SQL
119
+ -- create table
120
+ create table partitions (
121
+ pk varchar(1) primary key,
122
+ name varchar(30) unique not null
123
+ );
124
+
125
+ -- cannot update pk
126
+ create trigger partitions_bu_pk
127
+ before update of pk on partitions
128
+ begin
129
+ select raise(abort, 'cannot-update-partition-pk');
130
+ end;
131
+
132
+ -- create partitions
133
+ insert into partitions(pk, name) values('m', 'main');
134
+ insert into partitions(pk, name) values('r', 'roles');
135
+ insert into partitions(pk, name) values('d', 'design');
136
+
137
+ -- cannot insert partitions
138
+ create trigger partitions_bi
139
+ before insert on partitions
140
+ begin
141
+ select raise(abort, 'cannot-insert-new-partition');
142
+ end;
143
+
144
+ -- cannot update
145
+ create trigger partitions_bu
146
+ before update on partitions
147
+ begin
148
+ select raise(abort, 'cannot-update-partition');
149
+ end;
150
+
151
+ -- cannot delete partitions
152
+ create trigger partitions_bd
153
+ before delete on partitions
154
+ begin
155
+ select raise(abort, 'cannot-delete-partition');
156
+ end;
157
+ SQL
158
+ end
159
+ #
160
+ # partitions
161
+ #---------------------------------------------------------------------------
162
+
163
+
164
+ #---------------------------------------------------------------------------
165
+ # objects
166
+ #
167
+ def self.objects
168
+ # build
169
+ @dbh.execute_batch <<-SQL
170
+ -- fclasses table
171
+ create table fclasses(
172
+ pk integer primary key autoincrement,
173
+ name varchar(255) unique not null,
174
+ check (length(name)>0)
175
+ );
176
+
177
+ -- cannot update fclasses
178
+ create trigger fclasses_bu
179
+ before update on fclasses
180
+ begin
181
+ select raise(abort, 'cannot-update-fclasses');
182
+ end;
183
+
184
+ -- base_objects table
185
+ create table base_objects (
186
+ pk varchar(36) primary key,
187
+ partition varchar(1) not null references partitions(pk),
188
+ root boolean,
189
+ bclass_pk integer not null references fclasses(pk) on delete restrict,
190
+ fclass_pk integer not null references fclasses(pk) on delete restrict,
191
+ scalar text,
192
+ xt uuid references base_objects(pk) unique,
193
+ changed datetime default current_timestamp,
194
+ check (root=1)
195
+ );
196
+
197
+ -- indexes
198
+ create unique index base_objects_partition_root on base_objects(partition, root);
199
+ create index base_objects_partition on base_objects(partition);
200
+ create index base_objects_bclass_pk on base_objects(bclass_pk);
201
+ create index base_objects_fclass_pk on base_objects(fclass_pk);
202
+ create index base_objects_scalar on base_objects(scalar);
203
+ create index base_objects_changed on base_objects(changed);
204
+
205
+ -- cannot update most fields
206
+ create trigger base_objects_bu_pk before update of pk on base_objects begin select raise(abort, 'cannot-update-object-pk'); end;
207
+ create trigger base_objects_bu_partition before update of partition on base_objects begin select raise(abort, 'cannot-update-object-partition'); end;
208
+ create trigger base_objects_bu_root before update of root on base_objects begin select raise(abort, 'cannot-update-object-root'); end;
209
+ create trigger base_objects_bu_bclass_pk before update of bclass_pk on base_objects begin select raise(abort, 'cannot-update-object-bclass_pk'); end;
210
+ create trigger base_objects_bu_fclass_pk before update of fclass_pk on base_objects begin select raise(abort, 'cannot-update-object-fclass_pk'); end;
211
+ create trigger base_objects_bu_scalar before update of scalar on base_objects begin select raise(abort, 'cannot-update-object-scalar'); end;
212
+
213
+ -- cannot update xt once it has been defined
214
+ create trigger base_objects_bu_xt
215
+ before update of xt on base_objects when (old.xt is not null)
216
+ begin
217
+ select raise(abort, 'cannot-update-object-xt-once-set');
218
+ end;
219
+
220
+ -- cannot delete root object
221
+ create trigger base_objects_bd_root
222
+ before delete on base_objects when (old.root)
223
+ begin
224
+ select raise(abort, 'cannot-delete-root-object');
225
+ end;
226
+
227
+ -- insert: journal
228
+ create trigger base_objects_ai_journal
229
+ after insert on base_objects when (select value from settings where pk='journal')
230
+ begin
231
+ insert into journal(tbl, fpk, action, dsc) values(
232
+ 'o',
233
+ new.pk,
234
+ 'i',
235
+ insert_object_journal(
236
+ new.partition,
237
+ new.root,
238
+ (select name from fclasses where pk=new.fclass_pk),
239
+ new.scalar,
240
+ new.xt
241
+ )
242
+ );
243
+ end;
244
+
245
+ -- update: journal
246
+ create trigger base_objects_au_journal
247
+ after update on base_objects when (select value from settings where pk='journal')
248
+ begin
249
+ insert into journal(tbl, fpk, action, dsc) values('o', new.pk, 'u',
250
+ '{' ||
251
+ '"x":"' || replace(new.xt, '"', '\"') || '"' ||
252
+ '}');
253
+ end;
254
+
255
+ -- after delete on object with xt
256
+ create trigger base_objects_ad
257
+ after delete on base_objects
258
+ begin
259
+ delete from base_objects where pk=old.xt;
260
+ end;
261
+
262
+ -- delete: journal
263
+ create trigger base_objects_ad_journal
264
+ after delete on base_objects when (select value from settings where pk='journal')
265
+ begin
266
+ insert into journal(tbl, fpk, action) values('o', old.pk, 'd');
267
+ end;
268
+
269
+ -- initial fclass
270
+ insert into fclasses(name) values('Audrey::Object::Hash');
271
+ insert into fclasses(name) values('Audrey::Object::Root');
272
+
273
+ -- add root objects
274
+ insert into base_objects(pk, partition, bclass_pk, fclass_pk, root, changed) values('1', 'm', 1, 2, 1, null);
275
+ insert into base_objects(pk, partition, bclass_pk, fclass_pk, root, changed) values('2', 'r', 1, 2, 1, null);
276
+ insert into base_objects(pk, partition, bclass_pk, fclass_pk, root, changed) values('3', 'd', 1, 2, 1, null);
277
+
278
+ -- objects view
279
+ create view objects as
280
+ select
281
+ o.pk, o.partition, o.root, o.scalar, o.xt, o.changed,
282
+ (select name from fclasses where pk=o.bclass_pk) as bclass,
283
+ (select name from fclasses where pk=o.fclass_pk) as fclass
284
+ from base_objects o
285
+ where o.partition = current_partition();
286
+
287
+ -- insert into objects
288
+ create trigger objects_insert
289
+ instead of insert on objects
290
+ begin
291
+ -- notify database of change
292
+ -- select change_to_true(new.fclass);
293
+
294
+ -- ensure bclass record
295
+ insert or ignore into
296
+ fclasses(name)
297
+ values(new.bclass);
298
+
299
+ -- ensure fclass record
300
+ insert or ignore into
301
+ fclasses(name)
302
+ values(new.fclass);
303
+
304
+ -- insert
305
+ insert into
306
+ base_objects(
307
+ pk,
308
+ partition,
309
+ root,
310
+ bclass_pk,
311
+ fclass_pk,
312
+ scalar,
313
+ xt
314
+ )
315
+
316
+ values(
317
+ new.pk,
318
+ current_partition(),
319
+ new.root,
320
+ (select pk from fclasses where name=new.bclass),
321
+ (select pk from fclasses where name=new.fclass),
322
+ new.scalar,
323
+ new.xt
324
+ );
325
+ end;
326
+
327
+ /*
328
+ -- update objects
329
+ create trigger objects_update
330
+ instead of update of changed on objects
331
+ begin
332
+ update base_objects
333
+ set changed = new.changed
334
+ where pk = new.pk;
335
+ end;
336
+ */
337
+
338
+ -- delete from objects
339
+ create trigger objects_delete
340
+ instead of delete on objects
341
+ begin
342
+ delete from base_objects where pk=old.pk and partition = current_partition();
343
+ end;
344
+
345
+ -- end of sql
346
+ SQL
347
+ end
348
+ #
349
+ # objects
350
+ #---------------------------------------------------------------------------
351
+
352
+
353
+ #---------------------------------------------------------------------------
354
+ # relationships
355
+ # TODO: Need to rework relationships table so that ord can be changed.
356
+ #
357
+ def self.relationships()
358
+ # $tm.hrm
359
+
360
+ # build
361
+ @dbh.execute_batch <<-SQL
362
+ -- create table
363
+ create table relationships (
364
+ pk varchar(36) primary key,
365
+ parent varchar(36) not null references base_objects(pk) on delete cascade,
366
+ child varchar(36) not null references base_objects(pk) on delete cascade,
367
+ ord integer not null,
368
+ hkey varchar(255),
369
+ check(typeof(ord)='integer')
370
+ );
371
+
372
+ -- indexes
373
+ create unique index relationships_parent_hkey on relationships(parent, hkey);
374
+ create index relationships_parent on relationships(parent);
375
+
376
+ -- must be in same partition
377
+ create trigger relationships_bi_partitions
378
+ before insert on relationships
379
+ begin
380
+ select case
381
+ when (select partition from base_objects where pk=new.parent) <> (select partition from base_objects where pk=new.child) then
382
+ raise(abort, 'relationship-objects-not-in-same-partition')
383
+ end;
384
+ end;
385
+
386
+ -- parent must be array or hash
387
+ create trigger relationships_bi_bclass
388
+ before insert on relationships
389
+ begin
390
+ select case
391
+ when (select bclass from objects where pk=new.parent) not in ('Audrey::Object::Array', 'Audrey::Object::Hash') then
392
+ raise(abort, 'relationship-parent-base-class-does-not-support-relatonships')
393
+ end;
394
+ end;
395
+
396
+ -- cannot update
397
+ create trigger relationships_bu
398
+ before update on relationships
399
+ begin
400
+ select raise(abort, 'cannot-update-relationships');
401
+ end;
402
+
403
+ -- insert: journal
404
+ create trigger relationships_ai_journal
405
+ after insert on relationships when (select value from settings where pk='journal')
406
+ begin
407
+ insert into journal(tbl, fpk, action, dsc) values('r', new.pk, 'i',
408
+ '{' ||
409
+ '"p":"' || replace(new.parent, '"', '\"') || '",' ||
410
+ '"c":"' || replace(new.child, '"', '\"') || '",' ||
411
+ '"ord":' || new.ord || ',' ||
412
+ '"hk":"' || replace(new.hkey, '"', '\"') || '"' ||
413
+ '}');
414
+ end;
415
+
416
+ -- insert: changed
417
+ create trigger relationships_ai_changed
418
+ after insert on relationships
419
+ begin
420
+ update base_objects set changed=current_timestamp where pk=new.parent;
421
+ end;
422
+
423
+ -- journal: update
424
+ create trigger relationships_au_journal
425
+ after update on relationships when (select value from settings where pk='journal')
426
+ begin
427
+ insert into journal(tbl, fpk, action, dsc) values('r', new.pk, 'u',
428
+ '{' ||
429
+ '"c":"' || replace(new.child, '"', '\"') || '",' ||
430
+ '"ord":' || new.ord || ',' ||
431
+ '"hk":"' || replace(new.hkey, '"', '\"') || '"' ||
432
+ '}');
433
+ end;
434
+
435
+ -- delete: journal
436
+ create trigger relationships_ad_journal
437
+ after delete on relationships when (select value from settings where pk='journal')
438
+ begin
439
+ insert into journal(tbl, fpk, action) values('r', old.pk, 'd');
440
+ end;
441
+
442
+ -- delete: changed
443
+ create trigger relationships_ad_changed
444
+ after delete on relationships
445
+ begin
446
+ update base_objects set changed=current_timestamp where pk=old.parent;
447
+ end;
448
+
449
+ -- delete parent if child is graph
450
+ -- KLUDGE: Cannot figure out why, but if this routine attempts to delete
451
+ -- from objects view, the delete never happens. So deleting directly
452
+ -- from base_objects.
453
+ create trigger relationships_ad_graph
454
+ after delete on relationships when (select graph_field((select fclass from objects where pk=old.parent), old.hkey))
455
+ begin
456
+ delete from base_objects where pk=old.parent;
457
+ end;
458
+
459
+ -- end of sql
460
+ SQL
461
+ end
462
+ #
463
+ # relationships
464
+ #---------------------------------------------------------------------------
465
+
466
+
467
+ #---------------------------------------------------------------------------
468
+ # views
469
+ #
470
+ def self.views
471
+ # $tm.hrm
472
+
473
+ # build
474
+ @dbh.execute_batch <<-SQL
475
+ -- hash_pairs
476
+ create view hash_pairs as
477
+ select c.partition, r.parent, r.child, r.hkey, c.scalar, r.ord
478
+ from objects c, relationships r
479
+ where (c.pk = r.child) and (r.hkey is not null)
480
+ order by ord;
481
+
482
+ -- fcos
483
+ create view fcos as
484
+ select pk
485
+ from objects
486
+ where fclass_fco(fclass);
487
+
488
+ -- fco_descendants
489
+ create view fco_descendants as
490
+ with recursive ancestor(child) as (
491
+ select child from relationships where parent in (select pk from fcos)
492
+ union
493
+ select r.child from ancestor a inner join relationships r on r.parent = a.child
494
+ )
495
+ select child from ancestor;
496
+
497
+ -- fco_traced
498
+ create view fco_traced as
499
+ select distinct pk
500
+ from objects
501
+ where fclass_fco(fclass) or (pk in (select child from fco_descendants));
502
+
503
+ -- fco_not_traced
504
+ create view fco_not_traced as
505
+ select pk from objects
506
+ where pk not in (select pk from fco_traced);
507
+
508
+ -- end of SQL
509
+ SQL
510
+ end
511
+ #
512
+ # views
513
+ #---------------------------------------------------------------------------
514
+
515
+
516
+ #---------------------------------------------------------------------------
517
+ # sessions
518
+ #
519
+ def self.sessions
520
+ # $tm.hrm
521
+
522
+ # build
523
+ @dbh.execute_batch <<-SQL
524
+ -- sessions
525
+ create table sessions (
526
+ pk varchar(36) primary key,
527
+ pw varchar(36)
528
+ );
529
+
530
+ -- cannot update sessions
531
+ create trigger sessions_bu
532
+ before update on sessions
533
+ begin
534
+ select raise(abort, 'cannot-update-sessions');
535
+ end;
536
+
537
+ -- results
538
+ create table results (
539
+ pk varchar(36) primary key,
540
+ session varchar(36) not null references sessions(pk) on delete cascade
541
+ );
542
+
543
+ -- cannot update results
544
+ create trigger results_bu
545
+ before update on results
546
+ begin
547
+ select raise(abort, 'cannot-update-results');
548
+ end;
549
+
550
+ -- result_rows
551
+ create table result_rows (
552
+ pk varchar(36) primary key,
553
+ result varchar(36) not null references results(pk) on delete cascade,
554
+ object varchar(36) not null references base_objects(pk) on delete cascade
555
+ );
556
+
557
+ -- cannot update result_rows
558
+ create trigger result_rows_bu
559
+ before update on result_rows
560
+ begin
561
+ select raise(abort, 'cannot-update-result_rows');
562
+ end;
563
+
564
+ -- end of SQL
565
+ SQL
566
+ end
567
+ #
568
+ # sessions
569
+ #---------------------------------------------------------------------------
570
+ end
571
+ #
572
+ # Audrey::Engine::SQLite3::Init
573
+ #===============================================================================