vorpal 1.0.2 → 1.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 (62) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +73 -26
  3. data/lib/vorpal/aggregate_mapper.rb +13 -2
  4. data/lib/vorpal/aggregate_traversal.rb +9 -8
  5. data/lib/vorpal/config/association_config.rb +84 -0
  6. data/lib/vorpal/config/belongs_to_config.rb +35 -0
  7. data/lib/vorpal/config/class_config.rb +71 -0
  8. data/lib/vorpal/config/configs.rb +54 -0
  9. data/lib/vorpal/config/foreign_key_info.rb +23 -0
  10. data/lib/vorpal/config/has_many_config.rb +38 -0
  11. data/lib/vorpal/config/has_one_config.rb +35 -0
  12. data/lib/vorpal/config/main_config.rb +68 -0
  13. data/lib/vorpal/db_loader.rb +25 -22
  14. data/lib/vorpal/driver/postgresql.rb +42 -6
  15. data/lib/vorpal/dsl/config_builder.rb +26 -73
  16. data/lib/vorpal/dsl/configuration.rb +139 -42
  17. data/lib/vorpal/dsl/defaults_generator.rb +1 -1
  18. data/lib/vorpal/engine.rb +27 -13
  19. data/lib/vorpal/exceptions.rb +4 -0
  20. data/lib/vorpal/identity_map.rb +7 -2
  21. data/lib/vorpal/loaded_objects.rb +57 -14
  22. data/lib/vorpal/util/array_hash.rb +22 -8
  23. data/lib/vorpal/util/hash_initialization.rb +1 -1
  24. data/lib/vorpal/version.rb +1 -1
  25. data/vorpal.gemspec +4 -5
  26. metadata +18 -78
  27. data/.editorconfig +0 -13
  28. data/.envrc +0 -4
  29. data/.gitignore +0 -16
  30. data/.rspec +0 -1
  31. data/.ruby-version +0 -1
  32. data/.travis.yml +0 -18
  33. data/.yardopts +0 -1
  34. data/Appraisals +0 -18
  35. data/Gemfile +0 -4
  36. data/Rakefile +0 -39
  37. data/bin/appraisal +0 -29
  38. data/bin/rake +0 -29
  39. data/bin/rspec +0 -29
  40. data/docker-compose.yml +0 -19
  41. data/gemfiles/rails_5_1.gemfile +0 -11
  42. data/gemfiles/rails_5_1.gemfile.lock +0 -101
  43. data/gemfiles/rails_5_2.gemfile +0 -11
  44. data/gemfiles/rails_5_2.gemfile.lock +0 -101
  45. data/gemfiles/rails_6_0.gemfile +0 -9
  46. data/gemfiles/rails_6_0.gemfile.lock +0 -101
  47. data/lib/vorpal/configs.rb +0 -296
  48. data/spec/acceptance/vorpal/aggregate_mapper_spec.rb +0 -910
  49. data/spec/helpers/codecov_helper.rb +0 -7
  50. data/spec/helpers/db_helpers.rb +0 -69
  51. data/spec/helpers/profile_helpers.rb +0 -26
  52. data/spec/integration/vorpal/driver/postgresql_spec.rb +0 -42
  53. data/spec/integration_spec_helper.rb +0 -29
  54. data/spec/performance/vorpal/performance_spec.rb +0 -305
  55. data/spec/unit/vorpal/configs_spec.rb +0 -117
  56. data/spec/unit/vorpal/db_loader_spec.rb +0 -103
  57. data/spec/unit/vorpal/dsl/config_builder_spec.rb +0 -18
  58. data/spec/unit/vorpal/dsl/defaults_generator_spec.rb +0 -75
  59. data/spec/unit/vorpal/identity_map_spec.rb +0 -62
  60. data/spec/unit/vorpal/loaded_objects_spec.rb +0 -22
  61. data/spec/unit/vorpal/util/string_utils_spec.rb +0 -25
  62. data/spec/unit_spec_helper.rb +0 -1
