praxis-mapper 3.1.1
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 +7 -0
- data/.gitignore +26 -0
- data/.rspec +3 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +83 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +102 -0
- data/Guardfile +11 -0
- data/LICENSE +22 -0
- data/README.md +19 -0
- data/Rakefile +14 -0
- data/lib/praxis-mapper/config_hash.rb +40 -0
- data/lib/praxis-mapper/connection_manager.rb +102 -0
- data/lib/praxis-mapper/finalizable.rb +38 -0
- data/lib/praxis-mapper/identity_map.rb +532 -0
- data/lib/praxis-mapper/logging.rb +22 -0
- data/lib/praxis-mapper/model.rb +430 -0
- data/lib/praxis-mapper/query/base.rb +213 -0
- data/lib/praxis-mapper/query/sql.rb +183 -0
- data/lib/praxis-mapper/query_statistics.rb +46 -0
- data/lib/praxis-mapper/resource.rb +226 -0
- data/lib/praxis-mapper/support/factory_girl.rb +104 -0
- data/lib/praxis-mapper/support/memory_query.rb +34 -0
- data/lib/praxis-mapper/support/memory_repository.rb +44 -0
- data/lib/praxis-mapper/support/schema_dumper.rb +66 -0
- data/lib/praxis-mapper/support/schema_loader.rb +56 -0
- data/lib/praxis-mapper/support.rb +2 -0
- data/lib/praxis-mapper/version.rb +5 -0
- data/lib/praxis-mapper.rb +60 -0
- data/praxis-mapper.gemspec +38 -0
- data/spec/praxis-mapper/connection_manager_spec.rb +117 -0
- data/spec/praxis-mapper/identity_map_spec.rb +905 -0
- data/spec/praxis-mapper/logging_spec.rb +9 -0
- data/spec/praxis-mapper/memory_repository_spec.rb +56 -0
- data/spec/praxis-mapper/model_spec.rb +389 -0
- data/spec/praxis-mapper/query/base_spec.rb +317 -0
- data/spec/praxis-mapper/query/sql_spec.rb +184 -0
- data/spec/praxis-mapper/resource_spec.rb +154 -0
- data/spec/praxis_mapper_spec.rb +21 -0
- data/spec/spec_fixtures.rb +12 -0
- data/spec/spec_helper.rb +63 -0
- data/spec/support/spec_models.rb +215 -0
- data/spec/support/spec_resources.rb +39 -0
- metadata +298 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
|
3
|
+
Sequel.extension :migration
|
4
|
+
|
5
|
+
module Praxis::Mapper
|
6
|
+
module Support
|
7
|
+
class SchemaLoader
|
8
|
+
|
9
|
+
attr_reader :options, :schema_root
|
10
|
+
|
11
|
+
def initialize(schema_root='.', **options)
|
12
|
+
@schema_root = Pathname.new(schema_root)
|
13
|
+
@options = options
|
14
|
+
@connection_manager = ConnectionManager.new
|
15
|
+
@repositories = Set.new
|
16
|
+
|
17
|
+
@migrations = Hash.new
|
18
|
+
|
19
|
+
@connection_manager.repositories.each do |repository_name, config|
|
20
|
+
|
21
|
+
next unless config[:query] == Praxis::Mapper::Query::Sql
|
22
|
+
|
23
|
+
migration_path = @schema_root + repository_name.to_s
|
24
|
+
|
25
|
+
migration_path.children.each do |file|
|
26
|
+
table = file.basename.to_s[0..-4]
|
27
|
+
|
28
|
+
before = Sequel::Migration.descendants.clone
|
29
|
+
require file.expand_path if file.exist?
|
30
|
+
|
31
|
+
after = Sequel::Migration.descendants
|
32
|
+
|
33
|
+
migration = (after - before).first
|
34
|
+
|
35
|
+
@migrations[repository_name] ||= Array.new
|
36
|
+
@migrations[repository_name] << [table, migration]
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def load!
|
44
|
+
@migrations.each do |repository_name, migrations|
|
45
|
+
connection = @connection_manager.checkout(repository_name)
|
46
|
+
|
47
|
+
migrations.each do |(table, migration)|
|
48
|
+
migration.apply(connection, :up)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'yaml'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
require 'sequel'
|
6
|
+
|
7
|
+
module Praxis
|
8
|
+
module Mapper
|
9
|
+
|
10
|
+
# Get the logger configured for Praxis::Mapper
|
11
|
+
#
|
12
|
+
# @example Basic usage
|
13
|
+
# Praxis::Mapper.logger.info 'Something interesting happened'
|
14
|
+
#
|
15
|
+
# @return [Logger] The currently configured logger or a STDOUT logger
|
16
|
+
#
|
17
|
+
def self.logger
|
18
|
+
@logger ||= begin
|
19
|
+
require 'logger'
|
20
|
+
Logger.new(STDOUT)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Set the logger configured for Praxis::Mapper
|
25
|
+
#
|
26
|
+
# @example Basic usage
|
27
|
+
# Praxis::Mapper.logger = Logger.new('log/development.log')
|
28
|
+
#
|
29
|
+
# @return [Logger] The logger object
|
30
|
+
#
|
31
|
+
def self.logger=(logger)
|
32
|
+
@logger = logger
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# Perform any final initialiation needed
|
37
|
+
def self.finalize!
|
38
|
+
Praxis::Mapper::Model.finalize!
|
39
|
+
Praxis::Mapper::Resource.finalize!
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
require 'praxis-mapper/finalizable'
|
46
|
+
require 'praxis-mapper/logging'
|
47
|
+
|
48
|
+
require 'praxis-mapper/identity_map'
|
49
|
+
|
50
|
+
require 'praxis-mapper/model'
|
51
|
+
require 'praxis-mapper/query_statistics'
|
52
|
+
require 'praxis-mapper/connection_manager'
|
53
|
+
|
54
|
+
require 'praxis-mapper/resource'
|
55
|
+
|
56
|
+
require 'praxis-mapper/query/base'
|
57
|
+
require 'praxis-mapper/query/sql'
|
58
|
+
|
59
|
+
|
60
|
+
require 'praxis-mapper/config_hash'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
lib = File.expand_path('../lib', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
|
4
|
+
require 'praxis-mapper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "praxis-mapper"
|
8
|
+
spec.version = Praxis::Mapper::VERSION
|
9
|
+
spec.authors = ["Josep M. Blanquer","Dane Jensen"]
|
10
|
+
spec.date = "2014-08-18"
|
11
|
+
spec.summary = %q{A multi-datastore library designed for efficiency in loading large datasets.}
|
12
|
+
spec.email = ["blanquer@gmail.com","dane.jensen@gmail.com"]
|
13
|
+
|
14
|
+
spec.homepage = "https://github.com/rightscale/praxis-mapper"
|
15
|
+
spec.license = "MIT"
|
16
|
+
spec.required_ruby_version = ">=2.1"
|
17
|
+
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
spec.files = `git ls-files -z`.split("\x0")
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
|
22
|
+
spec.add_runtime_dependency(%q<randexp>, ["~> 0"])
|
23
|
+
spec.add_runtime_dependency(%q<sequel>, ["~> 4"])
|
24
|
+
spec.add_runtime_dependency(%q<activesupport>, ["~> 4"])
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
27
|
+
spec.add_development_dependency "rake", "~> 0"
|
28
|
+
|
29
|
+
spec.add_development_dependency(%q<redcarpet>, ["< 3.0"])
|
30
|
+
spec.add_development_dependency(%q<yard>, ["~> 0.8.7"])
|
31
|
+
spec.add_development_dependency(%q<guard>, ["~> 2"])
|
32
|
+
spec.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
33
|
+
spec.add_development_dependency(%q<rspec>, ["< 2.99"])
|
34
|
+
spec.add_development_dependency(%q<pry>, ["~> 0"])
|
35
|
+
spec.add_development_dependency(%q<pry-byebug>, ["~> 1"])
|
36
|
+
spec.add_development_dependency(%q<pry-stack_explorer>, ["~> 0"])
|
37
|
+
spec.add_development_dependency(%q<fuubar>, ["~> 1"])
|
38
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
+
|
3
|
+
class DummyFactory
|
4
|
+
def initialize(opts)
|
5
|
+
@opts = opts
|
6
|
+
end
|
7
|
+
|
8
|
+
def opts
|
9
|
+
@opts
|
10
|
+
end
|
11
|
+
|
12
|
+
def checkout
|
13
|
+
end
|
14
|
+
|
15
|
+
def release(connection)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
describe Praxis::Mapper::ConnectionManager do
|
22
|
+
let(:mock_connection) { double("connection") }
|
23
|
+
|
24
|
+
let(:default_hash) { Hash.new }
|
25
|
+
let(:factory_opts) { {:foo => "bar"} }
|
26
|
+
let(:config) { {:dummy => {:connection_factory => "DummyFactory", :connection_opts => factory_opts}} }
|
27
|
+
|
28
|
+
let(:dummy_factory_mock) { double("dummy_factory")}
|
29
|
+
|
30
|
+
subject { Praxis::Mapper::ConnectionManager }
|
31
|
+
|
32
|
+
before do
|
33
|
+
Praxis::Mapper::ConnectionManager.setup(config)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has a :dummy repository' do
|
37
|
+
repository = subject.repository(:dummy)
|
38
|
+
|
39
|
+
repository[:connection_factory].should be_kind_of(DummyFactory)
|
40
|
+
repository[:connection_factory].opts.should == factory_opts
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with repositories specified in a block for setup" do
|
44
|
+
let(:dummy_connection) { double("dummy connection")}
|
45
|
+
|
46
|
+
before do
|
47
|
+
opts = factory_opts
|
48
|
+
|
49
|
+
block = Proc.new { mock_connection }
|
50
|
+
Praxis::Mapper::ConnectionManager.setup do
|
51
|
+
repository :foo, &block
|
52
|
+
repository :bar, :connection_factory => "DummyFactory", :connection_opts => opts
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'supports proc-based repostories' do
|
57
|
+
subject.repository(:foo)[:connection_factory].should be_kind_of(Proc)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'supports config-based repositories' do
|
61
|
+
subject.repository(:bar)[:connection_factory].should be_kind_of(DummyFactory)
|
62
|
+
subject.repository(:bar)[:connection_factory].opts.should == factory_opts
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'getting connections' do
|
66
|
+
|
67
|
+
subject { Praxis::Mapper::ConnectionManager.new }
|
68
|
+
|
69
|
+
it 'gets connections from proc-based repositories' do
|
70
|
+
subject.checkout(:foo).should == mock_connection
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'gets connections from config-based repositories' do
|
74
|
+
DummyFactory.any_instance.should_receive(:checkout).and_return(dummy_connection)
|
75
|
+
subject.checkout(:bar).should == dummy_connection
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'releasing connections' do
|
81
|
+
subject { Praxis::Mapper::ConnectionManager.new }
|
82
|
+
|
83
|
+
it 'releases connections from config-based repositories' do
|
84
|
+
|
85
|
+
DummyFactory.any_instance.should_receive(:checkout).exactly(2).times.and_return(dummy_connection)
|
86
|
+
DummyFactory.any_instance.should_receive(:release).with(dummy_connection).and_return(true)
|
87
|
+
|
88
|
+
subject.checkout(:bar)
|
89
|
+
subject.checkout(:bar)
|
90
|
+
|
91
|
+
subject.release(:bar)
|
92
|
+
|
93
|
+
subject.checkout(:bar)
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'releases connections from proc-based repositories' do
|
97
|
+
subject.checkout(:foo)
|
98
|
+
subject.release(:foo)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'releases all connections' do
|
102
|
+
DummyFactory.any_instance.should_receive(:checkout).exactly(1).times.and_return(dummy_connection)
|
103
|
+
DummyFactory.any_instance.should_receive(:release).with(dummy_connection).and_return(true)
|
104
|
+
|
105
|
+
subject.checkout(:bar)
|
106
|
+
|
107
|
+
subject.should_not_receive(:release_one).with(:foo).and_call_original
|
108
|
+
subject.should_receive(:release_one).with(:bar).and_call_original
|
109
|
+
|
110
|
+
subject.release
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|