audrey 0.2 → 0.3

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
  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
+ #===============================================================================