ObjectModel 0.3.0

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.
Files changed (90) hide show
  1. data/README +849 -0
  2. data/lib/ObjectModel.res/config.yaml +5 -0
  3. data/lib/ObjectModel/AnEntity/BackReferences.rb +113 -0
  4. data/lib/ObjectModel/AnEntity/Bag.rb +129 -0
  5. data/lib/ObjectModel/AnEntity/BagCopy.rb +29 -0
  6. data/lib/ObjectModel/AnEntity/ChildrenBag.rb +10 -0
  7. data/lib/ObjectModel/AnEntity/EntityCopy.rb +38 -0
  8. data/lib/ObjectModel/AnEntity/EntityType.rb +408 -0
  9. data/lib/ObjectModel/AnEntity/ReferencesBag.rb +10 -0
  10. data/lib/ObjectModel/AnEntity/entity_cm.rb +108 -0
  11. data/lib/ObjectModel/Entity.rb +278 -0
  12. data/lib/ObjectModel/Errors/LoadError.rb +3 -0
  13. data/lib/ObjectModel/Errors/NoTransactionError.rb +3 -0
  14. data/lib/ObjectModel/Errors/NotFoundError.rb +2 -0
  15. data/lib/ObjectModel/Errors/OutdatedError.rb +8 -0
  16. data/lib/ObjectModel/Errors/ValidationError.rb +3 -0
  17. data/lib/ObjectModel/Indexes/HashIndex.rb +64 -0
  18. data/lib/ObjectModel/Indexes/IndexStorage.rb +64 -0
  19. data/lib/ObjectModel/Indexes/Manager.rb +72 -0
  20. data/lib/ObjectModel/Metadata.rb +34 -0
  21. data/lib/ObjectModel/Metadata.res/after_event_types.rb +25 -0
  22. data/lib/ObjectModel/Metadata.res/attribute_types_shortcuts.rb +10 -0
  23. data/lib/ObjectModel/Metadata.res/before_event_types.rb +25 -0
  24. data/lib/ObjectModel/Metadata.res/child_types_shortcuts.rb +4 -0
  25. data/lib/ObjectModel/Metadata.res/metadata_checks.rb +9 -0
  26. data/lib/ObjectModel/Metadata.res/reference_types_shortcuts.rb +4 -0
  27. data/lib/ObjectModel/Metadata/DSL.rb +11 -0
  28. data/lib/ObjectModel/Metadata/attribute.rb +56 -0
  29. data/lib/ObjectModel/Metadata/child.rb +50 -0
  30. data/lib/ObjectModel/Metadata/events.rb +109 -0
  31. data/lib/ObjectModel/Metadata/name.rb +20 -0
  32. data/lib/ObjectModel/Metadata/reference.rb +50 -0
  33. data/lib/ObjectModel/Metadata/require.rb +10 -0
  34. data/lib/ObjectModel/Metadata/validate.rb +66 -0
  35. data/lib/ObjectModel/Repository.rb +326 -0
  36. data/lib/ObjectModel/Repository/EventProcessor.rb +58 -0
  37. data/lib/ObjectModel/Repository/ObjectStorage.rb +102 -0
  38. data/lib/ObjectModel/Repository/StreamID.rb +20 -0
  39. data/lib/ObjectModel/Repository/StreamStorage.rb +121 -0
  40. data/lib/ObjectModel/Repository/SystemListener.rb +143 -0
  41. data/lib/ObjectModel/Repository/Transaction.rb +63 -0
  42. data/lib/ObjectModel/Repository/TransactionProcessor.rb +36 -0
  43. data/lib/ObjectModel/Tools/DefaultTransactionStrategy.rb +9 -0
  44. data/lib/ObjectModel/Tools/InMemoryCache.rb +9 -0
  45. data/lib/ObjectModel/Tools/NoCache.rb +18 -0
  46. data/lib/ObjectModel/Tools/OGLRUCache.rb +37 -0
  47. data/lib/ObjectModel/Types/BagType.rb +94 -0
  48. data/lib/ObjectModel/Types/BooleanType.rb +42 -0
  49. data/lib/ObjectModel/Types/ClassType.rb +43 -0
  50. data/lib/ObjectModel/Types/DataType.rb +44 -0
  51. data/lib/ObjectModel/Types/DateType.rb +43 -0
  52. data/lib/ObjectModel/Types/NumberType.rb +62 -0
  53. data/lib/ObjectModel/Types/ObjectType.rb +164 -0
  54. data/lib/ObjectModel/Types/ProcType.rb +43 -0
  55. data/lib/ObjectModel/Types/SingleType.rb +59 -0
  56. data/lib/ObjectModel/Types/StringType.rb +39 -0
  57. data/lib/ObjectModel/_require.rb +43 -0
  58. data/lib/ObjectModel/require.rb +1 -0
  59. data/rakefile +62 -0
  60. data/spec/ObjectModel/BasicSpec/BaseClass.rb +7 -0
  61. data/spec/ObjectModel/BasicSpec/BaseTypes.rb +11 -0
  62. data/spec/ObjectModel/BasicSpec/Descendant.rb +5 -0
  63. data/spec/ObjectModel/BasicSpec/EachTest.rb +14 -0
  64. data/spec/ObjectModel/BasicSpec/UpChild.rb +10 -0
  65. data/spec/ObjectModel/BasicSpec/UpParent.rb +11 -0
  66. data/spec/ObjectModel/ErrorsSpec/AfterCommitError.rb +9 -0
  67. data/spec/ObjectModel/ExtendedSpec/CustomInitialization.rb +11 -0
  68. data/spec/ObjectModel/ExtendedSpec/UpNotNil.rb +8 -0
  69. data/spec/ObjectModel/ExtendedSpec/UpParent.rb +11 -0
  70. data/spec/ObjectModel/ValidationSpec/BaseTypes.rb +11 -0
  71. data/spec/aspect_spec.rb +55 -0
  72. data/spec/back_references_spec.rb +161 -0
  73. data/spec/basic_spec.rb +162 -0
  74. data/spec/cascade_delete_spec.rb +168 -0
  75. data/spec/complex_events_spec.rb +134 -0
  76. data/spec/concurrency_spec.rb +186 -0
  77. data/spec/containment_spec.rb +146 -0
  78. data/spec/data_migration_spec.rb +51 -0
  79. data/spec/errors_spec.rb +65 -0
  80. data/spec/events_spec.rb +173 -0
  81. data/spec/extended_spec.rb +171 -0
  82. data/spec/indexing_spec.rb +56 -0
  83. data/spec/set_in_memory.rb +2 -0
  84. data/spec/set_no_cache.rb +2 -0
  85. data/spec/smoke_test_spec.rb +85 -0
  86. data/spec/stream_spec.rb +143 -0
  87. data/spec/stream_storage.rb +148 -0
  88. data/spec/timer.rb +5 -0
  89. data/spec/validation_spec.rb +87 -0
  90. 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,10 @@
1
+ {
2
+ :string => Types::StringType,
3
+ :number => Types::NumberType,
4
+ :boolean => Types::BooleanType,
5
+ :object => Types::ObjectType,
6
+ :date => Types::DateType,
7
+ :data => Types::DataType,
8
+ :proc => Types::ProcType,
9
+ :class => Types::ClassType,
10
+ }
@@ -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,4 @@
1
+ {
2
+ :bag => Types::BagType,
3
+ :single => Types::SingleType,
4
+ }
@@ -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,4 @@
1
+ {
2
+ :bag => Types::BagType,
3
+ :single => Types::SingleType,
4
+ }
@@ -0,0 +1,11 @@
1
+ class DSL
2
+ def initialize klass, &block
3
+ @klass = klass
4
+ @meta = Metadata.new klass
5
+ @klass.self_meta = @meta
6
+ self.instance_eval &block
7
+
8
+ full_meta = klass.meta
9
+ Metadata["metadata_checks.rb"].each{|check| check.call klass, full_meta}
10
+ end
11
+ end
@@ -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