@@ -1,7 +0,0 @@
1
- if ENV["TRAVIS"]
2
- require 'simplecov'
3
- SimpleCov.start
4
-
5
- require 'codecov'
6
- SimpleCov.formatter = SimpleCov::Formatter::Codecov
7
- end
@@ -1,69 +0,0 @@
1
- module DbHelpers
2
- module_function
3
-
4
- CONNECTION_SETTINGS = {
5
- adapter: 'postgresql',
6
- host: 'localhost',
7
- database: 'vorpal_test',
8
- min_messages: 'error',
9
- }
10
-
11
- if !ENV["TRAVIS"]
12
- # These settings need to agree with what is in the docker-compose.yml file
13
- CONNECTION_SETTINGS.merge!(
14
- port: 55433,
15
- username: 'vorpal',
16
- password: 'pass',
17
- )
18
- end
19
-
20
- def ensure_database_exists
21
- test_database_name = CONNECTION_SETTINGS.fetch(:database)
22
- if !db_exists?(test_database_name)
23
- db_connection.create_database(test_database_name)
24
- end
25
- end
26
-
27
- def db_exists?(db_name)
28
- ActiveRecord::Base.establish_connection(CONNECTION_SETTINGS.merge(database: 'template1'))
29
-
30
- return db_connection.exec_query("SELECT 1 from pg_database WHERE datname='#{db_name}';").present?
31
- end
32
-
33
- def db_connection
34
- ActiveRecord::Base.connection
35
- end
36
-
37
- def establish_connection
38
- ActiveRecord::Base.establish_connection(CONNECTION_SETTINGS)
39
- end
40
-
41
- # when you change a table's columns, set force to true to re-generate the table in the DB
42
- def define_table(table_name, columns, force)
43
- if table_name_is_free?(table_name) || force
44
- db_connection.create_table(table_name, force: true) do |t|
45
- columns.each do |name, type|
46
- t.send(type, name)
47
- end
48
- end
49
- end
50
- end
51
-
52
- def defineAr(table_name)
53
- Class.new(ActiveRecord::Base) do
54
- self.table_name = table_name
55
- end
56
- end
57
-
58
- private
59
-
60
- def table_name_is_free?(table_name)
61
- if (ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR == 1) ||
62
- (ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR == 2) ||
63
- (ActiveRecord::VERSION::MAJOR == 6 && ActiveRecord::VERSION::MINOR == 0)
64
- !db_connection.data_source_exists?(table_name)
65
- else
66
- raise "ActiveRecord Version #{ActiveRecord::VERSION::STRING} is not supported!"
67
- end
68
- end
69
- end
@@ -1,26 +0,0 @@
1
- require 'ruby-prof'
2
-
3
- # In order to use these helpers do the following:
4
- # 1) Add `spec.add_development_dependency "ruby-prof"` to the vorpal.gemspec file.
5
- # 2) Do a `bundle update`
6
- # 3) Add `require 'helpers/profile_helpers'` to the spec where you wish to profile.
7
- module ProfileHelpers
8
- module_function
9
-
10
- # Runs a block a given number of times and outputs the profiling results in a 'Call Tree'
11
- # format suitable for display by a tool like KCacheGrind.
12
- #
13
- # - Installing QCacheGrind on OSX: http://nickology.com/2014/04/16/view-xdebug-cachegrind-files-on-mac-os/
14
- def output_callgrind(description, times=1, &block)
15
- RubyProf.measure_mode = RubyProf::PROCESS_TIME
16
- RubyProf.start
17
-
18
- times.times(&block)
19
-
20
- result = RubyProf.stop
21
- printer = RubyProf::CallTreePrinter.new(result)
22
- File.open("#{description}_#{DateTime.now.strftime("%FT%H:%M:%S%z")}.callgrind", "w") do |file|
23
- printer.print(file)
24
- end
25
- end
26
- end
@@ -1,42 +0,0 @@
1
- require 'integration_spec_helper'
2
- require 'vorpal'
3
-
4
- describe Vorpal::Driver::Postgresql do
5
- describe '#build_db_class' do
6
- let(:db_class) { subject.build_db_class(PostgresDriverSpec::Foo, 'example') }
7
-
8
- it 'generates a valid class name so that rails auto-reloading works' do
9
- expect { Vorpal.const_defined?(db_class.name) }.to_not raise_error
10
- end
11
-
12
- it 'does not let the user access the generated class' do
13
- expect { Vorpal.const_get(db_class.name) }.to raise_error(NameError)
14
- end
15
-
16
- it 'isolates two POROs that map to the same db table' do
17
- db_class1 = build_db_class(PostgresDriverSpec::Foo)
18
- db_class2 = build_db_class(PostgresDriverSpec::Bar)
19
-
20
- expect(db_class1).to_not eq(db_class2)
21
- expect(db_class1.name).to_not eq(db_class2.name)
22
- end
23
-
24
- it 'uses the model class name to make the generated AR::Base class name unique' do
25
- db_class = build_db_class(PostgresDriverSpec::Foo)
26
-
27
- expect(db_class.name).to match("PostgresDriverSpec__Foo")
28
- end
29
- end
30
-
31
- private
32
-
33
- module PostgresDriverSpec
34
- class Foo; end
35
- class Bar; end
36
- end
37
-
38
- def build_db_class(clazz)
39
- db_driver = Vorpal::Driver::Postgresql.new
40
- db_driver.build_db_class(clazz, 'example')
41
- end
42
- end
@@ -1,29 +0,0 @@
1
- require 'active_record'
2
- require 'pg'
3
- require 'helpers/db_helpers'
4
- require 'helpers/codecov_helper'
5
- begin
6
- require 'activerecord-import/base'
7
- rescue LoadError
8
- puts "Not using activerecord-import!"
9
- end
10
-
11
-
12
- DbHelpers.ensure_database_exists
13
- DbHelpers.establish_connection
14
-
15
- RSpec.configure do |config|
16
- config.include DbHelpers
17
-
18
- # implements `use_transactional_fixtures = true`
19
- config.before(:each) do
20
- connection = ActiveRecord::Base.connection
21
- connection.begin_transaction(joinable: false)
22
- end
23
-
24
- config.after(:each) do
25
- connection = ActiveRecord::Base.connection
26
- connection.rollback_transaction if connection.transaction_open?
27
- ActiveRecord::Base.clear_active_connections!
28
- end
29
- end
@@ -1,305 +0,0 @@
1
- require 'integration_spec_helper'
2
- require 'vorpal'
3
- require 'virtus'
4
-
5
- module Performance
6
- describe 'performance' do
7
-
8
- class Bug
9
- include Virtus.model
10
-
11
- attribute :id, Integer
12
- attribute :name, String
13
- attribute :lives_on, Object
14
- end
15
-
16
- class Tree; end
17
-
18
- class Trunk
19
- include Virtus.model
20
-
21
- attribute :id, Integer
22
- attribute :length, Decimal
23
- attribute :bugs, Array[Bug]
24
- attribute :tree, Tree
25
- end
26
-
27
- class Branch
28
- include Virtus.model
29
-
30
- attribute :id, Integer
31
- attribute :length, Decimal
32
- attribute :tree, Tree
33
- attribute :branches, Array[Branch]
34
- attribute :bugs, Array[Bug]
35
-
36
- def add_branch(branch_options)
37
- branch = Branch.new(branch_options.merge(branch: self))
38
- branches << branch
39
- branch
40
- end
41
- end
42
-
43
- class Tree
44
- include Virtus.model
45
-
46
- attribute :id, Integer
47
- attribute :name, String
48
- attribute :trunk, Trunk
49
- attribute :branches, Array[Branch]
50
-
51
- def set_trunk(trunk)
52
- trunk.tree = self
53
- self.trunk = trunk
54
- end
55
-
56
- def add_branch(branch_options)
57
- branch = Branch.new(branch_options.merge(tree: self))
58
- branches << branch
59
- branch
60
- end
61
- end
62
-
63
- before(:all) do
64
- define_table('branches_perf', {length: :decimal, tree_id: :integer, branch_id: :integer}, false)
65
- define_table('bugs_perf', {name: :text, lives_on_id: :integer, lives_on_type: :string}, false)
66
- define_table('trees_perf', {name: :text, trunk_id: :integer}, false)
67
- define_table('trunks_perf', {length: :decimal}, false)
68
- end
69
-
70
- let(:tree_mapper) { build_mapper }
71
-
72
- # Vorpal 0.0.5:
73
- # user system total real
74
- # create 4.160000 0.440000 4.600000 ( 6.071752)
75
- # update 7.990000 0.730000 8.720000 ( 15.281017)
76
- # load 10.120000 0.730000 10.850000 ( 21.087785)
77
- # destroy 6.090000 0.620000 6.710000 ( 12.541420)
78
- #
79
- # Vorpal 0.0.6:
80
- # user system total real
81
- # create 0.990000 0.100000 1.090000 ( 1.415715)
82
- # update 2.240000 0.180000 2.420000 ( 2.745321)
83
- # load 2.130000 0.020000 2.150000 ( 2.223182)
84
- # destroy 0.930000 0.010000 0.940000 ( 1.038624)
85
- #
86
- # Vorpal 0.1.0:
87
- # user system total real
88
- # create 0.870000 0.100000 0.970000 ( 1.320534)
89
- # update 1.820000 0.210000 2.030000 ( 2.351518)
90
- # load 1.310000 0.010000 1.320000 ( 1.394192)
91
- # destroy 0.930000 0.010000 0.940000 ( 1.030910)
92
- #
93
- # Vorpal 1.0.0, Ruby 2.1.6, ActiveRecord 4.1.16, AR:Import 0.10.0
94
- # user system total real
95
- # create 0.980000 0.140000 1.120000 ( 1.671115)
96
- # update 2.030000 0.250000 2.280000 ( 2.748697)
97
- # load 1.230000 0.010000 1.240000 ( 1.395219)
98
- # destroy 0.830000 0.010000 0.840000 ( 1.042960)
99
- #
100
- # Vorpal 1.0.0, Ruby 2.3.3, ActiveRecord 4.1.16, AR:Import 0.10.0
101
- # user system total real
102
- # create 0.940000 0.120000 1.060000 ( 1.579334)
103
- # update 1.880000 0.250000 2.130000 ( 2.601979)
104
- # load 1.130000 0.010000 1.140000 ( 1.292817)
105
- # destroy 0.730000 0.000000 0.730000 ( 0.930980)
106
- #
107
- # Vorpal 1.0.0, Ruby 2.3.3, ActiveRecord 4.2.10, AR:Import 0.10.0
108
- # user system total real
109
- # create 1.230000 0.130000 1.360000 ( 1.864400)
110
- # update 2.660000 0.260000 2.920000 ( 3.416604)
111
- # load 1.310000 0.010000 1.320000 ( 1.479030)
112
- # destroy 0.840000 0.010000 0.850000 ( 1.037512)
113
- #
114
- # Vorpal 1.0.0, Ruby 2.3.3, ActiveRecord 5.0.7, AR:Import 0.13.0
115
- # user system total real
116
- # create 0.960000 0.120000 1.080000 ( 1.631415)
117
- # update 2.810000 0.270000 3.080000 ( 3.633569)
118
- # load 1.340000 0.010000 1.350000 ( 1.510898)
119
- # destroy 0.900000 0.010000 0.910000 ( 1.085288)
120
- #
121
- # Vorpal 1.0.0, Ruby 2.3.3, ActiveRecord 5.1.6, AR:Import 0.13.0
122
- # create 0.960000 0.120000 1.080000 ( 1.588142)
123
- # update 3.030000 0.290000 3.320000 ( 3.839557)
124
- # load 1.340000 0.010000 1.350000 ( 1.509182)
125
- # destroy 0.950000 0.010000 0.960000 ( 1.155866)
126
- #
127
- # Vorpal 1.0.0, Ruby 2.3.3, ActiveRecord 5.1.6, AR:Import 0.13.0
128
- # create 0.920000 0.120000 1.040000 ( 1.534410)
129
- # update 3.010000 0.290000 3.300000 ( 3.850101)
130
- # load 1.380000 0.010000 1.390000 ( 1.561047)
131
- # destroy 1.050000 0.010000 1.060000 ( 1.260379)
132
- #
133
- # Vorpal 1.0.1, Ruby 2.5.7, ActiveRecord 5.1.7, AR:Import 0.13.0, OSX
134
- # user system total real
135
- # create 0.865771 0.102388 0.968159 ( 1.525707)
136
- # update 2.644134 0.206294 2.850428 ( 3.318751)
137
- # load 1.246217 0.009570 1.255787 ( 1.416289)
138
- # destroy 0.743522 0.002833 0.746355 ( 0.951756)
139
- #
140
- # Vorpal 1.0.1, Ruby 2.5.7, ActiveRecord 5.1.7, AR:Import 0.13.0, Dockerized Test DB, OSX
141
- # user system total real
142
- # create 0.928937 0.132224 1.061161 ( 5.779951)
143
- # update 2.980097 0.266119 3.246216 ( 12.187891)
144
- # load 1.254854 0.010550 1.265404 ( 1.368346)
145
- # destroy 0.758912 0.003954 0.762866 ( 0.888106)
146
- #
147
- # Vorpal 1.0.1, Ruby 2.6.3, ActiveRecord 5.2.4.1, AR:Import 0.13.0, OSX
148
- # user system total real
149
- # create 0.732053 0.096794 0.828847 ( 1.301937)
150
- # update 2.041864 0.190059 2.231923 ( 2.717304)
151
- # load 1.067965 0.006396 1.074361 ( 1.244547)
152
- # destroy 0.685867 0.002530 0.688397 ( 0.910923)
153
- #
154
- # Vorpal 1.0.1, Ruby 2.6.3, ActiveRecord 5.2.4.1, AR:Import 0.13.0, Dockerized Test DB, OSX
155
- # user system total real
156
- # create 0.867153 0.144517 1.011670 ( 6.219567)
157
- # update 2.429280 0.268099 2.697379 ( 11.714242)
158
- # load 1.068408 0.005479 1.073887 ( 1.168998)
159
- # destroy 0.681347 0.002968 0.684315 ( 0.803671)
160
- #
161
- # Vorpal 1.0.1, Ruby 2.6.3, ActiveRecord 5.2.4.1, AR:Import 1.0.4, OSX
162
- # user system total real
163
- # create 0.640735 0.009528 0.650263 ( 0.778304)
164
- # update 2.051961 0.187531 2.239492 ( 2.752651)
165
- # load 1.127992 0.009353 1.137345 ( 1.323969)
166
- # destroy 0.694419 0.004167 0.698586 ( 0.928359)
167
- #
168
- # Vorpal 1.0.1, Ruby 2.6.3, ActiveRecord 5.2.4.1, AR:Import 1.0.4, Dockerized Test DB, OSX
169
- # user system total real
170
- # create 0.665585 0.009352 0.674937 ( 0.809183)
171
- # update 2.644085 0.299573 2.943658 ( 12.945297)
172
- # load 1.233911 0.009636 1.243547 ( 1.353933)
173
- # destroy 0.756727 0.004722 0.761449 ( 0.892230)
174
- #
175
- # Vorpal 1.0.1, Ruby 2.6.3, ActiveRecord 5.2.4.1, No AR:Import, OSX
176
- # user system total real
177
- # create 2.342875 0.299983 2.642858 ( 3.809430)
178
- # update 2.021266 0.181808 2.203074 ( 2.672334)
179
- # load 1.113677 0.008489 1.122166 ( 1.301392)
180
- # destroy 0.695616 0.002754 0.698370 ( 0.933155)
181
- #
182
- # Vorpal 1.0.1, Ruby 2.6.3, ActiveRecord 5.2.4.1, No AR:Import, Dockerized Test DB, OSX
183
- # user system total real
184
- # create 2.934016 0.397708 3.331724 ( 17.443961)
185
- # update 2.450073 0.262948 2.713021 ( 11.525552)
186
- # load 1.106541 0.009080 1.115621 ( 1.218981)
187
- # destroy 0.694103 0.003070 0.697173 ( 0.825317)
188
- #
189
- # Vorpal 1.0.1, Ruby 2.7.0, ActiveRecord 6.0.2, AR:Import 1.0.4, OSX
190
- # user system total real
191
- # create 0.637130 0.005220 0.642350 ( 0.725564)
192
- # update 1.488417 0.010347 1.498764 ( 1.685821)
193
- # load 1.209270 0.014584 1.223854 ( 1.443170)
194
- # destroy 0.692401 0.003984 0.696385 ( 0.926835)
195
- #
196
- # Vorpal 1.0.1, Ruby 2.7.0, ActiveRecord 6.0.2, AR:Import 1.0.4, Dockerized Test DB, OSX
197
- # user system total real
198
- # create 0.661741 0.008410 0.670151 ( 0.785426)
199
- # update 1.419727 0.005630 1.425357 ( 1.539234)
200
- # load 1.042127 0.006379 1.048506 ( 1.156116)
201
- # destroy 0.693851 0.003333 0.697184 ( 0.829565)
202
- #
203
- it 'benchmarks all operations' do
204
- trees = build_trees(1000)
205
- Benchmark.bm(7) do |x|
206
- x.report('create') { tree_mapper.persist(trees) }
207
- x.report('update') { tree_mapper.persist(trees) }
208
- x.report('load') { tree_mapper.query.where(id: trees.map(&:id)).load_many }
209
- x.report('destroy') { tree_mapper.destroy(trees) }
210
- end
211
- end
212
-
213
- # it 'creates aggregates quickly' do
214
- # trees = build_trees(1000)
215
- #
216
- # puts 'starting persistence benchmark'
217
- # puts Benchmark.measure {
218
- # tree_mapper.persist(trees)
219
- # }
220
- # end
221
- #
222
- # it 'updates aggregates quickly' do
223
- # trees = build_trees(1000)
224
- #
225
- # tree_mapper.persist(trees)
226
- #
227
- # puts 'starting update benchmark'
228
- # puts Benchmark.measure {
229
- # tree_mapper.persist(trees)
230
- # }
231
- # end
232
- #
233
- # it 'loads aggregates quickly' do
234
- # trees = build_trees(1000)
235
- # tree_mapper.persist(trees)
236
- # ids = trees.map(&:id)
237
- #
238
- # puts 'starting loading benchmark'
239
- # puts Benchmark.measure {
240
- # tree_mapper.query.where(id: ids).load_many
241
- # }
242
- # end
243
- #
244
- # it 'destroys aggregates quickly' do
245
- # trees = build_trees(1000)
246
- # tree_mapper.persist(trees)
247
- #
248
- # puts 'starting destruction benchmark'
249
- # puts Benchmark.measure {
250
- # tree_mapper.destroy(trees)
251
- # }
252
- # end
253
-
254
- def build_trees(count)
255
- (1..count).map do |i|
256
- tree = Tree.new
257
- trunk = Trunk.new(length: i)
258
- tree.set_trunk(trunk)
259
-
260
- branch1 = tree.add_branch(length: i * 10)
261
- branch2 = tree.add_branch(length: i * 20)
262
- branch2.add_branch(length: i * 30)
263
-
264
- build_bug(trunk)
265
- build_bug(branch1)
266
-
267
- tree
268
- end
269
- end
270
-
271
- def build_bug(bug_home)
272
- bug = Bug.new(lives_on: bug_home)
273
- bug_home.bugs = [bug]
274
- end
275
-
276
- def build_mapper
277
- engine = Vorpal.define do
278
- map Tree, table_name: "trees_perf" do
279
- attributes :name
280
- belongs_to :trunk
281
- has_many :branches
282
- end
283
-
284
- map Trunk, table_name: "trunks_perf" do
285
- attributes :length
286
- has_one :tree
287
- has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
288
- end
289
-
290
- map Branch, table_name: "branches_perf" do
291
- attributes :length
292
- belongs_to :tree
293
- has_many :bugs, fk: :lives_on_id, fk_type: :lives_on_type
294
- has_many :branches
295
- end
296
-
297
- map Bug, table_name: "bugs_perf" do
298
- attributes :name
299
- belongs_to :lives_on, fk: :lives_on_id, fk_type: :lives_on_type, child_classes: [Trunk, Branch]
300
- end
301
- end
302
- engine.mapper_for(Tree)
303
- end
304
- end
305
- end