ObjectModel 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README +849 -0
- data/lib/ObjectModel.res/config.yaml +5 -0
- data/lib/ObjectModel/AnEntity/BackReferences.rb +113 -0
- data/lib/ObjectModel/AnEntity/Bag.rb +129 -0
- data/lib/ObjectModel/AnEntity/BagCopy.rb +29 -0
- data/lib/ObjectModel/AnEntity/ChildrenBag.rb +10 -0
- data/lib/ObjectModel/AnEntity/EntityCopy.rb +38 -0
- data/lib/ObjectModel/AnEntity/EntityType.rb +408 -0
- data/lib/ObjectModel/AnEntity/ReferencesBag.rb +10 -0
- data/lib/ObjectModel/AnEntity/entity_cm.rb +108 -0
- data/lib/ObjectModel/Entity.rb +278 -0
- data/lib/ObjectModel/Errors/LoadError.rb +3 -0
- data/lib/ObjectModel/Errors/NoTransactionError.rb +3 -0
- data/lib/ObjectModel/Errors/NotFoundError.rb +2 -0
- data/lib/ObjectModel/Errors/OutdatedError.rb +8 -0
- data/lib/ObjectModel/Errors/ValidationError.rb +3 -0
- data/lib/ObjectModel/Indexes/HashIndex.rb +64 -0
- data/lib/ObjectModel/Indexes/IndexStorage.rb +64 -0
- data/lib/ObjectModel/Indexes/Manager.rb +72 -0
- data/lib/ObjectModel/Metadata.rb +34 -0
- data/lib/ObjectModel/Metadata.res/after_event_types.rb +25 -0
- data/lib/ObjectModel/Metadata.res/attribute_types_shortcuts.rb +10 -0
- data/lib/ObjectModel/Metadata.res/before_event_types.rb +25 -0
- data/lib/ObjectModel/Metadata.res/child_types_shortcuts.rb +4 -0
- data/lib/ObjectModel/Metadata.res/metadata_checks.rb +9 -0
- data/lib/ObjectModel/Metadata.res/reference_types_shortcuts.rb +4 -0
- data/lib/ObjectModel/Metadata/DSL.rb +11 -0
- data/lib/ObjectModel/Metadata/attribute.rb +56 -0
- data/lib/ObjectModel/Metadata/child.rb +50 -0
- data/lib/ObjectModel/Metadata/events.rb +109 -0
- data/lib/ObjectModel/Metadata/name.rb +20 -0
- data/lib/ObjectModel/Metadata/reference.rb +50 -0
- data/lib/ObjectModel/Metadata/require.rb +10 -0
- data/lib/ObjectModel/Metadata/validate.rb +66 -0
- data/lib/ObjectModel/Repository.rb +326 -0
- data/lib/ObjectModel/Repository/EventProcessor.rb +58 -0
- data/lib/ObjectModel/Repository/ObjectStorage.rb +102 -0
- data/lib/ObjectModel/Repository/StreamID.rb +20 -0
- data/lib/ObjectModel/Repository/StreamStorage.rb +121 -0
- data/lib/ObjectModel/Repository/SystemListener.rb +143 -0
- data/lib/ObjectModel/Repository/Transaction.rb +63 -0
- data/lib/ObjectModel/Repository/TransactionProcessor.rb +36 -0
- data/lib/ObjectModel/Tools/DefaultTransactionStrategy.rb +9 -0
- data/lib/ObjectModel/Tools/InMemoryCache.rb +9 -0
- data/lib/ObjectModel/Tools/NoCache.rb +18 -0
- data/lib/ObjectModel/Tools/OGLRUCache.rb +37 -0
- data/lib/ObjectModel/Types/BagType.rb +94 -0
- data/lib/ObjectModel/Types/BooleanType.rb +42 -0
- data/lib/ObjectModel/Types/ClassType.rb +43 -0
- data/lib/ObjectModel/Types/DataType.rb +44 -0
- data/lib/ObjectModel/Types/DateType.rb +43 -0
- data/lib/ObjectModel/Types/NumberType.rb +62 -0
- data/lib/ObjectModel/Types/ObjectType.rb +164 -0
- data/lib/ObjectModel/Types/ProcType.rb +43 -0
- data/lib/ObjectModel/Types/SingleType.rb +59 -0
- data/lib/ObjectModel/Types/StringType.rb +39 -0
- data/lib/ObjectModel/_require.rb +43 -0
- data/lib/ObjectModel/require.rb +1 -0
- data/rakefile +62 -0
- data/spec/ObjectModel/BasicSpec/BaseClass.rb +7 -0
- data/spec/ObjectModel/BasicSpec/BaseTypes.rb +11 -0
- data/spec/ObjectModel/BasicSpec/Descendant.rb +5 -0
- data/spec/ObjectModel/BasicSpec/EachTest.rb +14 -0
- data/spec/ObjectModel/BasicSpec/UpChild.rb +10 -0
- data/spec/ObjectModel/BasicSpec/UpParent.rb +11 -0
- data/spec/ObjectModel/ErrorsSpec/AfterCommitError.rb +9 -0
- data/spec/ObjectModel/ExtendedSpec/CustomInitialization.rb +11 -0
- data/spec/ObjectModel/ExtendedSpec/UpNotNil.rb +8 -0
- data/spec/ObjectModel/ExtendedSpec/UpParent.rb +11 -0
- data/spec/ObjectModel/ValidationSpec/BaseTypes.rb +11 -0
- data/spec/aspect_spec.rb +55 -0
- data/spec/back_references_spec.rb +161 -0
- data/spec/basic_spec.rb +162 -0
- data/spec/cascade_delete_spec.rb +168 -0
- data/spec/complex_events_spec.rb +134 -0
- data/spec/concurrency_spec.rb +186 -0
- data/spec/containment_spec.rb +146 -0
- data/spec/data_migration_spec.rb +51 -0
- data/spec/errors_spec.rb +65 -0
- data/spec/events_spec.rb +173 -0
- data/spec/extended_spec.rb +171 -0
- data/spec/indexing_spec.rb +56 -0
- data/spec/set_in_memory.rb +2 -0
- data/spec/set_no_cache.rb +2 -0
- data/spec/smoke_test_spec.rb +85 -0
- data/spec/stream_spec.rb +143 -0
- data/spec/stream_storage.rb +148 -0
- data/spec/timer.rb +5 -0
- data/spec/validation_spec.rb +87 -0
- metadata +186 -0
@@ -0,0 +1,64 @@
|
|
1
|
+
class IndexStorage
|
2
|
+
inherit Log
|
3
|
+
|
4
|
+
attr_reader :db
|
5
|
+
attr_writer :index_manager
|
6
|
+
|
7
|
+
def initialize name, dir
|
8
|
+
folder = File.expand_path "#{dir}/#{name}"
|
9
|
+
Dir.mkdir folder unless File.exist? folder
|
10
|
+
@db = Sequel.connect("sqlite://#{folder}/#{name}_indexes.db")
|
11
|
+
@db.logger = log
|
12
|
+
|
13
|
+
initialize_db unless @db.table_exists? :metadata
|
14
|
+
|
15
|
+
@metadata ||= @db[:metadata]
|
16
|
+
@tables = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def [] type
|
20
|
+
@tables[type] ||= @db[type]
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate generator_name
|
24
|
+
generator_name = generator_name.to_s
|
25
|
+
@db.transaction do
|
26
|
+
unless row = @metadata[:key => generator_name]
|
27
|
+
@metadata << {:key => generator_name, :value => "0"}
|
28
|
+
row = @metadata[:key => generator_name]
|
29
|
+
end
|
30
|
+
id = @metadata[:key => generator_name.to_s][:value].to_i
|
31
|
+
@metadata.filter(:key => generator_name).update(:value => (id + 1).to_s)
|
32
|
+
return id.to_s
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def close
|
37
|
+
@tables.clear
|
38
|
+
@db.disconnect
|
39
|
+
end
|
40
|
+
|
41
|
+
def transaction &b
|
42
|
+
@db.transaction &b
|
43
|
+
end
|
44
|
+
|
45
|
+
def print name = nil
|
46
|
+
@index_manager.indexes.values.each{|index| index.print_storage name}
|
47
|
+
end
|
48
|
+
|
49
|
+
protected
|
50
|
+
def initialize_db
|
51
|
+
@db.create_table :metadata do
|
52
|
+
column :key, :text
|
53
|
+
column :value, :text
|
54
|
+
primary_key :key
|
55
|
+
# index :key
|
56
|
+
end
|
57
|
+
|
58
|
+
@metadata = @db[:metadata]
|
59
|
+
# @metadata << {:key => "entity_id", :value => "0"}
|
60
|
+
# @metadata << {:key => "name", :value => "0"}
|
61
|
+
# @metadata << {:key => "stream_id", :value => "0"}
|
62
|
+
@metadata << {:key => "size", :value => "0"}
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
class Manager
|
2
|
+
attr_accessor :indexes
|
3
|
+
|
4
|
+
def initialize repository
|
5
|
+
@repository = repository
|
6
|
+
@indexes = Hash.new{|hash, key| raise_without_self "No Index - '#{key}'!", ObjectModel}
|
7
|
+
@not_initialized = Set.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def add index
|
11
|
+
index.name.should! :be_a, Symbol
|
12
|
+
@indexes[index.name] = index
|
13
|
+
index.storage = @repository.indexes_storage
|
14
|
+
index.repository = @repository
|
15
|
+
builded = index.create_index
|
16
|
+
@not_initialized << index unless builded
|
17
|
+
end
|
18
|
+
|
19
|
+
def delete index_name
|
20
|
+
index_name.should! :be_a, Symbol
|
21
|
+
index = @indexes.delete index_name
|
22
|
+
index.should_not! :be_nil
|
23
|
+
index.delete_index
|
24
|
+
@not_initialized.delete index
|
25
|
+
end
|
26
|
+
|
27
|
+
def update transaction
|
28
|
+
Thread.current[:om_transaction].should_not! :be_nil
|
29
|
+
@not_initialized.should! :be_empty
|
30
|
+
|
31
|
+
@repository.indexes_storage.transaction do
|
32
|
+
indexes = @indexes.values
|
33
|
+
transaction.copies.each do |entity_id, c|
|
34
|
+
e = transaction.resolve entity_id
|
35
|
+
indexes.every.update e, c
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def [] name
|
41
|
+
check_transaction
|
42
|
+
@not_initialized.should! :be_empty
|
43
|
+
return @indexes[name]
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_index_without_transaction_check name
|
47
|
+
@not_initialized.should! :be_empty
|
48
|
+
return @indexes[name]
|
49
|
+
end
|
50
|
+
|
51
|
+
def clear_indexes
|
52
|
+
check_transaction
|
53
|
+
@indexes.values.every.delete_index
|
54
|
+
@not_initialized.replace @indexes.values
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_indexes
|
58
|
+
check_transaction
|
59
|
+
@not_initialized.every.create_index
|
60
|
+
@repository.indexes_storage.transaction do
|
61
|
+
@repository.each{|e| @not_initialized.every.add e}
|
62
|
+
end
|
63
|
+
@not_initialized.clear
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
def check_transaction
|
68
|
+
# if Thread.current[:om_transaction]
|
69
|
+
# raise_without_self "Forbiden to use Indexes inside Transaction!", ObjectModel
|
70
|
+
# end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Metadata
|
2
|
+
ATTRIBUTE_TYPES_SHORTCUTS = self["attribute_types_shortcuts.rb"]
|
3
|
+
CHILD_TYPES_SHORTCUTS = self["child_types_shortcuts.rb"]
|
4
|
+
REFERENCE_TYPES_SHORTCUTS = self["reference_types_shortcuts.rb"]
|
5
|
+
|
6
|
+
BEFORE_EVENT_TYPES = self["before_event_types.rb"]
|
7
|
+
AFTER_EVENT_TYPES = self["after_event_types.rb"]
|
8
|
+
|
9
|
+
attr_accessor :klass
|
10
|
+
|
11
|
+
def initialize klass
|
12
|
+
super()
|
13
|
+
@klass = klass
|
14
|
+
Metadata.definition.each do |name, defn|
|
15
|
+
send name.to_writer, defn.initial_value(@klass)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def inherit parent
|
20
|
+
new = Metadata.new klass
|
21
|
+
Metadata.definition.each do |name, defn|
|
22
|
+
pmeta = parent.send name
|
23
|
+
cmeta = self.send name
|
24
|
+
new.send name.to_writer, defn.inherit(pmeta, cmeta)
|
25
|
+
end
|
26
|
+
return new
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
def definition
|
31
|
+
@definition ||= {}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
[
|
2
|
+
:attribute_update,
|
3
|
+
|
4
|
+
:name_update,
|
5
|
+
|
6
|
+
:new_reference,
|
7
|
+
:delete_reference,
|
8
|
+
|
9
|
+
:new_referrer,
|
10
|
+
:delete_referrer,
|
11
|
+
|
12
|
+
:new_child,
|
13
|
+
:delete_child,
|
14
|
+
|
15
|
+
:new_parent,
|
16
|
+
:delete_parent,
|
17
|
+
|
18
|
+
:new,
|
19
|
+
:delete,
|
20
|
+
:move,
|
21
|
+
|
22
|
+
:commit,
|
23
|
+
|
24
|
+
#:containment_update,
|
25
|
+
].to_set
|
@@ -0,0 +1,25 @@
|
|
1
|
+
[
|
2
|
+
:attribute_update,
|
3
|
+
|
4
|
+
:name_update,
|
5
|
+
|
6
|
+
:new_reference,
|
7
|
+
:delete_reference,
|
8
|
+
|
9
|
+
:new_referrer,
|
10
|
+
:delete_referrer,
|
11
|
+
|
12
|
+
:new_child,
|
13
|
+
:delete_child,
|
14
|
+
|
15
|
+
:new_parent,
|
16
|
+
:delete_parent,
|
17
|
+
|
18
|
+
:new,
|
19
|
+
:delete,
|
20
|
+
:move,
|
21
|
+
|
22
|
+
:commit,
|
23
|
+
|
24
|
+
#:containment_update,
|
25
|
+
].to_set
|
@@ -0,0 +1,9 @@
|
|
1
|
+
[
|
2
|
+
lambda do |klass, meta|
|
3
|
+
a = meta.attributes.keys.to_set
|
4
|
+
c = meta.children.keys.to_set
|
5
|
+
r = meta.references.keys.to_set
|
6
|
+
dup = (a & c) + (a & r) + (c & r)
|
7
|
+
raise "The same name '#{dup.inspect}' used for attribute/child/reference definition!" unless dup.empty?
|
8
|
+
end,
|
9
|
+
]
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module ObjectModel
|
2
|
+
class Metadata
|
3
|
+
class Attributes < Hash
|
4
|
+
def initialize
|
5
|
+
super{should! :be_never_called}
|
6
|
+
end
|
7
|
+
|
8
|
+
def copy
|
9
|
+
c = Attributes.new
|
10
|
+
each{|n, m| c[n] = m.copy}
|
11
|
+
return c
|
12
|
+
end
|
13
|
+
|
14
|
+
def inherit parent
|
15
|
+
parent.copy.merge copy
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Attribute
|
20
|
+
include OpenConstructor
|
21
|
+
|
22
|
+
attr_accessor :name, :ivname, :title, :type, :initialize, :parameters, :validate
|
23
|
+
public :initialize
|
24
|
+
|
25
|
+
def copy; clone end
|
26
|
+
end
|
27
|
+
|
28
|
+
definition[:attributes] = Object.new.singleton_class do
|
29
|
+
def initial_value klass; Attributes.new end
|
30
|
+
|
31
|
+
def copy attributes; attributes.copy end
|
32
|
+
|
33
|
+
def inherit pvalue, cvalue;
|
34
|
+
cvalue.inherit pvalue
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
attr_accessor :attributes
|
39
|
+
|
40
|
+
class DSL
|
41
|
+
def attribute name, type = :object, other = {}
|
42
|
+
type.should! :be_in, Metadata::ATTRIBUTE_TYPES_SHORTCUTS
|
43
|
+
values = {
|
44
|
+
:name => name,
|
45
|
+
:ivname => name.to_iv,
|
46
|
+
:type => Metadata::ATTRIBUTE_TYPES_SHORTCUTS[type],
|
47
|
+
:initialize => NotDefined
|
48
|
+
}.merge(other)
|
49
|
+
attr = Attribute.new.set_with_check values
|
50
|
+
@meta.attributes[name] = attr
|
51
|
+
|
52
|
+
@klass._define_attribute attr
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ObjectModel
|
2
|
+
class Metadata
|
3
|
+
class Children < Hash
|
4
|
+
def initialize
|
5
|
+
super{should! :be_never_called}
|
6
|
+
end
|
7
|
+
|
8
|
+
def copy
|
9
|
+
c = Children.new
|
10
|
+
each{|n, m| c[n] = m.copy}
|
11
|
+
return c
|
12
|
+
end
|
13
|
+
|
14
|
+
def inherit parent
|
15
|
+
parent.copy.merge copy
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Child
|
20
|
+
include OpenConstructor
|
21
|
+
|
22
|
+
attr_accessor :name, :ivname, :title, :type, :parameters
|
23
|
+
|
24
|
+
def copy; clone end
|
25
|
+
end
|
26
|
+
|
27
|
+
definition[:children] = Object.new.singleton_class do
|
28
|
+
def initial_value klass; Children.new end
|
29
|
+
|
30
|
+
def copy children; children.copy end
|
31
|
+
|
32
|
+
def inherit pvalue, cvalue;
|
33
|
+
cvalue.inherit pvalue
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
attr_accessor :children
|
38
|
+
|
39
|
+
class DSL
|
40
|
+
def child name, type = :single, other = {}
|
41
|
+
type.should! :be_in, Metadata::CHILD_TYPES_SHORTCUTS
|
42
|
+
values = {:name => name, :ivname => name.to_iv, :type => Metadata::CHILD_TYPES_SHORTCUTS[type]}.merge(other)
|
43
|
+
child = Child.new.set_with_check values
|
44
|
+
@meta.children[name] = child
|
45
|
+
|
46
|
+
@klass._define_child child
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
module ObjectModel
|
2
|
+
class Metadata
|
3
|
+
class BaseEvents < Hash
|
4
|
+
def initialize
|
5
|
+
super{should! :be_never_called}
|
6
|
+
end
|
7
|
+
|
8
|
+
def copy
|
9
|
+
c = self.class.new
|
10
|
+
each{|n, m| c[n] = m.clone}
|
11
|
+
return c
|
12
|
+
end
|
13
|
+
|
14
|
+
def inherit parent
|
15
|
+
r = parent.copy
|
16
|
+
copy.each do |n, m|
|
17
|
+
if r.include? n
|
18
|
+
r[n] += m
|
19
|
+
else
|
20
|
+
r[n] = m
|
21
|
+
end
|
22
|
+
end
|
23
|
+
return r
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class BeforeEvents < BaseEvents
|
28
|
+
def fire entity, event_name, *params
|
29
|
+
event_name.should! :be_in, Metadata::BEFORE_EVENT_TYPES
|
30
|
+
if self.include? event_name
|
31
|
+
self[event_name].each{|event| event.fire entity, *params}
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class AfterEvents < BaseEvents
|
37
|
+
def fire entity, event_name, *params
|
38
|
+
event_name.should! :be_in, Metadata::AFTER_EVENT_TYPES
|
39
|
+
if self.include? event_name
|
40
|
+
self[event_name].each{|event| event.fire entity, *params}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Event
|
46
|
+
attr_reader :method, :block
|
47
|
+
|
48
|
+
def initialize method = nil, &block
|
49
|
+
if method
|
50
|
+
method.should! :be_a, Symbol
|
51
|
+
block.should! :be_nil
|
52
|
+
@method = method
|
53
|
+
elsif block
|
54
|
+
method.should! :be_nil
|
55
|
+
@block = block
|
56
|
+
else
|
57
|
+
should! :be_never_called
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def fire entity, *params
|
62
|
+
if @method
|
63
|
+
entity.send @method, *params
|
64
|
+
elsif @block
|
65
|
+
entity.instance_eval &@block
|
66
|
+
else
|
67
|
+
should! :be_never_called
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
definition[:before] = Object.new.singleton_class do
|
73
|
+
def initial_value klass; BeforeEvents.new end
|
74
|
+
|
75
|
+
def copy events; events.copy end
|
76
|
+
|
77
|
+
def inherit pvalue, cvalue;
|
78
|
+
cvalue.inherit pvalue
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
definition[:after] = Object.new.singleton_class do
|
83
|
+
def initial_value klass; AfterEvents.new end
|
84
|
+
|
85
|
+
def copy events; events.copy end
|
86
|
+
|
87
|
+
def inherit pvalue, cvalue;
|
88
|
+
cvalue.inherit pvalue
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
attr_accessor :before
|
93
|
+
attr_accessor :after
|
94
|
+
|
95
|
+
class DSL
|
96
|
+
def after name, method = nil, &block
|
97
|
+
name.should! :be_in, Metadata::AFTER_EVENT_TYPES
|
98
|
+
e = Event.new method, &block
|
99
|
+
@meta.after[name] = [e]
|
100
|
+
end
|
101
|
+
|
102
|
+
def before name, method = nil, &block
|
103
|
+
name.should! :be_in, Metadata::AFTER_EVENT_TYPES
|
104
|
+
e = Event.new method, &block
|
105
|
+
@meta.before[name] = [e]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|