ObjectModel 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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