audrey 0.3.1 → 0.3.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 +4 -4
- data/README.md +15 -11
- data/lib/audrey.rb +76 -78
- data/lib/audrey/engine/sqlite3.rb +32 -331
- data/lib/audrey/engine/sqlite3/init.rb +35 -41
- data/lib/audrey/engine/sqlite3/query/q0.rb +11 -11
- data/lib/audrey/query/q0.rb +16 -16
- metadata +3 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6b23e9b52a9288068ee7759f7801d2b7bf823039e175d605021a7e7f1ea3bf9a
|
|
4
|
+
data.tar.gz: c852e65ef1cc590c17604c7dafe448d884cc9d326e557dcfa9f8e748137cf050
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b004dd3df3ac223f34ba0f08b957e8b9b2e3054d6151b3831cc5b44c9d8e6ef6770421afae09036692fed8678dcfeaf40d54a2703e5536c917d15aec314a632e
|
|
7
|
+
data.tar.gz: b1f2fcb49a1bbdebc4c8990d20956c92a621c7f72825d07ed30c22d4fd4b74dbd3db6b0615efa97ae17f3ae5d9606a1a15e83b2023413587488376bf1fbe09cb
|
data/README.md
CHANGED
|
@@ -16,7 +16,7 @@ gem install audrey
|
|
|
16
16
|
|
|
17
17
|
By default, Audrey uses SQLite for storage, so the only dependencies are SQLite,
|
|
18
18
|
which is standard on most Unixish systems, and this gem. To create and start
|
|
19
|
-
using
|
|
19
|
+
using an Audrey database, all you have to do is open it with `Audrey.connect`,
|
|
20
20
|
giving a path to a database file and a read/write mode - `'rw'`, `'r'`, or
|
|
21
21
|
`'w'`. The file doesn't need to already exist; it will be created automatically
|
|
22
22
|
as needed.
|
|
@@ -471,7 +471,7 @@ on objects, searching for by class and by field value.
|
|
|
471
471
|
|
|
472
472
|
### Q0 will not be the only query language
|
|
473
473
|
|
|
474
|
-
Before we go further,
|
|
474
|
+
Before we go further, it's important to understand what Q0 is *not*: it
|
|
475
475
|
is not the only query language that Audrey will ever have. One of the problems
|
|
476
476
|
that database systems often have is that their query languages becomes more and
|
|
477
477
|
more convoluted as needs evolve. SQL is a good example. What started as a simple
|
|
@@ -493,7 +493,7 @@ Then we `each` through the results:
|
|
|
493
493
|
```text
|
|
494
494
|
Audrey.connect(path, 'rw') do |db|
|
|
495
495
|
query = db.q0
|
|
496
|
-
query.
|
|
496
|
+
query.aclass = Person
|
|
497
497
|
|
|
498
498
|
query.each do |person|
|
|
499
499
|
puts person.surname
|
|
@@ -504,7 +504,7 @@ end
|
|
|
504
504
|
Note that to search by class we use `fclass` (for *Audrey class*), not just
|
|
505
505
|
`class`. There are several reasons for this. First, the `class` property is
|
|
506
506
|
already taken. Second, as Audrey grows and is implemented by languages besides
|
|
507
|
-
Ruby, it will be necessary to distinguish because a Ruby class and
|
|
507
|
+
Ruby, it will be necessary to distinguish because a Ruby class and an Audrey
|
|
508
508
|
class. Audrey classes have the same names as Ruby classes, but other languages,
|
|
509
509
|
such as Python, use a different naming scheme for classes.
|
|
510
510
|
|
|
@@ -527,7 +527,7 @@ query to look for records in which the object's `first` field is "Mary".
|
|
|
527
527
|
```text
|
|
528
528
|
Audrey.connect(path, 'rw') do |db|
|
|
529
529
|
query = db.q0
|
|
530
|
-
query.
|
|
530
|
+
query.aclass = Person
|
|
531
531
|
query.fields['first'] = 'Mary'
|
|
532
532
|
|
|
533
533
|
query.each do |person|
|
|
@@ -588,9 +588,12 @@ in execution, but it allows you go from no project to working project faster
|
|
|
588
588
|
than most database systems. Consider the tradeoff.
|
|
589
589
|
|
|
590
590
|
|
|
591
|
-
## The name
|
|
591
|
+
## The name
|
|
592
592
|
|
|
593
|
-
Audrey is named after the character
|
|
593
|
+
Audrey is named after the character
|
|
594
|
+
[Audrey](https://commons.wikimedia.org/wiki/File:Audrey_-_Philip_Richard_Morris.jpg)
|
|
595
|
+
in Shakespeare's
|
|
596
|
+
[As You Like It](https://en.wikipedia.org/wiki/As_You_Like_It).
|
|
594
597
|
|
|
595
598
|
|
|
596
599
|
## Author
|
|
@@ -600,7 +603,8 @@ mike@idocs.com
|
|
|
600
603
|
|
|
601
604
|
## History
|
|
602
605
|
|
|
603
|
-
| version | date | notes
|
|
604
|
-
|
|
605
|
-
| 0.3 | Feb 12, 2020 | Initial upload.
|
|
606
|
-
| 0.3.1 | Feb 12, 2020 | Minor fixes to documentation
|
|
606
|
+
| version | date | notes |
|
|
607
|
+
|---------|--------------|---------------------------------------------------|
|
|
608
|
+
| 0.3 | Feb 12, 2020 | Initial upload. |
|
|
609
|
+
| 0.3.1 | Feb 12, 2020 | Minor fixes to documentation. |
|
|
610
|
+
| 0.3.2 | Feb 14, 2020 | Minor fixes to documentation. Minor code cleanup. |
|
data/lib/audrey.rb
CHANGED
|
@@ -15,7 +15,7 @@ class Audrey
|
|
|
15
15
|
@@current_db = nil
|
|
16
16
|
|
|
17
17
|
# version
|
|
18
|
-
VERSION = '0.3.
|
|
18
|
+
VERSION = '0.3.2'
|
|
19
19
|
|
|
20
20
|
#---------------------------------------------------------------------------
|
|
21
21
|
# delegate
|
|
@@ -336,27 +336,27 @@ class Audrey
|
|
|
336
336
|
# $tm.hrm
|
|
337
337
|
|
|
338
338
|
# scalar
|
|
339
|
-
if dfn = Audrey::AUDREY_SCALAR_TO_RUBY[row['
|
|
339
|
+
if dfn = Audrey::AUDREY_SCALAR_TO_RUBY[row['aclass']]
|
|
340
340
|
return dfn.call(row['scalar'])
|
|
341
341
|
end
|
|
342
342
|
|
|
343
343
|
# collection
|
|
344
|
-
if dfn = Audrey::AUDREY_COLLECTION_TO_RUBY[row['
|
|
344
|
+
if dfn = Audrey::AUDREY_COLLECTION_TO_RUBY[row['aclass']]
|
|
345
345
|
return dfn['nclass'].create_object(self, 'row'=>row)
|
|
346
346
|
end
|
|
347
347
|
|
|
348
348
|
# custom class
|
|
349
|
-
if Module.const_defined?(row['
|
|
350
|
-
clss = Module.const_get(row['
|
|
351
|
-
nclass = Audrey::AUDREY_COLLECTION_TO_RUBY[clss.
|
|
349
|
+
if Module.const_defined?(row['aclass'])
|
|
350
|
+
clss = Module.const_get(row['aclass'])
|
|
351
|
+
nclass = Audrey::AUDREY_COLLECTION_TO_RUBY[clss.hsa]['nclass']
|
|
352
352
|
node = nclass.new(self, 'row'=>row)
|
|
353
353
|
rv = clss.new('db'=>self, 'node'=>node)
|
|
354
354
|
return rv
|
|
355
355
|
end
|
|
356
356
|
|
|
357
|
-
# if we get this far then we don't know how to turn the row into
|
|
357
|
+
# if we get this far then we don't know how to turn the row into an
|
|
358
358
|
# Audrey object
|
|
359
|
-
raise 'unknown-
|
|
359
|
+
raise 'unknown-aclass: ' + row['aclass'].to_s
|
|
360
360
|
end
|
|
361
361
|
#
|
|
362
362
|
# object_from_row
|
|
@@ -408,9 +408,9 @@ class Audrey
|
|
|
408
408
|
#---------------------------------------------------------------------------
|
|
409
409
|
# import_csv
|
|
410
410
|
#
|
|
411
|
-
def import_csv(
|
|
411
|
+
def import_csv(aclass, path, opts={})
|
|
412
412
|
# $tm.hrm
|
|
413
|
-
return @engine.import_csv(
|
|
413
|
+
return @engine.import_csv(aclass, path, opts)
|
|
414
414
|
end
|
|
415
415
|
#
|
|
416
416
|
# import_csv
|
|
@@ -420,9 +420,9 @@ class Audrey
|
|
|
420
420
|
#---------------------------------------------------------------------------
|
|
421
421
|
# checks_outside_transaction
|
|
422
422
|
#
|
|
423
|
-
def checks_outside_transaction(
|
|
424
|
-
if
|
|
425
|
-
if (not in_transaction?) and
|
|
423
|
+
def checks_outside_transaction(aclass)
|
|
424
|
+
if aclass.respond_to?('has_checks?')
|
|
425
|
+
if (not in_transaction?) and aclass.has_checks?
|
|
426
426
|
raise 'cannot-create-or-modify-object-that-has-checks-when-not-in-a-transaction'
|
|
427
427
|
end
|
|
428
428
|
end
|
|
@@ -444,9 +444,6 @@ class Audrey
|
|
|
444
444
|
# yield
|
|
445
445
|
yield tr
|
|
446
446
|
|
|
447
|
-
# run checks
|
|
448
|
-
# xeme = run_checks()
|
|
449
|
-
|
|
450
447
|
# autocommit
|
|
451
448
|
if opts['autocommit']
|
|
452
449
|
tr.commit
|
|
@@ -496,10 +493,10 @@ class Audrey
|
|
|
496
493
|
end
|
|
497
494
|
|
|
498
495
|
# wrong class
|
|
499
|
-
elsif dfn.
|
|
500
|
-
xeme.error('wrong-
|
|
496
|
+
elsif dfn.aclass and (not val.is_a?(dfn.aclass))
|
|
497
|
+
xeme.error('wrong-aclass') do |msg|
|
|
501
498
|
msg['field'] = fieldname
|
|
502
|
-
msg['
|
|
499
|
+
msg['aclass'] = dfn.aclass.to_s
|
|
503
500
|
end
|
|
504
501
|
|
|
505
502
|
# run checks
|
|
@@ -697,7 +694,7 @@ class Audrey::Node
|
|
|
697
694
|
@engine = @db.engine
|
|
698
695
|
|
|
699
696
|
# hold on to flcass if one was sent
|
|
700
|
-
@
|
|
697
|
+
@aclass = opts['aclass']
|
|
701
698
|
|
|
702
699
|
# if a row was sent, cache it and set pk
|
|
703
700
|
if opts['row']
|
|
@@ -736,12 +733,12 @@ class Audrey::Node
|
|
|
736
733
|
#
|
|
737
734
|
def fco
|
|
738
735
|
# $tm.hrm
|
|
739
|
-
return Audrey::Util.
|
|
736
|
+
return Audrey::Util.aclass_fco(row['aclass'])
|
|
740
737
|
end
|
|
741
738
|
|
|
742
739
|
def isolate
|
|
743
740
|
# $tm.hrm
|
|
744
|
-
return Audrey::Util.
|
|
741
|
+
return Audrey::Util.aclass_isolate(row['aclass'])
|
|
745
742
|
end
|
|
746
743
|
#
|
|
747
744
|
# fco, isolate
|
|
@@ -943,7 +940,7 @@ class Audrey::Node::Hash < Audrey::Node::Collection
|
|
|
943
940
|
write_check()
|
|
944
941
|
|
|
945
942
|
# test for checks outside of a transaction
|
|
946
|
-
@db.checks_outside_transaction @
|
|
943
|
+
@db.checks_outside_transaction @aclass
|
|
947
944
|
|
|
948
945
|
@engine.hash_element_delete @pk, key
|
|
949
946
|
save_child child, 'key'=>key.to_s
|
|
@@ -1425,56 +1422,56 @@ module Audrey::Util
|
|
|
1425
1422
|
|
|
1426
1423
|
|
|
1427
1424
|
#---------------------------------------------------------------------------
|
|
1428
|
-
#
|
|
1425
|
+
# rclass_from_aclass
|
|
1429
1426
|
#
|
|
1430
|
-
|
|
1427
|
+
RCLASS_FROM_ACLASS_CACHE = {}
|
|
1431
1428
|
|
|
1432
|
-
def self.
|
|
1433
|
-
if early =
|
|
1429
|
+
def self.rclass_from_aclass(aclass)
|
|
1430
|
+
if early = RCLASS_FROM_ACLASS_CACHE[aclass]
|
|
1434
1431
|
return early
|
|
1435
1432
|
end
|
|
1436
1433
|
|
|
1437
|
-
if Module.const_defined?(
|
|
1438
|
-
rclass = Module.const_get(
|
|
1434
|
+
if Module.const_defined?(aclass)
|
|
1435
|
+
rclass = Module.const_get(aclass)
|
|
1439
1436
|
|
|
1440
1437
|
if rclass < Audrey::Object
|
|
1441
|
-
|
|
1438
|
+
RCLASS_FROM_ACLASS_CACHE[aclass] = rclass
|
|
1442
1439
|
return rclass
|
|
1443
1440
|
else
|
|
1444
|
-
raise 'not-custom-class: ' +
|
|
1441
|
+
raise 'not-custom-class: ' + aclass.to_s
|
|
1445
1442
|
end
|
|
1446
1443
|
else
|
|
1447
|
-
raise 'unknown-
|
|
1444
|
+
raise 'unknown-aclass: ' + aclass.to_s
|
|
1448
1445
|
end
|
|
1449
1446
|
end
|
|
1450
1447
|
#
|
|
1451
|
-
#
|
|
1448
|
+
# rclass_from_aclass
|
|
1452
1449
|
#---------------------------------------------------------------------------
|
|
1453
1450
|
|
|
1454
1451
|
|
|
1455
1452
|
#---------------------------------------------------------------------------
|
|
1456
|
-
#
|
|
1453
|
+
# aclass_fco, aclass_isolate
|
|
1457
1454
|
#
|
|
1458
|
-
def self.
|
|
1459
|
-
return self.
|
|
1455
|
+
def self.aclass_fco(aclass)
|
|
1456
|
+
return self.rclass_from_aclass(aclass).fco
|
|
1460
1457
|
end
|
|
1461
1458
|
|
|
1462
|
-
def self.
|
|
1463
|
-
return self.
|
|
1459
|
+
def self.aclass_isolate(aclass)
|
|
1460
|
+
return self.rclass_from_aclass(aclass).isolate
|
|
1464
1461
|
end
|
|
1465
1462
|
#
|
|
1466
|
-
#
|
|
1463
|
+
# aclass_fco, aclass_isolate
|
|
1467
1464
|
#---------------------------------------------------------------------------
|
|
1468
1465
|
|
|
1469
1466
|
|
|
1470
1467
|
#---------------------------------------------------------------------------
|
|
1471
1468
|
# graph_field?
|
|
1472
1469
|
#
|
|
1473
|
-
def self.graph_field?(
|
|
1470
|
+
def self.graph_field?(aclass, hkey)
|
|
1474
1471
|
# $tm.hrm
|
|
1475
1472
|
|
|
1476
|
-
if
|
|
1477
|
-
clss = Module.const_get(
|
|
1473
|
+
if aclass and Module.const_defined?(aclass)
|
|
1474
|
+
clss = Module.const_get(aclass)
|
|
1478
1475
|
|
|
1479
1476
|
if clss.respond_to?('fields')
|
|
1480
1477
|
if dfn = clss.fields[hkey]
|
|
@@ -1496,17 +1493,17 @@ module Audrey::Util
|
|
|
1496
1493
|
#
|
|
1497
1494
|
@@CUSTOM_CLASSES = {}
|
|
1498
1495
|
|
|
1499
|
-
def self.custom_class?(
|
|
1496
|
+
def self.custom_class?(aclass)
|
|
1500
1497
|
# $tm.hrm
|
|
1501
1498
|
|
|
1502
1499
|
# cache
|
|
1503
|
-
if not @@CUSTOM_CLASSES.has_key?(
|
|
1504
|
-
# puts
|
|
1505
|
-
@@CUSTOM_CLASSES[
|
|
1500
|
+
if not @@CUSTOM_CLASSES.has_key?(aclass)
|
|
1501
|
+
# puts aclass
|
|
1502
|
+
@@CUSTOM_CLASSES[aclass] = rclass_from_aclass(aclass) < Audrey::Object::Custom
|
|
1506
1503
|
end
|
|
1507
1504
|
|
|
1508
1505
|
# return
|
|
1509
|
-
return @@CUSTOM_CLASSES[
|
|
1506
|
+
return @@CUSTOM_CLASSES[aclass]
|
|
1510
1507
|
end
|
|
1511
1508
|
#
|
|
1512
1509
|
# custom_class?
|
|
@@ -1522,7 +1519,7 @@ end
|
|
|
1522
1519
|
#
|
|
1523
1520
|
class Audrey::Object
|
|
1524
1521
|
#---------------------------------------------------------------------------
|
|
1525
|
-
# inherited, descendants,
|
|
1522
|
+
# inherited, descendants, aclasses
|
|
1526
1523
|
#
|
|
1527
1524
|
def self.inherited(desc)
|
|
1528
1525
|
if not instance_variable_defined?(:@children)
|
|
@@ -1545,7 +1542,7 @@ class Audrey::Object
|
|
|
1545
1542
|
return rv
|
|
1546
1543
|
end
|
|
1547
1544
|
|
|
1548
|
-
def self.
|
|
1545
|
+
def self.aclasses
|
|
1549
1546
|
rv = [self.to_s]
|
|
1550
1547
|
|
|
1551
1548
|
descendants.each do |desc|
|
|
@@ -1555,7 +1552,7 @@ class Audrey::Object
|
|
|
1555
1552
|
return rv
|
|
1556
1553
|
end
|
|
1557
1554
|
#
|
|
1558
|
-
# inherited, descendants,
|
|
1555
|
+
# inherited, descendants, aclasses
|
|
1559
1556
|
#---------------------------------------------------------------------------
|
|
1560
1557
|
|
|
1561
1558
|
|
|
@@ -1616,8 +1613,8 @@ end
|
|
|
1616
1613
|
# scalar types
|
|
1617
1614
|
#
|
|
1618
1615
|
class Audrey::Object::Scalar < Audrey::Object
|
|
1619
|
-
def self.
|
|
1620
|
-
return
|
|
1616
|
+
def self.hsa
|
|
1617
|
+
return 's'
|
|
1621
1618
|
end
|
|
1622
1619
|
end
|
|
1623
1620
|
|
|
@@ -1654,8 +1651,8 @@ end
|
|
|
1654
1651
|
# Audrey::Object::Array
|
|
1655
1652
|
#
|
|
1656
1653
|
class Audrey::Object::Array < Audrey::Object::Collection
|
|
1657
|
-
def self.
|
|
1658
|
-
return
|
|
1654
|
+
def self.hsa
|
|
1655
|
+
return 'a'
|
|
1659
1656
|
end
|
|
1660
1657
|
|
|
1661
1658
|
def self.node_class
|
|
@@ -1671,8 +1668,8 @@ end
|
|
|
1671
1668
|
# Audrey::Object::Hash
|
|
1672
1669
|
#
|
|
1673
1670
|
class Audrey::Object::Hash < Audrey::Object::Collection
|
|
1674
|
-
def self.
|
|
1675
|
-
return
|
|
1671
|
+
def self.hsa
|
|
1672
|
+
return 'h'
|
|
1676
1673
|
end
|
|
1677
1674
|
|
|
1678
1675
|
def self.node_class
|
|
@@ -1688,10 +1685,6 @@ end
|
|
|
1688
1685
|
# Audrey::Object::Root
|
|
1689
1686
|
#
|
|
1690
1687
|
class Audrey::Object::Root < Audrey::Object::Hash
|
|
1691
|
-
def self.bclass
|
|
1692
|
-
return Audrey::Object::Hash
|
|
1693
|
-
end
|
|
1694
|
-
|
|
1695
1688
|
def self.node_class
|
|
1696
1689
|
return Audrey::Node::Hash
|
|
1697
1690
|
end
|
|
@@ -1772,7 +1765,7 @@ module Audrey::Object::Searchable
|
|
|
1772
1765
|
def prepare_query(opts)
|
|
1773
1766
|
db = Audrey.explicit_or_current_db(opts['accessor'])
|
|
1774
1767
|
query = db.q0
|
|
1775
|
-
query.
|
|
1768
|
+
query.aclass = self
|
|
1776
1769
|
return query
|
|
1777
1770
|
end
|
|
1778
1771
|
#
|
|
@@ -1946,7 +1939,7 @@ class Audrey::Object::Custom < Audrey::Object::Hash
|
|
|
1946
1939
|
#
|
|
1947
1940
|
def within_initialize(db, opts)
|
|
1948
1941
|
uuid = db.insert_object(self)
|
|
1949
|
-
@node = Audrey::Node::Hash.new(db, '
|
|
1942
|
+
@node = Audrey::Node::Hash.new(db, 'aclass'=>self.class, 'pk'=>uuid)
|
|
1950
1943
|
self.class.new_auto_fields self
|
|
1951
1944
|
end
|
|
1952
1945
|
#
|
|
@@ -1993,7 +1986,7 @@ class Audrey::Object::Custom < Audrey::Object::Hash
|
|
|
1993
1986
|
if idf = self.id_field
|
|
1994
1987
|
db = Audrey.explicit_or_current_db(nil)
|
|
1995
1988
|
q0 = db.q0
|
|
1996
|
-
q0.
|
|
1989
|
+
q0.aclass = self
|
|
1997
1990
|
q0.fields[idf] = key
|
|
1998
1991
|
return q0.first
|
|
1999
1992
|
|
|
@@ -2014,13 +2007,13 @@ class Audrey::Object::Custom < Audrey::Object::Hash
|
|
|
2014
2007
|
use_dfn = Audrey::Object::Custom::Field
|
|
2015
2008
|
|
|
2016
2009
|
# get custom field definition class
|
|
2017
|
-
if
|
|
2018
|
-
if Audrey::RUBY_OBJECT_TO_AUDREY[
|
|
2019
|
-
|
|
2010
|
+
if aclass = opts['aclass']
|
|
2011
|
+
if Audrey::RUBY_OBJECT_TO_AUDREY[aclass]
|
|
2012
|
+
aclass = Audrey::RUBY_OBJECT_TO_AUDREY[aclass]['aclass']
|
|
2020
2013
|
end
|
|
2021
2014
|
|
|
2022
|
-
if
|
|
2023
|
-
use_dfn =
|
|
2015
|
+
if aclass.respond_to?('field_definition')
|
|
2016
|
+
use_dfn = aclass.field_definition
|
|
2024
2017
|
end
|
|
2025
2018
|
end
|
|
2026
2019
|
|
|
@@ -2337,14 +2330,14 @@ class Audrey::Object::Scalar::String::Field < Audrey::Object::Custom::Field
|
|
|
2337
2330
|
attr_accessor :min_length
|
|
2338
2331
|
attr_accessor :max_length
|
|
2339
2332
|
attr_accessor :hascontent
|
|
2340
|
-
attr_reader :
|
|
2333
|
+
attr_reader :aclass
|
|
2341
2334
|
|
|
2342
2335
|
#---------------------------------------------------------------------------
|
|
2343
2336
|
# initialize
|
|
2344
2337
|
#
|
|
2345
2338
|
def initialize(*opts)
|
|
2346
2339
|
super(*opts)
|
|
2347
|
-
@
|
|
2340
|
+
@aclass = String
|
|
2348
2341
|
|
|
2349
2342
|
# normalize
|
|
2350
2343
|
@collapse = false
|
|
@@ -2449,7 +2442,7 @@ end
|
|
|
2449
2442
|
|
|
2450
2443
|
|
|
2451
2444
|
#===============================================================================
|
|
2452
|
-
# build
|
|
2445
|
+
# build aclasses for collections
|
|
2453
2446
|
# This code needs to go at the bottom of this file because the classes being
|
|
2454
2447
|
# referenced aren't defined until after the COLLECTIONS hash is used.
|
|
2455
2448
|
#
|
|
@@ -2458,15 +2451,15 @@ class Audrey
|
|
|
2458
2451
|
# RUBY_OBJECT_TO_AUDREY
|
|
2459
2452
|
#
|
|
2460
2453
|
RUBY_OBJECT_TO_AUDREY = {}
|
|
2461
|
-
RUBY_OBJECT_TO_AUDREY[String] = { '
|
|
2462
|
-
RUBY_OBJECT_TO_AUDREY[Integer] = { '
|
|
2454
|
+
RUBY_OBJECT_TO_AUDREY[String] = { 'aclass'=>Audrey::Object::Scalar::String}
|
|
2455
|
+
RUBY_OBJECT_TO_AUDREY[Integer] = { 'aclass'=>Audrey::Object::Scalar::Number}
|
|
2463
2456
|
RUBY_OBJECT_TO_AUDREY[Float] = RUBY_OBJECT_TO_AUDREY[Integer]
|
|
2464
|
-
RUBY_OBJECT_TO_AUDREY[TrueClass] = { '
|
|
2457
|
+
RUBY_OBJECT_TO_AUDREY[TrueClass] = { 'aclass'=>Audrey::Object::Scalar::Number}
|
|
2465
2458
|
RUBY_OBJECT_TO_AUDREY[FalseClass] = RUBY_OBJECT_TO_AUDREY[TrueClass]
|
|
2466
|
-
RUBY_OBJECT_TO_AUDREY[NilClass] = { '
|
|
2459
|
+
RUBY_OBJECT_TO_AUDREY[NilClass] = { 'aclass'=>Audrey::Object::Scalar::Null}
|
|
2467
2460
|
|
|
2468
|
-
RUBY_OBJECT_TO_AUDREY[Hash] = {'
|
|
2469
|
-
RUBY_OBJECT_TO_AUDREY[Array] = {'
|
|
2461
|
+
RUBY_OBJECT_TO_AUDREY[Hash] = {'aclass'=>Audrey::Object::Hash, 'nclass'=>Audrey::Node::Hash}
|
|
2462
|
+
RUBY_OBJECT_TO_AUDREY[Array] = {'aclass'=>Audrey::Object::Array, 'nclass'=>Audrey::Node::Array}
|
|
2470
2463
|
RUBY_OBJECT_TO_AUDREY.freeze
|
|
2471
2464
|
#
|
|
2472
2465
|
# RUBY_OBJECT_TO_AUDREY
|
|
@@ -2491,13 +2484,18 @@ class Audrey
|
|
|
2491
2484
|
# AUDREY_COLLECTION_TO_RUBY
|
|
2492
2485
|
#
|
|
2493
2486
|
AUDREY_COLLECTION_TO_RUBY = {}
|
|
2487
|
+
|
|
2494
2488
|
AUDREY_COLLECTION_TO_RUBY[Audrey::Object::Hash.to_s] = {'nclass'=>Audrey::Node::Hash}
|
|
2495
2489
|
AUDREY_COLLECTION_TO_RUBY[Audrey::Object::Array.to_s] = {'nclass'=>Audrey::Node::Array}
|
|
2490
|
+
|
|
2491
|
+
AUDREY_COLLECTION_TO_RUBY['h'] = {'nclass'=>Audrey::Node::Hash}
|
|
2492
|
+
AUDREY_COLLECTION_TO_RUBY['a'] = {'nclass'=>Audrey::Node::Array}
|
|
2493
|
+
|
|
2496
2494
|
AUDREY_COLLECTION_TO_RUBY.freeze
|
|
2497
2495
|
#
|
|
2498
2496
|
# AUDREY_COLLECTION_TO_RUBY
|
|
2499
2497
|
#---------------------------------------------------------------------------
|
|
2500
2498
|
end
|
|
2501
2499
|
#
|
|
2502
|
-
# build
|
|
2500
|
+
# build aclasses for collections
|
|
2503
2501
|
#===============================================================================
|
|
@@ -240,17 +240,17 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
240
240
|
#-----------------------------------------------------------------------
|
|
241
241
|
# insert_object_journal
|
|
242
242
|
#
|
|
243
|
-
@dbh.create_function('insert_object_journal', 4 ) do |func, partition, root,
|
|
243
|
+
@dbh.create_function('insert_object_journal', 4 ) do |func, partition, root, aclass, scalar, xt|
|
|
244
244
|
# $tm.hrm
|
|
245
245
|
|
|
246
246
|
# translate scalars to objects for storage in JSON
|
|
247
|
-
if converter = Audrey::AUDREY_SCALAR_TO_RUBY[
|
|
247
|
+
if converter = Audrey::AUDREY_SCALAR_TO_RUBY[aclass]
|
|
248
248
|
scalar = converter.call(scalar)
|
|
249
249
|
end
|
|
250
250
|
|
|
251
251
|
# initialize
|
|
252
252
|
rv = {}
|
|
253
|
-
rv['fc'] =
|
|
253
|
+
rv['fc'] = aclass
|
|
254
254
|
rv['pt'] = partition
|
|
255
255
|
|
|
256
256
|
# scalar
|
|
@@ -277,47 +277,36 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
277
277
|
|
|
278
278
|
|
|
279
279
|
#-----------------------------------------------------------------------
|
|
280
|
-
#
|
|
280
|
+
# aclass_fco, aclass_isolate
|
|
281
281
|
#
|
|
282
|
-
@dbh.create_function('
|
|
283
|
-
func.result = Audrey::Util.
|
|
282
|
+
@dbh.create_function('aclass_fco', 1) do |func, aclass|
|
|
283
|
+
func.result = Audrey::Util.aclass_fco(aclass) ? 1 : 0
|
|
284
284
|
end
|
|
285
285
|
|
|
286
|
-
@dbh.create_function('
|
|
287
|
-
func.result = Audrey::Util.
|
|
286
|
+
@dbh.create_function('aclass_isolate', 1) do |func, aclass|
|
|
287
|
+
func.result = Audrey::Util.aclass_isolate(aclass) ? 1 : 0
|
|
288
288
|
end
|
|
289
289
|
#
|
|
290
|
-
#
|
|
290
|
+
# aclass_fco, aclass_isolate
|
|
291
291
|
#-----------------------------------------------------------------------
|
|
292
292
|
|
|
293
293
|
|
|
294
294
|
#-----------------------------------------------------------------------
|
|
295
295
|
# graph_field
|
|
296
296
|
#
|
|
297
|
-
@dbh.create_function('graph_field', 2) do |func,
|
|
298
|
-
func.result = Audrey::Util.graph_field?(
|
|
297
|
+
@dbh.create_function('graph_field', 2) do |func, aclass, hkey|
|
|
298
|
+
func.result = Audrey::Util.graph_field?(aclass, hkey) ? 1 : 0
|
|
299
299
|
end
|
|
300
300
|
#
|
|
301
301
|
# graph_field
|
|
302
302
|
#-----------------------------------------------------------------------
|
|
303
303
|
|
|
304
304
|
|
|
305
|
-
#-----------------------------------------------------------------------
|
|
306
|
-
# change_to_true
|
|
307
|
-
#
|
|
308
|
-
# @dbh.create_function('change_to_true', 1) do |func, fclass|
|
|
309
|
-
# func.result = 1
|
|
310
|
-
# end
|
|
311
|
-
#
|
|
312
|
-
# change_to_true
|
|
313
|
-
#-----------------------------------------------------------------------
|
|
314
|
-
|
|
315
|
-
|
|
316
305
|
#-----------------------------------------------------------------------
|
|
317
306
|
# custom_class
|
|
318
307
|
#
|
|
319
|
-
@dbh.create_function('custom_class', 1) do |func,
|
|
320
|
-
func.result = Audrey::Util.custom_class?(
|
|
308
|
+
@dbh.create_function('custom_class', 1) do |func, aclass|
|
|
309
|
+
func.result = Audrey::Util.custom_class?(aclass) ? 1 : 0
|
|
321
310
|
end
|
|
322
311
|
#
|
|
323
312
|
# custom_class
|
|
@@ -381,8 +370,8 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
381
370
|
if dfn = Audrey::Engine::SQLite3::RUBY_SCALAR_TO_SQLITE[object.class]
|
|
382
371
|
if not @preps['insert_scalar']
|
|
383
372
|
sql = <<~'SQL'
|
|
384
|
-
insert into objects(pk, partition,
|
|
385
|
-
values(:pk, :partition,
|
|
373
|
+
insert into objects(pk, partition, hsa, aclass, scalar)
|
|
374
|
+
values(:pk, :partition, 's', :aclass, :scalar)
|
|
386
375
|
SQL
|
|
387
376
|
|
|
388
377
|
@preps['insert_scalar'] = @dbh.prepare(sql)
|
|
@@ -393,8 +382,7 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
393
382
|
@preps['insert_scalar'],
|
|
394
383
|
'pk' => pk,
|
|
395
384
|
'partition' => @partition,
|
|
396
|
-
'
|
|
397
|
-
'fclass' => dfn['fclass'].to_s,
|
|
385
|
+
'aclass' => dfn['aclass'].to_s,
|
|
398
386
|
'scalar' => dfn['to_db'].call(object)
|
|
399
387
|
);
|
|
400
388
|
|
|
@@ -404,18 +392,20 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
404
392
|
prepare_insert_collection(),
|
|
405
393
|
'pk' => pk,
|
|
406
394
|
'partition' => @partition,
|
|
407
|
-
'
|
|
408
|
-
'
|
|
395
|
+
'hsa' => dfn['aclass'].hsa,
|
|
396
|
+
'aclass' => dfn['aclass'].to_s
|
|
409
397
|
);
|
|
410
398
|
|
|
411
399
|
# if custom object
|
|
412
400
|
elsif object.is_a?(Audrey::Object::Custom)
|
|
401
|
+
oclass = object.class
|
|
402
|
+
|
|
413
403
|
simple_exec(
|
|
414
404
|
prepare_insert_collection(),
|
|
415
405
|
'pk' => pk,
|
|
416
406
|
'partition' => @partition,
|
|
417
|
-
'
|
|
418
|
-
'
|
|
407
|
+
'hsa' => oclass.hsa,
|
|
408
|
+
'aclass' => oclass.to_s,
|
|
419
409
|
);
|
|
420
410
|
|
|
421
411
|
# else unknown
|
|
@@ -464,8 +454,8 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
464
454
|
# prepare insert statement if necessary
|
|
465
455
|
if not @preps['insert_xt']
|
|
466
456
|
sql = <<~SQL
|
|
467
|
-
insert into objects(pk, partition,
|
|
468
|
-
values(?, (select partition from objects where pk=?), '
|
|
457
|
+
insert into objects(pk, partition, hsa, aclass)
|
|
458
|
+
values(?, (select partition from objects where pk=?), 'h', 'xt')
|
|
469
459
|
SQL
|
|
470
460
|
|
|
471
461
|
@preps['insert_xt'] ||= @dbh.prepare(sql)
|
|
@@ -1001,18 +991,6 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
1001
991
|
#---------------------------------------------------------------------------
|
|
1002
992
|
|
|
1003
993
|
|
|
1004
|
-
#---------------------------------------------------------------------------
|
|
1005
|
-
# import_csv
|
|
1006
|
-
#
|
|
1007
|
-
def import_csv(fclass, path, opts={})
|
|
1008
|
-
# $tm.hrm
|
|
1009
|
-
return Audrey::Engine::SQLite3::Importer::CSV.new(self, fclass, path, opts={})
|
|
1010
|
-
end
|
|
1011
|
-
#
|
|
1012
|
-
# import_csv
|
|
1013
|
-
#---------------------------------------------------------------------------
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
994
|
#---------------------------------------------------------------------------
|
|
1017
995
|
# changed_objects
|
|
1018
996
|
#
|
|
@@ -1026,7 +1004,7 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
1026
1004
|
from objects
|
|
1027
1005
|
where
|
|
1028
1006
|
changed and
|
|
1029
|
-
custom_class(
|
|
1007
|
+
custom_class(aclass)
|
|
1030
1008
|
order by
|
|
1031
1009
|
changed
|
|
1032
1010
|
SQL
|
|
@@ -1071,26 +1049,26 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
1071
1049
|
RUBY_SCALAR_TO_SQLITE = {}
|
|
1072
1050
|
|
|
1073
1051
|
RUBY_SCALAR_TO_SQLITE[::String] = {
|
|
1074
|
-
'
|
|
1052
|
+
'aclass' => Audrey::Object::Scalar::String,
|
|
1075
1053
|
'to_db' => Proc.new {|obj| obj}
|
|
1076
1054
|
}
|
|
1077
1055
|
|
|
1078
1056
|
RUBY_SCALAR_TO_SQLITE[::Integer] = {
|
|
1079
|
-
'
|
|
1057
|
+
'aclass' => Audrey::Object::Scalar::Number,
|
|
1080
1058
|
'to_db' => Proc.new {|obj| obj.to_s}
|
|
1081
1059
|
}
|
|
1082
1060
|
|
|
1083
1061
|
RUBY_SCALAR_TO_SQLITE[::Float] = RUBY_SCALAR_TO_SQLITE[::Integer]
|
|
1084
1062
|
|
|
1085
1063
|
RUBY_SCALAR_TO_SQLITE[::TrueClass] = {
|
|
1086
|
-
'
|
|
1064
|
+
'aclass' => Audrey::Object::Scalar::Boolean,
|
|
1087
1065
|
'to_db' => Proc.new {|obj| obj ? 1 : 0}
|
|
1088
1066
|
}
|
|
1089
1067
|
|
|
1090
1068
|
RUBY_SCALAR_TO_SQLITE[::FalseClass] = RUBY_SCALAR_TO_SQLITE[::TrueClass]
|
|
1091
1069
|
|
|
1092
1070
|
RUBY_SCALAR_TO_SQLITE[::NilClass] = {
|
|
1093
|
-
'
|
|
1071
|
+
'aclass' => Audrey::Object::Scalar::Null,
|
|
1094
1072
|
'to_db' => Proc.new {|obj| nil}
|
|
1095
1073
|
}
|
|
1096
1074
|
|
|
@@ -1106,8 +1084,8 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
1106
1084
|
def prepare_insert_collection
|
|
1107
1085
|
if not @preps['insert_collection']
|
|
1108
1086
|
sql = <<~'SQL'
|
|
1109
|
-
insert into objects(pk, partition,
|
|
1110
|
-
values(:pk, :partition, :
|
|
1087
|
+
insert into objects(pk, partition, hsa, aclass)
|
|
1088
|
+
values(:pk, :partition, :hsa, :aclass)
|
|
1111
1089
|
SQL
|
|
1112
1090
|
|
|
1113
1091
|
@preps['insert_collection'] = @dbh.prepare(sql)
|
|
@@ -1125,7 +1103,7 @@ class Audrey::Engine::SQLite3 < Audrey::Engine
|
|
|
1125
1103
|
#
|
|
1126
1104
|
def self.set_row_scalar(row)
|
|
1127
1105
|
# fix scalar if necessary
|
|
1128
|
-
if converter = Audrey::AUDREY_SCALAR_TO_RUBY[row['
|
|
1106
|
+
if converter = Audrey::AUDREY_SCALAR_TO_RUBY[row['aclass']]
|
|
1129
1107
|
row['scalar'] = converter.call(row['scalar'])
|
|
1130
1108
|
end
|
|
1131
1109
|
|
|
@@ -1194,283 +1172,6 @@ end
|
|
|
1194
1172
|
#===============================================================================
|
|
1195
1173
|
|
|
1196
1174
|
|
|
1197
|
-
#===============================================================================
|
|
1198
|
-
# Audrey::Engine::SQLite3::Importer
|
|
1199
|
-
#
|
|
1200
|
-
class Audrey::Engine::SQLite3::Importer
|
|
1201
|
-
end
|
|
1202
|
-
#
|
|
1203
|
-
# Audrey::Engine::SQLite3::Importer
|
|
1204
|
-
#===============================================================================
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
#===============================================================================
|
|
1208
|
-
# Audrey::Engine::SQLite3::Importer::CSV
|
|
1209
|
-
#
|
|
1210
|
-
class Audrey::Engine::SQLite3::Importer::CSV < Audrey::Engine::SQLite3::Importer
|
|
1211
|
-
attr_reader :fields
|
|
1212
|
-
attr_accessor :verbose
|
|
1213
|
-
|
|
1214
|
-
#---------------------------------------------------------------------------
|
|
1215
|
-
# initialize
|
|
1216
|
-
#
|
|
1217
|
-
def initialize(engine, fclass, path, opts={})
|
|
1218
|
-
# $tm.hrm
|
|
1219
|
-
require 'csv'
|
|
1220
|
-
@engine = engine
|
|
1221
|
-
@dbh = @engine.dbh
|
|
1222
|
-
@fclass = fclass.to_s
|
|
1223
|
-
@path = path
|
|
1224
|
-
@partition = 'm'
|
|
1225
|
-
@fields = {}
|
|
1226
|
-
@verbose = false
|
|
1227
|
-
end
|
|
1228
|
-
#
|
|
1229
|
-
# initialize
|
|
1230
|
-
#---------------------------------------------------------------------------
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
#---------------------------------------------------------------------------
|
|
1234
|
-
# run
|
|
1235
|
-
#
|
|
1236
|
-
def run
|
|
1237
|
-
# $tm.hrm
|
|
1238
|
-
converters = {}
|
|
1239
|
-
count = 0
|
|
1240
|
-
|
|
1241
|
-
# set fclass primary keys
|
|
1242
|
-
fclass_pks()
|
|
1243
|
-
|
|
1244
|
-
# prepare statements
|
|
1245
|
-
prepare_statements()
|
|
1246
|
-
|
|
1247
|
-
# build converters
|
|
1248
|
-
@fields.each do |k, dfn|
|
|
1249
|
-
converters[k] = Audrey::AUDREY_SCALAR_TO_RUBY[dfn.to_s]
|
|
1250
|
-
end
|
|
1251
|
-
|
|
1252
|
-
# begin transaction
|
|
1253
|
-
@dbh.execute 'begin transaction'
|
|
1254
|
-
|
|
1255
|
-
# TESTING
|
|
1256
|
-
$tm.timer('import') do
|
|
1257
|
-
# loop through CSV
|
|
1258
|
-
::CSV.foreach(@path, headers: true) do |row|
|
|
1259
|
-
# verbosify
|
|
1260
|
-
if @verbose
|
|
1261
|
-
count += 1
|
|
1262
|
-
puts count.to_s + ': ' + row.to_s
|
|
1263
|
-
end
|
|
1264
|
-
|
|
1265
|
-
# init collection ord
|
|
1266
|
-
ord = 0
|
|
1267
|
-
|
|
1268
|
-
# convert
|
|
1269
|
-
converters.each do |k, converter|
|
|
1270
|
-
if row.has_key?(k)
|
|
1271
|
-
row[k] = converter.call(row[k])
|
|
1272
|
-
end
|
|
1273
|
-
end
|
|
1274
|
-
|
|
1275
|
-
# object pk
|
|
1276
|
-
obj_pk = Audrey::Util.uuid
|
|
1277
|
-
|
|
1278
|
-
# add hash object
|
|
1279
|
-
@insert_hash.execute(
|
|
1280
|
-
'pk'=>obj_pk,
|
|
1281
|
-
'partition'=>@partition,
|
|
1282
|
-
'bclass'=>@obj_bclass_pk,
|
|
1283
|
-
'fclass'=>@obj_fclass_pk
|
|
1284
|
-
);
|
|
1285
|
-
|
|
1286
|
-
# add scalars and relationships
|
|
1287
|
-
row.each do |k,v|
|
|
1288
|
-
ord += 1
|
|
1289
|
-
scalar_uuid = Audrey::Util.uuid
|
|
1290
|
-
|
|
1291
|
-
# add scalar object
|
|
1292
|
-
@insert_scalar.execute(
|
|
1293
|
-
'pk'=>scalar_uuid,
|
|
1294
|
-
'partition'=>@partition,
|
|
1295
|
-
'bclass'=>@scalar_bclass_pk,
|
|
1296
|
-
'fclass'=>@bclasses[v.class],
|
|
1297
|
-
'scalar'=>v
|
|
1298
|
-
);
|
|
1299
|
-
|
|
1300
|
-
# add relationship
|
|
1301
|
-
@insert_relationship.execute(
|
|
1302
|
-
'pk'=>Audrey::Util.uuid,
|
|
1303
|
-
'parent'=>obj_pk,
|
|
1304
|
-
'child'=>scalar_uuid,
|
|
1305
|
-
'hkey'=>k,
|
|
1306
|
-
'ord'=>ord
|
|
1307
|
-
);
|
|
1308
|
-
end
|
|
1309
|
-
end
|
|
1310
|
-
end
|
|
1311
|
-
|
|
1312
|
-
# commit transaction
|
|
1313
|
-
$tm.timer('commit') do
|
|
1314
|
-
@dbh.execute 'commit'
|
|
1315
|
-
end
|
|
1316
|
-
|
|
1317
|
-
# close prepared statements
|
|
1318
|
-
ensure
|
|
1319
|
-
$tm.puts 'close prepared statements'
|
|
1320
|
-
|
|
1321
|
-
$tm.timer('close prepared statements') do
|
|
1322
|
-
@insert_hash and @insert_hash.close
|
|
1323
|
-
@insert_scalar and @insert_scalar.close
|
|
1324
|
-
@insert_relationship and @insert_relationship.close
|
|
1325
|
-
end
|
|
1326
|
-
end
|
|
1327
|
-
#
|
|
1328
|
-
# run
|
|
1329
|
-
#---------------------------------------------------------------------------
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
#---------------------------------------------------------------------------
|
|
1333
|
-
# prepare_statements
|
|
1334
|
-
#
|
|
1335
|
-
def prepare_statements
|
|
1336
|
-
# $tm.hrm
|
|
1337
|
-
|
|
1338
|
-
# hash
|
|
1339
|
-
sql = <<~'SQL'
|
|
1340
|
-
insert into
|
|
1341
|
-
base_objects(
|
|
1342
|
-
pk,
|
|
1343
|
-
partition,
|
|
1344
|
-
bclass_pk,
|
|
1345
|
-
fclass_pk
|
|
1346
|
-
)
|
|
1347
|
-
|
|
1348
|
-
values(
|
|
1349
|
-
:pk,
|
|
1350
|
-
:partition,
|
|
1351
|
-
:bclass,
|
|
1352
|
-
:fclass
|
|
1353
|
-
);
|
|
1354
|
-
SQL
|
|
1355
|
-
|
|
1356
|
-
# prepare
|
|
1357
|
-
@insert_hash = @dbh.prepare(sql)
|
|
1358
|
-
|
|
1359
|
-
# scalar
|
|
1360
|
-
sql = <<~'SQL'
|
|
1361
|
-
insert into
|
|
1362
|
-
base_objects(
|
|
1363
|
-
pk,
|
|
1364
|
-
partition,
|
|
1365
|
-
bclass_pk,
|
|
1366
|
-
fclass_pk,
|
|
1367
|
-
scalar
|
|
1368
|
-
)
|
|
1369
|
-
|
|
1370
|
-
values(
|
|
1371
|
-
:pk,
|
|
1372
|
-
:partition,
|
|
1373
|
-
:bclass,
|
|
1374
|
-
:fclass,
|
|
1375
|
-
:scalar
|
|
1376
|
-
);
|
|
1377
|
-
SQL
|
|
1378
|
-
|
|
1379
|
-
# prepare
|
|
1380
|
-
@insert_scalar = @dbh.prepare(sql)
|
|
1381
|
-
|
|
1382
|
-
# relationship
|
|
1383
|
-
sql = <<~'SQL'
|
|
1384
|
-
insert into relationships(
|
|
1385
|
-
pk,
|
|
1386
|
-
parent,
|
|
1387
|
-
child,
|
|
1388
|
-
hkey,
|
|
1389
|
-
ord
|
|
1390
|
-
)
|
|
1391
|
-
|
|
1392
|
-
values(
|
|
1393
|
-
:pk,
|
|
1394
|
-
:parent,
|
|
1395
|
-
:child,
|
|
1396
|
-
:hkey,
|
|
1397
|
-
:ord
|
|
1398
|
-
)
|
|
1399
|
-
SQL
|
|
1400
|
-
|
|
1401
|
-
# prepare
|
|
1402
|
-
@insert_relationship = @dbh.prepare(sql)
|
|
1403
|
-
end
|
|
1404
|
-
#
|
|
1405
|
-
# prepare_statements
|
|
1406
|
-
#---------------------------------------------------------------------------
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
#---------------------------------------------------------------------------
|
|
1410
|
-
# fclass_pks
|
|
1411
|
-
#
|
|
1412
|
-
def fclass_pks
|
|
1413
|
-
@bclasses = {}
|
|
1414
|
-
|
|
1415
|
-
# object bclass primary key
|
|
1416
|
-
@obj_bclass_pk = set_fclass_pk('Audrey::Object::Hash')
|
|
1417
|
-
|
|
1418
|
-
# object fclass primary key
|
|
1419
|
-
@obj_fclass_pk = set_fclass_pk(@fclass)
|
|
1420
|
-
|
|
1421
|
-
# scalar base class
|
|
1422
|
-
@scalar_bclass_pk = set_fclass_pk('Audrey::Object::Scalar')
|
|
1423
|
-
|
|
1424
|
-
# loop through scalar classes
|
|
1425
|
-
[String, Integer, Float, NilClass].each do |clss|
|
|
1426
|
-
@bclasses[clss] = set_fclass_pk(Audrey::RUBY_OBJECT_TO_AUDREY[clss]['fclass'].to_s)
|
|
1427
|
-
end
|
|
1428
|
-
end
|
|
1429
|
-
#
|
|
1430
|
-
# fclass_pks
|
|
1431
|
-
#---------------------------------------------------------------------------
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
#---------------------------------------------------------------------------
|
|
1435
|
-
# set_fclass_pk
|
|
1436
|
-
#
|
|
1437
|
-
def set_fclass_pk(set_fclass)
|
|
1438
|
-
# $tm.hrm
|
|
1439
|
-
|
|
1440
|
-
# ensure fclass record
|
|
1441
|
-
sql = <<~'SQL'
|
|
1442
|
-
insert or ignore into
|
|
1443
|
-
fclasses(name)
|
|
1444
|
-
values(:fclass);
|
|
1445
|
-
SQL
|
|
1446
|
-
|
|
1447
|
-
# execute
|
|
1448
|
-
@dbh.execute sql, 'fclass'=>set_fclass
|
|
1449
|
-
|
|
1450
|
-
# get fclass pk
|
|
1451
|
-
sql = 'select pk from fclasses where name=:fclass'
|
|
1452
|
-
return @dbh.get_first_value(sql, 'fclass'=>set_fclass)
|
|
1453
|
-
end
|
|
1454
|
-
#
|
|
1455
|
-
# set_fclass_pk
|
|
1456
|
-
#---------------------------------------------------------------------------
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
#---------------------------------------------------------------------------
|
|
1460
|
-
# set_bclass_pks
|
|
1461
|
-
#
|
|
1462
|
-
# def set_bclass_pks
|
|
1463
|
-
# $tm.hrm
|
|
1464
|
-
# end
|
|
1465
|
-
#
|
|
1466
|
-
# set_bclass_pks
|
|
1467
|
-
#---------------------------------------------------------------------------
|
|
1468
|
-
end
|
|
1469
|
-
#
|
|
1470
|
-
# Audrey::Engine::SQLite3::Importer::CSV
|
|
1471
|
-
#===============================================================================
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
1175
|
#===============================================================================
|
|
1475
1176
|
# Audrey::Engine::SQLite3::Query
|
|
1476
1177
|
#
|
|
@@ -167,18 +167,18 @@ module Audrey::Engine::SQLite3::Init
|
|
|
167
167
|
def self.objects
|
|
168
168
|
# build
|
|
169
169
|
@dbh.execute_batch <<-SQL
|
|
170
|
-
--
|
|
171
|
-
create table
|
|
170
|
+
-- aclasses table
|
|
171
|
+
create table aclasses(
|
|
172
172
|
pk integer primary key autoincrement,
|
|
173
173
|
name varchar(255) unique not null,
|
|
174
174
|
check (length(name)>0)
|
|
175
175
|
);
|
|
176
176
|
|
|
177
|
-
-- cannot update
|
|
178
|
-
create trigger
|
|
179
|
-
before update on
|
|
177
|
+
-- cannot update aclasses
|
|
178
|
+
create trigger aclasses_bu
|
|
179
|
+
before update on aclasses
|
|
180
180
|
begin
|
|
181
|
-
select raise(abort, 'cannot-update-
|
|
181
|
+
select raise(abort, 'cannot-update-aclasses');
|
|
182
182
|
end;
|
|
183
183
|
|
|
184
184
|
-- base_objects table
|
|
@@ -186,8 +186,8 @@ module Audrey::Engine::SQLite3::Init
|
|
|
186
186
|
pk varchar(36) primary key,
|
|
187
187
|
partition varchar(1) not null references partitions(pk),
|
|
188
188
|
root boolean,
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
hsa varchar(1) not null check(hsa in ('h', 's', 'a')),
|
|
190
|
+
aclass_pk integer not null references aclasses(pk) on delete restrict,
|
|
191
191
|
scalar text,
|
|
192
192
|
xt uuid references base_objects(pk) unique,
|
|
193
193
|
changed datetime default current_timestamp,
|
|
@@ -197,8 +197,8 @@ module Audrey::Engine::SQLite3::Init
|
|
|
197
197
|
-- indexes
|
|
198
198
|
create unique index base_objects_partition_root on base_objects(partition, root);
|
|
199
199
|
create index base_objects_partition on base_objects(partition);
|
|
200
|
-
create index
|
|
201
|
-
create index
|
|
200
|
+
create index base_objects_hsa on base_objects(hsa);
|
|
201
|
+
create index base_objects_aclass_pk on base_objects(aclass_pk);
|
|
202
202
|
create index base_objects_scalar on base_objects(scalar);
|
|
203
203
|
create index base_objects_changed on base_objects(changed);
|
|
204
204
|
|
|
@@ -206,8 +206,8 @@ module Audrey::Engine::SQLite3::Init
|
|
|
206
206
|
create trigger base_objects_bu_pk before update of pk on base_objects begin select raise(abort, 'cannot-update-object-pk'); end;
|
|
207
207
|
create trigger base_objects_bu_partition before update of partition on base_objects begin select raise(abort, 'cannot-update-object-partition'); end;
|
|
208
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
|
|
210
|
-
create trigger
|
|
209
|
+
create trigger base_objects_bu_hsa before update of hsa on base_objects begin select raise(abort, 'cannot-update-object-hsa'); end;
|
|
210
|
+
create trigger base_objects_bu_aclass_pk before update of aclass_pk on base_objects begin select raise(abort, 'cannot-update-object-aclass_pk'); end;
|
|
211
211
|
create trigger base_objects_bu_scalar before update of scalar on base_objects begin select raise(abort, 'cannot-update-object-scalar'); end;
|
|
212
212
|
|
|
213
213
|
-- cannot update xt once it has been defined
|
|
@@ -235,7 +235,7 @@ module Audrey::Engine::SQLite3::Init
|
|
|
235
235
|
insert_object_journal(
|
|
236
236
|
new.partition,
|
|
237
237
|
new.root,
|
|
238
|
-
(select name from
|
|
238
|
+
(select name from aclasses where pk=new.aclass_pk),
|
|
239
239
|
new.scalar,
|
|
240
240
|
new.xt
|
|
241
241
|
)
|
|
@@ -266,21 +266,20 @@ module Audrey::Engine::SQLite3::Init
|
|
|
266
266
|
insert into journal(tbl, fpk, action) values('o', old.pk, 'd');
|
|
267
267
|
end;
|
|
268
268
|
|
|
269
|
-
-- initial
|
|
270
|
-
insert into
|
|
271
|
-
insert into
|
|
269
|
+
-- initial aclass
|
|
270
|
+
insert into aclasses(name) values('Audrey::Object::Hash');
|
|
271
|
+
insert into aclasses(name) values('Audrey::Object::Root');
|
|
272
272
|
|
|
273
273
|
-- add root objects
|
|
274
|
-
insert into base_objects(pk, partition,
|
|
275
|
-
insert into base_objects(pk, partition,
|
|
276
|
-
insert into base_objects(pk, partition,
|
|
274
|
+
insert into base_objects(pk, partition, hsa, aclass_pk, root, changed) values('1', 'm', 'h', 2, 1, null);
|
|
275
|
+
insert into base_objects(pk, partition, hsa, aclass_pk, root, changed) values('2', 'r', 'h', 2, 1, null);
|
|
276
|
+
insert into base_objects(pk, partition, hsa, aclass_pk, root, changed) values('3', 'd', 'h', 2, 1, null);
|
|
277
277
|
|
|
278
278
|
-- objects view
|
|
279
279
|
create view objects as
|
|
280
280
|
select
|
|
281
|
-
o.pk, o.partition, o.root, o.scalar, o.xt, o.changed,
|
|
282
|
-
(select name from
|
|
283
|
-
(select name from fclasses where pk=o.fclass_pk) as fclass
|
|
281
|
+
o.pk, o.partition, o.root, o.scalar, o.xt, o.changed, o.hsa,
|
|
282
|
+
(select name from aclasses where pk=o.aclass_pk) as aclass
|
|
284
283
|
from base_objects o
|
|
285
284
|
where o.partition = current_partition();
|
|
286
285
|
|
|
@@ -289,17 +288,12 @@ module Audrey::Engine::SQLite3::Init
|
|
|
289
288
|
instead of insert on objects
|
|
290
289
|
begin
|
|
291
290
|
-- notify database of change
|
|
292
|
-
-- select change_to_true(new.
|
|
291
|
+
-- select change_to_true(new.aclass);
|
|
293
292
|
|
|
294
|
-
-- ensure
|
|
293
|
+
-- ensure aclass record
|
|
295
294
|
insert or ignore into
|
|
296
|
-
|
|
297
|
-
values(new.
|
|
298
|
-
|
|
299
|
-
-- ensure fclass record
|
|
300
|
-
insert or ignore into
|
|
301
|
-
fclasses(name)
|
|
302
|
-
values(new.fclass);
|
|
295
|
+
aclasses(name)
|
|
296
|
+
values(new.aclass);
|
|
303
297
|
|
|
304
298
|
-- insert
|
|
305
299
|
insert into
|
|
@@ -307,8 +301,8 @@ module Audrey::Engine::SQLite3::Init
|
|
|
307
301
|
pk,
|
|
308
302
|
partition,
|
|
309
303
|
root,
|
|
310
|
-
|
|
311
|
-
|
|
304
|
+
hsa,
|
|
305
|
+
aclass_pk,
|
|
312
306
|
scalar,
|
|
313
307
|
xt
|
|
314
308
|
)
|
|
@@ -317,8 +311,8 @@ module Audrey::Engine::SQLite3::Init
|
|
|
317
311
|
new.pk,
|
|
318
312
|
current_partition(),
|
|
319
313
|
new.root,
|
|
320
|
-
|
|
321
|
-
(select pk from
|
|
314
|
+
new.hsa,
|
|
315
|
+
(select pk from aclasses where name=new.aclass),
|
|
322
316
|
new.scalar,
|
|
323
317
|
new.xt
|
|
324
318
|
);
|
|
@@ -384,12 +378,12 @@ module Audrey::Engine::SQLite3::Init
|
|
|
384
378
|
end;
|
|
385
379
|
|
|
386
380
|
-- parent must be array or hash
|
|
387
|
-
create trigger
|
|
381
|
+
create trigger relationships_bi_hsa
|
|
388
382
|
before insert on relationships
|
|
389
383
|
begin
|
|
390
384
|
select case
|
|
391
|
-
|
|
392
|
-
|
|
385
|
+
when (select hsa from objects where pk=new.parent) not in ('h', 'a') then
|
|
386
|
+
raise(abort, 'relationship-parent-base-class-does-not-support-relatonships')
|
|
393
387
|
end;
|
|
394
388
|
end;
|
|
395
389
|
|
|
@@ -451,7 +445,7 @@ module Audrey::Engine::SQLite3::Init
|
|
|
451
445
|
-- from objects view, the delete never happens. So deleting directly
|
|
452
446
|
-- from base_objects.
|
|
453
447
|
create trigger relationships_ad_graph
|
|
454
|
-
after delete on relationships when (select graph_field((select
|
|
448
|
+
after delete on relationships when (select graph_field((select aclass from objects where pk=old.parent), old.hkey))
|
|
455
449
|
begin
|
|
456
450
|
delete from base_objects where pk=old.parent;
|
|
457
451
|
end;
|
|
@@ -483,7 +477,7 @@ module Audrey::Engine::SQLite3::Init
|
|
|
483
477
|
create view fcos as
|
|
484
478
|
select pk
|
|
485
479
|
from objects
|
|
486
|
-
where
|
|
480
|
+
where aclass_fco(aclass);
|
|
487
481
|
|
|
488
482
|
-- fco_descendants
|
|
489
483
|
create view fco_descendants as
|
|
@@ -498,7 +492,7 @@ module Audrey::Engine::SQLite3::Init
|
|
|
498
492
|
create view fco_traced as
|
|
499
493
|
select distinct pk
|
|
500
494
|
from objects
|
|
501
|
-
where
|
|
495
|
+
where aclass_fco(aclass) or (pk in (select child from fco_descendants));
|
|
502
496
|
|
|
503
497
|
-- fco_not_traced
|
|
504
498
|
create view fco_not_traced as
|
|
@@ -125,18 +125,18 @@ class Audrey::Engine::SQLite3::Query::Q0
|
|
|
125
125
|
# partition pk
|
|
126
126
|
params['partition'] = @engine.partition
|
|
127
127
|
|
|
128
|
-
#
|
|
129
|
-
if (
|
|
128
|
+
# aclasses
|
|
129
|
+
if (aclasses = @fquery.aclasses) and aclasses.any?
|
|
130
130
|
wheres = []
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
aclasses.each do |aclass|
|
|
133
133
|
rs = Audrey::Util.randstr(40)
|
|
134
134
|
wheres.push ":#{rs}"
|
|
135
|
-
params[rs] =
|
|
135
|
+
params[rs] = aclass
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
# add wheres
|
|
139
|
-
sql += " and\n" + ' (
|
|
139
|
+
sql += " and\n" + ' (aclass in (' + wheres.join(', ') + '))'
|
|
140
140
|
end
|
|
141
141
|
|
|
142
142
|
# limit to hashes
|
|
@@ -226,14 +226,14 @@ class Audrey::Engine::SQLite3::Query::Q0
|
|
|
226
226
|
|
|
227
227
|
|
|
228
228
|
#---------------------------------------------------------------------------
|
|
229
|
-
#
|
|
229
|
+
# aclasses
|
|
230
230
|
#
|
|
231
|
-
def
|
|
232
|
-
fcs = @fquery.
|
|
231
|
+
def aclasses(wheres, params)
|
|
232
|
+
fcs = @fquery.aclasses
|
|
233
233
|
fcs.any? or return
|
|
234
234
|
where = []
|
|
235
235
|
|
|
236
|
-
# loop through
|
|
236
|
+
# loop through aclasses
|
|
237
237
|
fcs.each do |fc|
|
|
238
238
|
rs = Audrey::Util.randstr(40)
|
|
239
239
|
params[rs] = fc
|
|
@@ -241,10 +241,10 @@ class Audrey::Engine::SQLite3::Query::Q0
|
|
|
241
241
|
end
|
|
242
242
|
|
|
243
243
|
# add to wheres
|
|
244
|
-
wheres.push '
|
|
244
|
+
wheres.push 'aclass in (' + where.join(', ') + ')'
|
|
245
245
|
end
|
|
246
246
|
#
|
|
247
|
-
#
|
|
247
|
+
# aclasses
|
|
248
248
|
#---------------------------------------------------------------------------
|
|
249
249
|
|
|
250
250
|
|
data/lib/audrey/query/q0.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
class Audrey::Query::Q0 < Audrey::Query
|
|
5
5
|
attr_reader :db
|
|
6
6
|
attr_accessor :fields
|
|
7
|
-
attr_accessor :
|
|
7
|
+
attr_accessor :aclass
|
|
8
8
|
attr_accessor :limit
|
|
9
9
|
attr_accessor :offset
|
|
10
10
|
|
|
@@ -19,7 +19,7 @@ class Audrey::Query::Q0 < Audrey::Query
|
|
|
19
19
|
|
|
20
20
|
@db = p_db
|
|
21
21
|
@engine = @db.engine
|
|
22
|
-
@
|
|
22
|
+
@aclass = nil
|
|
23
23
|
@fields = Audrey::Query::Q0::Fields.new()
|
|
24
24
|
end
|
|
25
25
|
#
|
|
@@ -152,20 +152,20 @@ class Audrey::Query::Q0 < Audrey::Query
|
|
|
152
152
|
|
|
153
153
|
|
|
154
154
|
#---------------------------------------------------------------------------
|
|
155
|
-
#
|
|
155
|
+
# aclasses
|
|
156
156
|
#
|
|
157
|
-
def
|
|
157
|
+
def aclasses
|
|
158
158
|
# $tm.hrm
|
|
159
159
|
|
|
160
|
-
# early exit: no
|
|
161
|
-
if not @
|
|
160
|
+
# early exit: no aclass
|
|
161
|
+
if not @aclass
|
|
162
162
|
return nil
|
|
163
163
|
end
|
|
164
164
|
|
|
165
165
|
# initialize
|
|
166
|
-
fcs = [*@
|
|
166
|
+
fcs = [*@aclass]
|
|
167
167
|
|
|
168
|
-
# early exit:
|
|
168
|
+
# early exit: aclass is an empty array
|
|
169
169
|
# NOTE: An empty array would mean that not records are returned, so
|
|
170
170
|
# we'll interpret it to mean all records.
|
|
171
171
|
if not fcs.any?
|
|
@@ -175,9 +175,9 @@ class Audrey::Query::Q0 < Audrey::Query
|
|
|
175
175
|
# initialize
|
|
176
176
|
rv = {}
|
|
177
177
|
|
|
178
|
-
# build
|
|
179
|
-
fcs.each do |
|
|
180
|
-
|
|
178
|
+
# build aclasses
|
|
179
|
+
fcs.each do |aclass|
|
|
180
|
+
aclass.aclasses.each do |desc|
|
|
181
181
|
rv[desc] = nil
|
|
182
182
|
end
|
|
183
183
|
end
|
|
@@ -186,7 +186,7 @@ class Audrey::Query::Q0 < Audrey::Query
|
|
|
186
186
|
return rv.keys
|
|
187
187
|
end
|
|
188
188
|
#
|
|
189
|
-
#
|
|
189
|
+
# aclasses
|
|
190
190
|
#---------------------------------------------------------------------------
|
|
191
191
|
|
|
192
192
|
|
|
@@ -197,11 +197,11 @@ class Audrey::Query::Q0 < Audrey::Query
|
|
|
197
197
|
# $tm.hrm
|
|
198
198
|
rv = self.class.new(@db)
|
|
199
199
|
|
|
200
|
-
#
|
|
201
|
-
if @
|
|
202
|
-
rv.
|
|
200
|
+
# aclass
|
|
201
|
+
if @aclass.is_a?(Array)
|
|
202
|
+
rv.aclass = @aclass.clone
|
|
203
203
|
else
|
|
204
|
-
rv.
|
|
204
|
+
rv.aclass = @aclass
|
|
205
205
|
end
|
|
206
206
|
|
|
207
207
|
# fields
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: audrey
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike O'Sullivan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-02-
|
|
11
|
+
date: 2020-02-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: sqlite3
|
|
@@ -38,8 +38,7 @@ dependencies:
|
|
|
38
38
|
- - ">="
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: '0'
|
|
41
|
-
description:
|
|
42
|
-
in a few hours
|
|
41
|
+
description: The world's easiest database
|
|
43
42
|
email: mike@idocs.com
|
|
44
43
|
executables: []
|
|
45
44
|
extensions: []
|