rom 0.1.2 → 0.2.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.
- data/.rspec +2 -0
- data/.travis.yml +22 -0
- data/Changelog.md +16 -0
- data/Gemfile +13 -6
- data/Gemfile.devtools +71 -0
- data/Guardfile +19 -0
- data/LICENSE +1 -1
- data/README.md +52 -30
- data/Rakefile +3 -0
- data/config/devtools.yml +4 -0
- data/config/flay.yml +3 -0
- data/config/flog.yml +2 -0
- data/config/mutant.yml +5 -0
- data/config/reek.yml +103 -0
- data/config/rubocop.yml +62 -0
- data/config/yardstick.yml +2 -0
- data/lib/rom.rb +13 -5
- data/lib/rom/constants.rb +16 -0
- data/lib/rom/environment.rb +105 -0
- data/lib/rom/environment/builder.rb +71 -0
- data/lib/rom/mapper.rb +176 -0
- data/lib/rom/mapper/attribute.rb +108 -0
- data/lib/rom/mapper/builder.rb +58 -0
- data/lib/rom/mapper/builder/definition.rb +162 -0
- data/lib/rom/mapper/header.rb +103 -0
- data/lib/rom/mapper/loader_builder.rb +26 -0
- data/lib/rom/relation.rb +375 -0
- data/lib/rom/repository.rb +71 -0
- data/lib/rom/schema.rb +21 -0
- data/lib/rom/schema/builder.rb +59 -0
- data/lib/rom/schema/definition.rb +84 -0
- data/lib/rom/schema/definition/relation.rb +80 -0
- data/lib/rom/schema/definition/relation/base.rb +27 -0
- data/lib/rom/session.rb +111 -0
- data/lib/rom/session/environment.rb +67 -0
- data/lib/rom/session/identity_map.rb +43 -0
- data/lib/rom/session/mapper.rb +62 -0
- data/lib/rom/session/relation.rb +140 -0
- data/lib/rom/session/state.rb +59 -0
- data/lib/rom/session/state/created.rb +22 -0
- data/lib/rom/session/state/deleted.rb +25 -0
- data/lib/rom/session/state/persisted.rb +34 -0
- data/lib/rom/session/state/transient.rb +20 -0
- data/lib/rom/session/state/updated.rb +29 -0
- data/lib/rom/session/tracker.rb +62 -0
- data/lib/rom/support/axiom/adapter.rb +111 -0
- data/lib/rom/support/axiom/adapter/data_objects.rb +38 -0
- data/lib/rom/support/axiom/adapter/memory.rb +25 -0
- data/lib/rom/support/axiom/adapter/postgres.rb +19 -0
- data/lib/rom/support/axiom/adapter/sqlite3.rb +20 -0
- data/lib/version.rb +1 -1
- data/rom.gemspec +7 -3
- data/spec/integration/environment_setup_spec.rb +24 -0
- data/spec/integration/grouped_mappers_spec.rb +87 -0
- data/spec/integration/join_and_group_spec.rb +76 -0
- data/spec/integration/join_and_wrap_spec.rb +68 -0
- data/spec/integration/mapping_embedded_relations_spec.rb +73 -0
- data/spec/integration/mapping_relations_spec.rb +120 -0
- data/spec/integration/schema_definition_spec.rb +152 -0
- data/spec/integration/session_spec.rb +87 -0
- data/spec/integration/wrapped_mappers_spec.rb +73 -0
- data/spec/shared/unit/environment_context.rb +6 -0
- data/spec/shared/unit/loader.rb +11 -0
- data/spec/shared/unit/loader_identity.rb +13 -0
- data/spec/shared/unit/mapper_context.rb +11 -0
- data/spec/shared/unit/relation_context.rb +82 -0
- data/spec/shared/unit/session_environment_context.rb +11 -0
- data/spec/shared/unit/session_relation_context.rb +18 -0
- data/spec/spec_helper.rb +49 -0
- data/spec/support/helper.rb +34 -0
- data/spec/support/ice_nine_config.rb +10 -0
- data/spec/support/test_mapper.rb +110 -0
- data/spec/unit/rom/environment/builder/mapping_spec.rb +24 -0
- data/spec/unit/rom/environment/builder/schema_spec.rb +33 -0
- data/spec/unit/rom/environment/class_methods/setup_spec.rb +18 -0
- data/spec/unit/rom/environment/repository_spec.rb +21 -0
- data/spec/unit/rom/mapper/attribute/embedded_collection/to_ast_spec.rb +18 -0
- data/spec/unit/rom/mapper/attribute/embedded_value/to_ast_spec.rb +16 -0
- data/spec/unit/rom/mapper/attribute/rename_spec.rb +9 -0
- data/spec/unit/rom/mapper/attribute/to_ast_spec.rb +9 -0
- data/spec/unit/rom/mapper/builder/class_methods/call_spec.rb +61 -0
- data/spec/unit/rom/mapper/class_methods/build_spec.rb +55 -0
- data/spec/unit/rom/mapper/dump_spec.rb +11 -0
- data/spec/unit/rom/mapper/group_spec.rb +35 -0
- data/spec/unit/rom/mapper/header/each_spec.rb +26 -0
- data/spec/unit/rom/mapper/header/element_reader_spec.rb +21 -0
- data/spec/unit/rom/mapper/header/group_spec.rb +18 -0
- data/spec/unit/rom/mapper/header/join_spec.rb +14 -0
- data/spec/unit/rom/mapper/header/keys_spec.rb +29 -0
- data/spec/unit/rom/mapper/header/project_spec.rb +13 -0
- data/spec/unit/rom/mapper/header/rename_spec.rb +11 -0
- data/spec/unit/rom/mapper/header/to_ast_spec.rb +11 -0
- data/spec/unit/rom/mapper/header/wrap_spec.rb +18 -0
- data/spec/unit/rom/mapper/identity_from_tuple_spec.rb +11 -0
- data/spec/unit/rom/mapper/identity_spec.rb +11 -0
- data/spec/unit/rom/mapper/join_spec.rb +15 -0
- data/spec/unit/rom/mapper/load_spec.rb +11 -0
- data/spec/unit/rom/mapper/new_object_spec.rb +14 -0
- data/spec/unit/rom/mapper/project_spec.rb +11 -0
- data/spec/unit/rom/mapper/rename_spec.rb +16 -0
- data/spec/unit/rom/mapper/wrap_spec.rb +35 -0
- data/spec/unit/rom/relation/delete_spec.rb +15 -0
- data/spec/unit/rom/relation/drop_spec.rb +11 -0
- data/spec/unit/rom/relation/each_spec.rb +23 -0
- data/spec/unit/rom/relation/first_spec.rb +19 -0
- data/spec/unit/rom/relation/group_spec.rb +29 -0
- data/spec/unit/rom/relation/inject_mapper_spec.rb +17 -0
- data/spec/unit/rom/relation/insert_spec.rb +13 -0
- data/spec/unit/rom/relation/last_spec.rb +19 -0
- data/spec/unit/rom/relation/one_spec.rb +49 -0
- data/spec/unit/rom/relation/rename_spec.rb +21 -0
- data/spec/unit/rom/relation/replace_spec.rb +13 -0
- data/spec/unit/rom/relation/restrict_spec.rb +25 -0
- data/spec/unit/rom/relation/sort_by_spec.rb +25 -0
- data/spec/unit/rom/relation/take_spec.rb +11 -0
- data/spec/unit/rom/relation/to_a_spec.rb +20 -0
- data/spec/unit/rom/relation/update_spec.rb +25 -0
- data/spec/unit/rom/relation/wrap_spec.rb +29 -0
- data/spec/unit/rom/repository/class_methods/build_spec.rb +27 -0
- data/spec/unit/rom/repository/element_reader_spec.rb +21 -0
- data/spec/unit/rom/repository/element_writer_spec.rb +18 -0
- data/spec/unit/rom/schema/builder/class_methods/build_spec.rb +103 -0
- data/spec/unit/rom/schema/element_reader_spec.rb +15 -0
- data/spec/unit/rom/session/class_methods/start_spec.rb +23 -0
- data/spec/unit/rom/session/clean_predicate_spec.rb +21 -0
- data/spec/unit/rom/session/environment/element_reader_spec.rb +13 -0
- data/spec/unit/rom/session/flush_spec.rb +58 -0
- data/spec/unit/rom/session/mapper/load_spec.rb +47 -0
- data/spec/unit/rom/session/relation/delete_spec.rb +28 -0
- data/spec/unit/rom/session/relation/dirty_predicate_spec.rb +35 -0
- data/spec/unit/rom/session/relation/identity_spec.rb +11 -0
- data/spec/unit/rom/session/relation/new_spec.rb +50 -0
- data/spec/unit/rom/session/relation/save_spec.rb +50 -0
- data/spec/unit/rom/session/relation/state_spec.rb +23 -0
- data/spec/unit/rom/session/relation/track_spec.rb +23 -0
- data/spec/unit/rom/session/relation/tracking_predicate_spec.rb +23 -0
- data/spec/unit/rom/session/relation/update_attributes_spec.rb +45 -0
- data/spec/unit/rom/session/state_spec.rb +79 -0
- metadata +212 -11
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rom/support/axiom/adapter'
|
|
4
|
+
|
|
5
|
+
module ROM
|
|
6
|
+
|
|
7
|
+
# A repository with a given +name+ and +adapter+
|
|
8
|
+
#
|
|
9
|
+
# @api private
|
|
10
|
+
class Repository
|
|
11
|
+
include Concord.new(:name, :adapter, :relations)
|
|
12
|
+
|
|
13
|
+
# Build a repository with a given +name+ and +uri+
|
|
14
|
+
#
|
|
15
|
+
# @param [Symbol] name
|
|
16
|
+
# the repository's name
|
|
17
|
+
#
|
|
18
|
+
# @param [Addressable::URI] uri
|
|
19
|
+
# the uri for initializing the adapter
|
|
20
|
+
#
|
|
21
|
+
# @return [Repository]
|
|
22
|
+
#
|
|
23
|
+
# @api private
|
|
24
|
+
def self.build(name, uri, relations = {})
|
|
25
|
+
new(name, Axiom::Adapter.build(uri), relations)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Return the relation identified by +name+
|
|
29
|
+
#
|
|
30
|
+
# @example
|
|
31
|
+
#
|
|
32
|
+
# repo = Repository.coerce(:test, 'in_memory://test')
|
|
33
|
+
# repo.register(:foo, [[:id, String], [:foo, String]])
|
|
34
|
+
# repo[:foo]
|
|
35
|
+
#
|
|
36
|
+
# # => <Axiom::Relation header=Axiom::Header ...>
|
|
37
|
+
#
|
|
38
|
+
# @param [Symbol] name
|
|
39
|
+
# the name of the relation
|
|
40
|
+
#
|
|
41
|
+
# @return [Axiom::Relation]
|
|
42
|
+
#
|
|
43
|
+
# @raise [KeyError]
|
|
44
|
+
#
|
|
45
|
+
# @api public
|
|
46
|
+
def [](name)
|
|
47
|
+
relations.fetch(name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Register a relation with this repository
|
|
51
|
+
#
|
|
52
|
+
# @param [Axiom::Relation::Base] relation
|
|
53
|
+
#
|
|
54
|
+
# @return [Object] relation gateway
|
|
55
|
+
#
|
|
56
|
+
# @api public
|
|
57
|
+
def []=(name, relation)
|
|
58
|
+
relation =
|
|
59
|
+
if adapter.respond_to?(:gateway)
|
|
60
|
+
adapter.gateway(relation)
|
|
61
|
+
else
|
|
62
|
+
adapter[name] = relation
|
|
63
|
+
adapter[name]
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
relations[name] = relation
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end # Repository
|
|
70
|
+
|
|
71
|
+
end # ROM
|
data/lib/rom/schema.rb
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
|
|
5
|
+
# ROM's relation schema
|
|
6
|
+
#
|
|
7
|
+
class Schema
|
|
8
|
+
include Concord.new(:relations), Adamantium::Flat
|
|
9
|
+
|
|
10
|
+
# Return a relation identified by name
|
|
11
|
+
#
|
|
12
|
+
# @param [Symbol] name of the relation
|
|
13
|
+
#
|
|
14
|
+
# @return [Relation]
|
|
15
|
+
def [](name)
|
|
16
|
+
relations.fetch(name)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end # Schema
|
|
20
|
+
|
|
21
|
+
end # ROM
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rom/schema'
|
|
4
|
+
require 'rom/schema/definition'
|
|
5
|
+
|
|
6
|
+
module ROM
|
|
7
|
+
class Schema
|
|
8
|
+
|
|
9
|
+
# Schema builder DSL
|
|
10
|
+
#
|
|
11
|
+
class Builder
|
|
12
|
+
include Concord.new(:definition), Adamantium::Flat
|
|
13
|
+
|
|
14
|
+
# Build a relation schema
|
|
15
|
+
#
|
|
16
|
+
# @example
|
|
17
|
+
#
|
|
18
|
+
# Schema.build do
|
|
19
|
+
# base_relation :users do
|
|
20
|
+
# repository :test
|
|
21
|
+
# attribute :id, :name
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# @return [Schema]
|
|
26
|
+
#
|
|
27
|
+
# @api public
|
|
28
|
+
def self.build(repositories, &block)
|
|
29
|
+
new(Definition.new(repositories, &block))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Return defined relation identified by name
|
|
33
|
+
#
|
|
34
|
+
# @example
|
|
35
|
+
#
|
|
36
|
+
# schema[:users] # => #<Axiom::Relation::Base ..>
|
|
37
|
+
#
|
|
38
|
+
# @return [Axiom::Relation, Axiom::Relation::Base]
|
|
39
|
+
#
|
|
40
|
+
# @api public
|
|
41
|
+
def [](name)
|
|
42
|
+
definition[name]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# @api private
|
|
46
|
+
def call(&block)
|
|
47
|
+
definition.instance_eval(&block)
|
|
48
|
+
self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @api private
|
|
52
|
+
def finalize
|
|
53
|
+
Schema.new(definition.relations)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end # Builder
|
|
57
|
+
|
|
58
|
+
end # Schema
|
|
59
|
+
end # ROM
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rom/schema/definition/relation/base'
|
|
4
|
+
|
|
5
|
+
module ROM
|
|
6
|
+
class Schema
|
|
7
|
+
|
|
8
|
+
# Builder object used by schema DSL to establish Axiom relations
|
|
9
|
+
#
|
|
10
|
+
# @private
|
|
11
|
+
class Definition
|
|
12
|
+
include Equalizer.new(:repositories, :relations)
|
|
13
|
+
|
|
14
|
+
attr_reader :repositories, :relations
|
|
15
|
+
|
|
16
|
+
# @api private
|
|
17
|
+
def initialize(repositories, &block)
|
|
18
|
+
@repositories = repositories
|
|
19
|
+
@relations = {}
|
|
20
|
+
instance_eval(&block) if block
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Build a base relation
|
|
24
|
+
#
|
|
25
|
+
# @example
|
|
26
|
+
#
|
|
27
|
+
# Schema.build do
|
|
28
|
+
# base_relation :users do
|
|
29
|
+
# # ...
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
#
|
|
33
|
+
# @return [Definition]
|
|
34
|
+
#
|
|
35
|
+
# @api private
|
|
36
|
+
def base_relation(name, &block)
|
|
37
|
+
builder = Relation::Base.new(relations, &block)
|
|
38
|
+
repository = repositories.fetch(builder.repository)
|
|
39
|
+
|
|
40
|
+
repository[name] = builder.call(name)
|
|
41
|
+
relations[name] = repository[name]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Build a relation
|
|
45
|
+
#
|
|
46
|
+
# @example
|
|
47
|
+
#
|
|
48
|
+
# Schema.build do
|
|
49
|
+
# relation :users do
|
|
50
|
+
# # ...
|
|
51
|
+
# end
|
|
52
|
+
# end
|
|
53
|
+
#
|
|
54
|
+
# @return [Definition]
|
|
55
|
+
#
|
|
56
|
+
# @api private
|
|
57
|
+
def relation(name, &block)
|
|
58
|
+
relations[name] = instance_eval(&block)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Return relation identified by name
|
|
62
|
+
#
|
|
63
|
+
# @return [Axiom::Relation, Axiom::Relation::Base]
|
|
64
|
+
#
|
|
65
|
+
# @api private
|
|
66
|
+
def [](name)
|
|
67
|
+
relations[name]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
# Method missing hook
|
|
73
|
+
#
|
|
74
|
+
# @return [Axiom::Relation, Axiom::Relation::Base]
|
|
75
|
+
#
|
|
76
|
+
# @api private
|
|
77
|
+
def method_missing(*args)
|
|
78
|
+
self[args.first] || super
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end # Definition
|
|
82
|
+
|
|
83
|
+
end # Schema
|
|
84
|
+
end # ROM
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module ROM
|
|
4
|
+
class Schema
|
|
5
|
+
class Definition
|
|
6
|
+
|
|
7
|
+
# Builder object for Axiom relation
|
|
8
|
+
#
|
|
9
|
+
# @private
|
|
10
|
+
class Relation
|
|
11
|
+
include Equalizer.new(:header, :keys)
|
|
12
|
+
|
|
13
|
+
attr_reader :registry
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
def initialize(registry, &block)
|
|
17
|
+
@registry = registry
|
|
18
|
+
@header = []
|
|
19
|
+
@keys = []
|
|
20
|
+
@wrappings = []
|
|
21
|
+
@groupings = []
|
|
22
|
+
instance_eval(&block)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @api private
|
|
26
|
+
def call(name)
|
|
27
|
+
relation = Axiom::Relation::Base.new(name, build_header)
|
|
28
|
+
|
|
29
|
+
if @wrappings.any?
|
|
30
|
+
@wrappings.each { |wrapping| relation = relation.wrap(wrapping) }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
if @groupings.any?
|
|
34
|
+
@groupings.each { |grouping| relation = relation.group(grouping) }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
renames = @header.each_with_object({}) { |ary, mapping|
|
|
38
|
+
mapping[ary.first] = ary.last[:rename] if ary.last[:rename]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
relation.rename(renames).optimize
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @api private
|
|
45
|
+
def attribute(name, type, options = {})
|
|
46
|
+
@header << [name, type, options]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# @api private
|
|
50
|
+
def wrap(wrapping)
|
|
51
|
+
@wrappings << wrapping
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @api private
|
|
55
|
+
def group(grouping)
|
|
56
|
+
@groupings << grouping
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @api private
|
|
60
|
+
def key(*attribute_names)
|
|
61
|
+
@keys.concat(attribute_names)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
# @api private
|
|
67
|
+
def method_missing(*args)
|
|
68
|
+
registry[args.first] || super
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# @api private
|
|
72
|
+
def build_header
|
|
73
|
+
Axiom::Relation::Header.coerce(@header, keys: @keys)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
end # Relation
|
|
77
|
+
|
|
78
|
+
end # Definition
|
|
79
|
+
end # Schema
|
|
80
|
+
end # ROM
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rom/schema/definition/relation'
|
|
4
|
+
|
|
5
|
+
module ROM
|
|
6
|
+
class Schema
|
|
7
|
+
class Definition
|
|
8
|
+
class Relation
|
|
9
|
+
|
|
10
|
+
# Base relation builder object
|
|
11
|
+
#
|
|
12
|
+
class Base < self
|
|
13
|
+
|
|
14
|
+
def repository(name = Undefined)
|
|
15
|
+
if name == Undefined
|
|
16
|
+
@repository
|
|
17
|
+
else
|
|
18
|
+
@repository = name
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
end # Base
|
|
23
|
+
|
|
24
|
+
end # Relation
|
|
25
|
+
end # Definition
|
|
26
|
+
end # Schema
|
|
27
|
+
end # ROM
|
data/lib/rom/session.rb
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'rom/session/environment'
|
|
4
|
+
require 'rom/session/tracker'
|
|
5
|
+
require 'rom/session/identity_map'
|
|
6
|
+
require 'rom/session/relation'
|
|
7
|
+
require 'rom/session/mapper'
|
|
8
|
+
|
|
9
|
+
require 'rom/session/state'
|
|
10
|
+
require 'rom/session/state/transient'
|
|
11
|
+
require 'rom/session/state/persisted'
|
|
12
|
+
require 'rom/session/state/created'
|
|
13
|
+
require 'rom/session/state/updated'
|
|
14
|
+
require 'rom/session/state/deleted'
|
|
15
|
+
|
|
16
|
+
module ROM
|
|
17
|
+
|
|
18
|
+
# Extended ROM::Environment with session support
|
|
19
|
+
class Environment
|
|
20
|
+
|
|
21
|
+
# Start a new session for this environment
|
|
22
|
+
#
|
|
23
|
+
# @example
|
|
24
|
+
# env.session do |session|
|
|
25
|
+
# # ...
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# @see Session.start
|
|
29
|
+
#
|
|
30
|
+
# @api public
|
|
31
|
+
def session(&block)
|
|
32
|
+
Session.start(self, &block)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Session with IdentityMap and state-tracking functionality
|
|
37
|
+
#
|
|
38
|
+
# @example
|
|
39
|
+
#
|
|
40
|
+
# env.session do |session|
|
|
41
|
+
# user = session[:users].new(id: 1, name: 'Jane')
|
|
42
|
+
#
|
|
43
|
+
# session[:users].save(user)
|
|
44
|
+
#
|
|
45
|
+
# session.flush
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# @api public
|
|
49
|
+
class Session
|
|
50
|
+
include Concord.new(:environment)
|
|
51
|
+
|
|
52
|
+
# Raised when an object is expected to be tracked and it's not
|
|
53
|
+
#
|
|
54
|
+
class ObjectNotTrackedError < StandardError
|
|
55
|
+
def initialize(identity)
|
|
56
|
+
super("Tracker doesn't include object with identity #{identity.inspect}")
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Start a new session
|
|
61
|
+
#
|
|
62
|
+
# @example
|
|
63
|
+
#
|
|
64
|
+
# ROM::Session.start(env) do |session|
|
|
65
|
+
# user = session[:users].new(name: 'Jane')
|
|
66
|
+
# session[:users].save(user)
|
|
67
|
+
# session[:users].flush
|
|
68
|
+
# end
|
|
69
|
+
#
|
|
70
|
+
# @param [ROM::Environment] rom's environment
|
|
71
|
+
#
|
|
72
|
+
# @yieldparam [Session::Environment]
|
|
73
|
+
#
|
|
74
|
+
# @api public
|
|
75
|
+
def self.start(environment)
|
|
76
|
+
yield(new(Environment.build(environment)))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Return a session relation identified by name
|
|
80
|
+
#
|
|
81
|
+
# @param [Symbol] relation name
|
|
82
|
+
#
|
|
83
|
+
# @return [Session::Relation]
|
|
84
|
+
#
|
|
85
|
+
# @api public
|
|
86
|
+
def [](relation_name)
|
|
87
|
+
environment[relation_name]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Flush this session committing all the state changes
|
|
91
|
+
#
|
|
92
|
+
# @return [Session]
|
|
93
|
+
#
|
|
94
|
+
# @api public
|
|
95
|
+
def flush
|
|
96
|
+
environment.commit
|
|
97
|
+
self
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Return if there are any pending state changes
|
|
101
|
+
#
|
|
102
|
+
# @return [Boolean]
|
|
103
|
+
#
|
|
104
|
+
# @api public
|
|
105
|
+
def clean?
|
|
106
|
+
environment.clean?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
end # Session
|
|
110
|
+
|
|
111
|
+
end # ROM
|