rmodel 0.4.0.dev → 1.0.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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -0
- data/.travis.yml +4 -3
- data/README.md +119 -153
- data/Rakefile +1 -2
- data/examples/mongo_embedded.rb +27 -21
- data/examples/scopes.rb +28 -0
- data/examples/sql_repository.rb +14 -26
- data/examples/timestamps.rb +7 -10
- data/examples/webapp/models/task.rb +9 -0
- data/examples/webapp/repositories/task_repository.rb +14 -0
- data/examples/webapp/server.rb +25 -0
- data/examples/webapp/support/mappers.rb +11 -0
- data/examples/webapp/support/repositories.rb +12 -0
- data/examples/webapp/support/sources.rb +13 -0
- data/examples/webapp/views/index.erb +20 -0
- data/lib/rmodel.rb +11 -8
- data/lib/rmodel/array_mapper.rb +23 -0
- data/lib/rmodel/base_mapper.rb +56 -0
- data/lib/rmodel/dummy_mapper.rb +15 -0
- data/lib/rmodel/mongo/mapper.rb +11 -0
- data/lib/rmodel/mongo/source.rb +50 -0
- data/lib/rmodel/repository.rb +36 -0
- data/lib/rmodel/repository_ext/scopable.rb +44 -0
- data/lib/rmodel/repository_ext/sugarable.rb +35 -0
- data/lib/rmodel/repository_ext/timestampable.rb +29 -0
- data/lib/rmodel/scope.rb +31 -0
- data/lib/rmodel/sequel/mapper.rb +6 -0
- data/lib/rmodel/sequel/source.rb +43 -0
- data/lib/rmodel/uni_hash.rb +16 -0
- data/lib/rmodel/version.rb +1 -1
- data/rmodel.gemspec +9 -3
- data/spec/rmodel/array_mapper_spec.rb +43 -0
- data/spec/rmodel/mongo/mapper_spec.rb +154 -0
- data/spec/rmodel/mongo/repository_spec.rb +16 -37
- data/spec/rmodel/mongo/source_spec.rb +113 -0
- data/spec/rmodel/sequel/mapper_spec.rb +57 -0
- data/spec/rmodel/sequel/repository_spec.rb +27 -38
- data/spec/rmodel/sequel/source_spec.rb +121 -0
- data/spec/shared/base_mapper.rb +39 -0
- data/spec/shared/clean_moped.rb +6 -2
- data/spec/shared/clean_sequel.rb +1 -1
- data/spec/shared/{repository_ext → repository}/crud.rb +20 -14
- data/spec/shared/repository/initialization.rb +39 -0
- data/spec/shared/repository/scopable.rb +137 -0
- data/spec/shared/repository/sugarable.rb +67 -0
- data/spec/shared/repository/timestampable.rb +137 -0
- data/spec/spec_helper.rb +17 -18
- metadata +120 -54
- data/examples/advanced_creation_of_repository.rb +0 -15
- data/examples/user.rb +0 -48
- data/lib/rmodel/base/repository.rb +0 -12
- data/lib/rmodel/base/repository_ext/sugarable.rb +0 -17
- data/lib/rmodel/base/repository_ext/timestampable.rb +0 -19
- data/lib/rmodel/mongo/repository.rb +0 -62
- data/lib/rmodel/mongo/repository_ext/query.rb +0 -34
- data/lib/rmodel/mongo/repository_ext/queryable.rb +0 -34
- data/lib/rmodel/mongo/setup.rb +0 -17
- data/lib/rmodel/mongo/simple_factory.rb +0 -78
- data/lib/rmodel/sequel/repository.rb +0 -61
- data/lib/rmodel/sequel/repository_ext/query.rb +0 -34
- data/lib/rmodel/sequel/repository_ext/queryable.rb +0 -30
- data/lib/rmodel/sequel/setup.rb +0 -12
- data/lib/rmodel/sequel/simple_factory.rb +0 -28
- data/lib/rmodel/setup.rb +0 -34
- data/spec/rmodel/mongo/repository_ext/queryable_spec.rb +0 -103
- data/spec/rmodel/mongo/repository_initialize_spec.rb +0 -174
- data/spec/rmodel/mongo/simple_factory_spec.rb +0 -195
- data/spec/rmodel/sequel/repository_ext/queryable_spec.rb +0 -114
- data/spec/rmodel/sequel/repository_initialize_spec.rb +0 -118
- data/spec/rmodel/sequel/simple_factory_spec.rb +0 -55
- data/spec/rmodel/setup_spec.rb +0 -54
- data/spec/shared/repository_ext/sugarable.rb +0 -44
- data/spec/shared/repository_ext/timestampable.rb +0 -67
@@ -1,19 +0,0 @@
|
|
1
|
-
module Rmodel::Base
|
2
|
-
module RepositoryExt
|
3
|
-
module Timestampable
|
4
|
-
def insert(object)
|
5
|
-
if object.respond_to?(:created_at) && object.respond_to?(:created_at=)
|
6
|
-
object.created_at ||= Time.now
|
7
|
-
end
|
8
|
-
super
|
9
|
-
end
|
10
|
-
|
11
|
-
def update(object)
|
12
|
-
if object.respond_to?(:updated_at) && object.respond_to?(:updated_at=)
|
13
|
-
object.updated_at = Time.now
|
14
|
-
end
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require 'mongo'
|
2
|
-
require 'rmodel/base/repository'
|
3
|
-
require 'active_support/inflector'
|
4
|
-
require 'rmodel/mongo/repository_ext/queryable'
|
5
|
-
|
6
|
-
module Rmodel::Mongo
|
7
|
-
class Repository < Rmodel::Base::Repository
|
8
|
-
include RepositoryExt::Queryable
|
9
|
-
|
10
|
-
def initialize(client = nil, collection = nil, factory = nil)
|
11
|
-
@client = client || Rmodel.setup.establish_mongo_client(self.class.client_name || :default) or
|
12
|
-
raise ArgumentError.new('Client driver is not setup')
|
13
|
-
|
14
|
-
@collection = collection || self.class.setting_collection ||
|
15
|
-
self.class.collection_by_convention or
|
16
|
-
raise ArgumentError.new('Collection can not be guessed')
|
17
|
-
|
18
|
-
@factory = factory || self.class.setting_factory or
|
19
|
-
raise ArgumentError.new('Factory can not be guessed')
|
20
|
-
end
|
21
|
-
|
22
|
-
def find(id)
|
23
|
-
result = @client[@collection].find(_id: id).first
|
24
|
-
result && @factory.fromHash(result)
|
25
|
-
end
|
26
|
-
|
27
|
-
def insert(object)
|
28
|
-
object.id ||= BSON::ObjectId.new
|
29
|
-
@client[@collection].insert_one(@factory.toHash(object, true))
|
30
|
-
end
|
31
|
-
|
32
|
-
def update(object)
|
33
|
-
@client[@collection].find(_id: object.id).update_one(@factory.toHash(object, false))
|
34
|
-
end
|
35
|
-
|
36
|
-
def remove(object)
|
37
|
-
@client[@collection].find(_id: object.id).delete_one
|
38
|
-
end
|
39
|
-
|
40
|
-
class << self
|
41
|
-
attr_reader :client_name, :setting_collection, :setting_factory
|
42
|
-
|
43
|
-
def client(name)
|
44
|
-
@client_name = name
|
45
|
-
end
|
46
|
-
|
47
|
-
def collection(name)
|
48
|
-
@setting_collection = name
|
49
|
-
end
|
50
|
-
|
51
|
-
def collection_by_convention
|
52
|
-
if name =~ /(.*)Repository$/
|
53
|
-
ActiveSupport::Inflector.tableize($1).to_sym
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def simple_factory(klass, *attributes, &block)
|
58
|
-
@setting_factory = SimpleFactory.new(klass, *attributes, &block)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'origin'
|
2
|
-
|
3
|
-
module Rmodel::Mongo
|
4
|
-
module RepositoryExt
|
5
|
-
class Query
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
class Queryable
|
9
|
-
include Origin::Queryable
|
10
|
-
end
|
11
|
-
|
12
|
-
def initialize(repo, queryable = nil)
|
13
|
-
@repo = repo
|
14
|
-
@queryable = queryable || Queryable.new
|
15
|
-
end
|
16
|
-
|
17
|
-
def each(&block)
|
18
|
-
@repo.find_by_query(@queryable.selector, @queryable.options).each(&block)
|
19
|
-
self
|
20
|
-
end
|
21
|
-
|
22
|
-
def remove
|
23
|
-
@repo.execute_query(@queryable.selector, @queryable.options).delete_many
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.define_scope(name, &block)
|
27
|
-
define_method name do |*args|
|
28
|
-
new_queryable = @queryable.instance_exec(*args, &block)
|
29
|
-
self.class.new(@repo, new_queryable)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'rmodel/mongo/repository_ext/query'
|
2
|
-
|
3
|
-
module Rmodel::Mongo
|
4
|
-
module RepositoryExt
|
5
|
-
module Queryable
|
6
|
-
def self.included(base)
|
7
|
-
base.extend ClassMethods
|
8
|
-
end
|
9
|
-
|
10
|
-
def query
|
11
|
-
(self.class.query_klass ||= Class.new(Query)).new(self)
|
12
|
-
end
|
13
|
-
|
14
|
-
def find_by_query(selector, options)
|
15
|
-
execute_query(selector, options).map do |hash|
|
16
|
-
@factory.fromHash(hash)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def execute_query(selector, options)
|
21
|
-
@client[@collection].find(selector, options)
|
22
|
-
end
|
23
|
-
|
24
|
-
module ClassMethods
|
25
|
-
attr_accessor :query_klass
|
26
|
-
|
27
|
-
def scope(name, &block)
|
28
|
-
self.query_klass ||= Class.new(Query)
|
29
|
-
self.query_klass.define_scope(name, &block)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/lib/rmodel/mongo/setup.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module Rmodel::Mongo
|
2
|
-
module Setup
|
3
|
-
def establish_mongo_client(name)
|
4
|
-
config = @clients_config[name]
|
5
|
-
if config
|
6
|
-
options = config.dup
|
7
|
-
options.delete :hosts
|
8
|
-
|
9
|
-
establish_client(name) { Mongo::Client.new(config[:hosts], options) }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
class Rmodel::Setup
|
16
|
-
include Rmodel::Mongo::Setup
|
17
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
module Rmodel::Mongo
|
2
|
-
class SimpleFactory
|
3
|
-
def initialize(klass, *attributes, &block)
|
4
|
-
@klass = klass
|
5
|
-
@attributes = attributes
|
6
|
-
@embeds_many = {}
|
7
|
-
@embeds_one = {}
|
8
|
-
instance_eval(&block) if block
|
9
|
-
end
|
10
|
-
|
11
|
-
def fromHash(hash)
|
12
|
-
object = @klass.new
|
13
|
-
object.id = hash['_id']
|
14
|
-
@attributes.each do |attribute|
|
15
|
-
object.public_send "#{attribute}=", hash[attribute.to_s]
|
16
|
-
end
|
17
|
-
@embeds_many.each do |attribute, factory|
|
18
|
-
if hash[attribute.to_s]
|
19
|
-
object.public_send "#{attribute}=", []
|
20
|
-
hash[attribute.to_s].each do |sub_hash|
|
21
|
-
object.public_send(attribute) << factory.fromHash(sub_hash)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
@embeds_one.each do |attribute, factory|
|
26
|
-
sub_hash = hash[attribute.to_s]
|
27
|
-
if sub_hash
|
28
|
-
object.public_send "#{attribute}=", factory.fromHash(sub_hash)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
object
|
32
|
-
end
|
33
|
-
|
34
|
-
def toHash(object, id_included)
|
35
|
-
hash = {}
|
36
|
-
@attributes.each do |attribute|
|
37
|
-
hash[attribute.to_s] = object.public_send(attribute)
|
38
|
-
end
|
39
|
-
if id_included
|
40
|
-
hash['_id'] = object.id
|
41
|
-
end
|
42
|
-
@embeds_many.each do |attribute, factory|
|
43
|
-
hash[attribute.to_s] = []
|
44
|
-
sub_objects = object.public_send(attribute)
|
45
|
-
if sub_objects
|
46
|
-
sub_objects.each do |sub_object|
|
47
|
-
sub_object.id ||= BSON::ObjectId.new
|
48
|
-
hash[attribute.to_s] << factory.toHash(sub_object, true)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
@embeds_one.each do |attribute, factory|
|
53
|
-
sub_object = object.public_send(attribute)
|
54
|
-
if sub_object
|
55
|
-
sub_object.id ||= BSON::ObjectId.new
|
56
|
-
hash[attribute.to_s] = factory.toHash(sub_object, true)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
hash
|
60
|
-
end
|
61
|
-
|
62
|
-
private
|
63
|
-
|
64
|
-
def embeds_many(attribute, factory, &block)
|
65
|
-
factory.instance_eval(&block) if block
|
66
|
-
@embeds_many[attribute.to_sym] = factory
|
67
|
-
end
|
68
|
-
|
69
|
-
def embeds_one(attribute, factory, &block)
|
70
|
-
factory.instance_eval(&block) if block
|
71
|
-
@embeds_one[attribute.to_sym] = factory
|
72
|
-
end
|
73
|
-
|
74
|
-
def simple_factory(klass, *attributes, &block)
|
75
|
-
self.class.new(klass, *attributes, &block)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'sequel'
|
2
|
-
require 'rmodel/base/repository'
|
3
|
-
require 'rmodel/sequel/repository_ext/queryable'
|
4
|
-
|
5
|
-
module Rmodel::Sequel
|
6
|
-
class Repository < Rmodel::Base::Repository
|
7
|
-
include RepositoryExt::Queryable
|
8
|
-
|
9
|
-
def initialize(client = nil, table = nil, factory = nil)
|
10
|
-
@client = client || Rmodel.setup.establish_sequel_client(self.class.client_name || :default) or
|
11
|
-
raise ArgumentError.new('Client driver is not setup')
|
12
|
-
|
13
|
-
@table = table || self.class.setting_table ||
|
14
|
-
self.class.table_by_convention or
|
15
|
-
raise ArgumentError.new('Table can not be guessed')
|
16
|
-
|
17
|
-
@factory = factory || self.class.setting_factory or
|
18
|
-
raise ArgumentError.new('Factory can not be guessed')
|
19
|
-
end
|
20
|
-
|
21
|
-
def find(id)
|
22
|
-
result = @client[@table].where(id: id).first
|
23
|
-
result && @factory.fromHash(result)
|
24
|
-
end
|
25
|
-
|
26
|
-
def insert(object)
|
27
|
-
id = @client[@table].insert(@factory.toHash(object, true))
|
28
|
-
object.id ||= id
|
29
|
-
end
|
30
|
-
|
31
|
-
def update(object)
|
32
|
-
@client[@table].where(id: object.id).update(@factory.toHash(object, false))
|
33
|
-
end
|
34
|
-
|
35
|
-
def remove(object)
|
36
|
-
@client[@table].where(id: object.id).delete
|
37
|
-
end
|
38
|
-
|
39
|
-
class << self
|
40
|
-
attr_reader :client_name, :setting_table, :setting_factory
|
41
|
-
|
42
|
-
def client(name)
|
43
|
-
@client_name = name
|
44
|
-
end
|
45
|
-
|
46
|
-
def table(name)
|
47
|
-
@setting_table = name
|
48
|
-
end
|
49
|
-
|
50
|
-
def table_by_convention
|
51
|
-
if name =~ /(.*)Repository$/
|
52
|
-
ActiveSupport::Inflector.tableize($1).to_sym
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def simple_factory(klass, *attributes)
|
57
|
-
@setting_factory = SimpleFactory.new(klass, *attributes)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'origin'
|
2
|
-
|
3
|
-
module Rmodel::Sequel
|
4
|
-
module RepositoryExt
|
5
|
-
class Query
|
6
|
-
include Enumerable
|
7
|
-
|
8
|
-
def initialize(repo, dataset)
|
9
|
-
@repo = repo
|
10
|
-
@dataset = dataset
|
11
|
-
end
|
12
|
-
|
13
|
-
def each(&block)
|
14
|
-
@repo.find_by_query(@dataset).each(&block)
|
15
|
-
self
|
16
|
-
end
|
17
|
-
|
18
|
-
def remove
|
19
|
-
@dataset.delete
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_sql
|
23
|
-
@dataset.sql
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.define_scope(name, &block)
|
27
|
-
define_method name do |*args|
|
28
|
-
new_dataset = @dataset.instance_exec(*args, &block)
|
29
|
-
self.class.new(@repo, new_dataset)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
require 'rmodel/sequel/repository_ext/query'
|
2
|
-
|
3
|
-
module Rmodel::Sequel
|
4
|
-
module RepositoryExt
|
5
|
-
module Queryable
|
6
|
-
def self.included(base)
|
7
|
-
base.extend ClassMethods
|
8
|
-
end
|
9
|
-
|
10
|
-
def query
|
11
|
-
(self.class.query_klass ||= Class.new(Query)).new(self, @client[@table])
|
12
|
-
end
|
13
|
-
|
14
|
-
def find_by_query(dataset)
|
15
|
-
dataset.map do |hash|
|
16
|
-
@factory.fromHash(hash)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
module ClassMethods
|
21
|
-
attr_accessor :query_klass
|
22
|
-
|
23
|
-
def scope(name, &block)
|
24
|
-
self.query_klass ||= Class.new(Query)
|
25
|
-
self.query_klass.define_scope(name, &block)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/lib/rmodel/sequel/setup.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
module Rmodel::Sequel
|
2
|
-
class SimpleFactory
|
3
|
-
def initialize(klass, *attributes)
|
4
|
-
@klass = klass
|
5
|
-
@attributes = attributes
|
6
|
-
end
|
7
|
-
|
8
|
-
def fromHash(hash)
|
9
|
-
object = @klass.new
|
10
|
-
object.id = hash[:id]
|
11
|
-
@attributes.each do |attribute|
|
12
|
-
object.public_send "#{attribute}=", hash[attribute.to_sym]
|
13
|
-
end
|
14
|
-
object
|
15
|
-
end
|
16
|
-
|
17
|
-
def toHash(object, id_included)
|
18
|
-
hash = {}
|
19
|
-
@attributes.each do |attribute|
|
20
|
-
hash[attribute.to_sym] = object.public_send(attribute)
|
21
|
-
end
|
22
|
-
if id_included
|
23
|
-
hash[:id] = object.id
|
24
|
-
end
|
25
|
-
hash
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/rmodel/setup.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
module Rmodel
|
4
|
-
class Setup
|
5
|
-
include Singleton
|
6
|
-
|
7
|
-
def initialize
|
8
|
-
@clients_config = {}
|
9
|
-
@established_clients = {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def client(name, config)
|
13
|
-
@clients_config[name] = config
|
14
|
-
end
|
15
|
-
|
16
|
-
def clear
|
17
|
-
@clients_config.clear
|
18
|
-
@established_clients.clear
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def establish_client(name)
|
24
|
-
@established_clients[name] ||= yield
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.setup(&block)
|
29
|
-
if block
|
30
|
-
Setup.instance.instance_eval &block
|
31
|
-
end
|
32
|
-
Setup.instance
|
33
|
-
end
|
34
|
-
end
|