realm-rom 0.7.0 → 0.7.3
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/README.md +40 -0
- data/Rakefile +19 -0
- metadata +39 -16
- data/lib/realm-rom.rb +0 -8
- data/lib/realm/rom/gateway.rb +0 -53
- data/lib/realm/rom/plugin.rb +0 -18
- data/lib/realm/rom/rake_tasks.rb +0 -73
- data/lib/realm/rom/read_only_relation_wrapper.rb +0 -26
- data/lib/realm/rom/read_only_repository_wrapper.rb +0 -25
- data/lib/realm/rom/repository.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 631dd7891edbda2e66cc9d812434d1a2036197f80be79e25ea061d2f37b8f2d6
|
4
|
+
data.tar.gz: 7d71ebd4ebc9d465fb36ee1d7b93b87d30166c635569aed0b0df9a1a425e3f08
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b9a81123cb1e55f7c9173a2d4edd8e0da6a30d15f606d74789f64c7fb52aab3ff9f64fc4629371938ee1fd076d5557c48187f2a1bb6e23c982e7d2b573216901
|
7
|
+
data.tar.gz: c2d44929520091709e83469ff68b2cdc52995eb5faa22dd4be223d7a083309b12597b4260f4063bfa23f7af978fd65654910282e2fd219ca9737301df7eaa668
|
data/README.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Realm
|
2
|
+
|
3
|
+
Domain layer framework following Domain-driven/CQRS design principles.
|
4
|
+
|
5
|
+
[](https://buildkite.com/reevoo/realm)
|
6
|
+
|
7
|
+
## Service layers
|
8
|
+
|
9
|
+
We follow the standard MVC design pattern of Rails but giving the model layer more structure and guidance regarding where
|
10
|
+
to put your code. The model is split into domain layer (using our [Realm](https://github.com/reevoo/smart-mono/tree/master/gems/realm) library)
|
11
|
+
and persistence layer (using [ROM](https://rom-rb.org/) library). The individual components are explained in the following section.
|
12
|
+
|
13
|
+

|
14
|
+
|
15
|
+
Advanced components are shown in lighter color, those will be needed only later on as the service domain logic grows.
|
16
|
+
|
17
|
+
## Model layer components
|
18
|
+
|
19
|
+

|
20
|
+
|
21
|
+
Each service has one **domain** module which consists of multiple [**aggregate**](https://martinfowler.com/bliki/DDD_Aggregate.html) modules.
|
22
|
+
Aggregate is a cluster of domain objects that can be treated as a single unit. The only way for outer world to communicate
|
23
|
+
with aggregate is by **queries** and **commands**. Query exposes aggregate's internal state and command changes it.
|
24
|
+
The state of an aggregate is represented by tree of **entities** with one being the aggregate root and zero or more dependent
|
25
|
+
entities with *belongs_to* relation to the root entity. The state of an aggregate (entity tree) is persisted
|
26
|
+
and retrieved by **repository**. There is generally one repository per aggregate unless we split the read/write
|
27
|
+
(query/command) persistence model for that particular domain. The repository uses **relations** to access the database
|
28
|
+
tables. Each relation class represents one table.
|
29
|
+
|
30
|
+
|
31
|
+
## Where to put my code as it grows?
|
32
|
+
|
33
|
+
TODO
|
34
|
+
|
35
|
+
|
36
|
+
## Roadmap
|
37
|
+
|
38
|
+
- [ ] Support Ruby 3
|
39
|
+
- [ ] Make it work outside of Rails engines
|
40
|
+
- [ ] Support multiple persistence gateways in one runtime
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler/setup'
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'rdoc/task'
|
10
|
+
|
11
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
12
|
+
rdoc.rdoc_dir = 'rdoc'
|
13
|
+
rdoc.title = 'Realm'
|
14
|
+
rdoc.options << '--line-numbers'
|
15
|
+
rdoc.rdoc_files.include('README.md')
|
16
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'bundler/gem_tasks'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: realm-rom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- developers@reevoo.com
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: realm-core
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.2'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: zeitwerk
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.4'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.4'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: pg
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,24 +136,33 @@ dependencies:
|
|
122
136
|
- - ">="
|
123
137
|
- !ruby/object:Gem::Version
|
124
138
|
version: '0'
|
125
|
-
|
126
|
-
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: sqlite3
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description:
|
154
|
+
email:
|
127
155
|
executables: []
|
128
156
|
extensions: []
|
129
157
|
extra_rdoc_files: []
|
130
158
|
files:
|
131
|
-
-
|
132
|
-
-
|
133
|
-
|
134
|
-
- lib/realm/rom/rake_tasks.rb
|
135
|
-
- lib/realm/rom/read_only_relation_wrapper.rb
|
136
|
-
- lib/realm/rom/read_only_repository_wrapper.rb
|
137
|
-
- lib/realm/rom/repository.rb
|
138
|
-
homepage:
|
159
|
+
- README.md
|
160
|
+
- Rakefile
|
161
|
+
homepage:
|
139
162
|
licenses:
|
140
163
|
- MIT
|
141
164
|
metadata: {}
|
142
|
-
post_install_message:
|
165
|
+
post_install_message:
|
143
166
|
rdoc_options: []
|
144
167
|
require_paths:
|
145
168
|
- lib
|
@@ -154,8 +177,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
177
|
- !ruby/object:Gem::Version
|
155
178
|
version: '0'
|
156
179
|
requirements: []
|
157
|
-
rubygems_version: 3.1.
|
158
|
-
signing_key:
|
180
|
+
rubygems_version: 3.1.4
|
181
|
+
signing_key:
|
159
182
|
specification_version: 4
|
160
183
|
summary: ROM SQL persistence plugin for Realm
|
161
184
|
test_files: []
|
data/lib/realm-rom.rb
DELETED
data/lib/realm/rom/gateway.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rom'
|
4
|
-
require 'realm/health_status'
|
5
|
-
require 'active_support/core_ext/string'
|
6
|
-
|
7
|
-
module Realm
|
8
|
-
module ROM
|
9
|
-
class Gateway
|
10
|
-
def initialize(url:, root_module:, class_path:, migration_path:, **)
|
11
|
-
@url = url
|
12
|
-
@root_module = root_module
|
13
|
-
@class_path = class_path
|
14
|
-
@migration_path = migration_path
|
15
|
-
end
|
16
|
-
|
17
|
-
def health
|
18
|
-
issues = []
|
19
|
-
issues << 'Cannot connect to db' unless default_gateway.connection.test_connection
|
20
|
-
issues << 'Pending migrations' if default_gateway.migrator.pending?
|
21
|
-
HealthStatus.from_issues(issues)
|
22
|
-
end
|
23
|
-
|
24
|
-
def method_missing(...)
|
25
|
-
client.send(...)
|
26
|
-
end
|
27
|
-
|
28
|
-
def respond_to_missing?(...)
|
29
|
-
client.respond_to?(...)
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def client
|
35
|
-
@client ||= ::ROM.container(config)
|
36
|
-
end
|
37
|
-
|
38
|
-
def config
|
39
|
-
::ROM::Configuration.new(:sql, @url, **config_options).tap do |config|
|
40
|
-
config.auto_registration(@class_path, namespace: @root_module.to_s)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def config_options
|
45
|
-
{ search_path: @root_module.to_s.underscore, migrator: { path: @migration_path } }
|
46
|
-
end
|
47
|
-
|
48
|
-
def default_gateway
|
49
|
-
client.gateways[:default]
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
data/lib/realm/rom/plugin.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'realm/plugin'
|
4
|
-
require_relative 'gateway'
|
5
|
-
|
6
|
-
module Realm
|
7
|
-
module ROM
|
8
|
-
class Plugin < Realm::Plugin
|
9
|
-
def self.setup(config, container)
|
10
|
-
return unless config.persistence_gateway[:type] == :rom
|
11
|
-
|
12
|
-
gateway = Gateway.new(config.persistence_gateway)
|
13
|
-
container.register('persistence.gateway', gateway)
|
14
|
-
container.register(:rom, gateway) # for backward compatibility as we access it a lot in tests
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/lib/realm/rom/rake_tasks.rb
DELETED
@@ -1,73 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rake'
|
4
|
-
require 'active_support/core_ext/string'
|
5
|
-
|
6
|
-
module Realm
|
7
|
-
module ROM
|
8
|
-
module RakeTasks
|
9
|
-
# rubocop:disable Metrics/AbcSize, Metrics/BlockLength, Metrics/MethodLength
|
10
|
-
def self.setup(engine_name, engine_root: Rails.root.join('engines', engine_name.to_s),
|
11
|
-
db_url: ENV['DATABASE_URL'])
|
12
|
-
return unless db_url
|
13
|
-
|
14
|
-
options = { search_path: engine_name.to_s, migrator: { path: "#{engine_root}/db/migrate" } }
|
15
|
-
config = ::ROM::Configuration.new(:sql, db_url, options)
|
16
|
-
gateway = config.gateways[:default]
|
17
|
-
|
18
|
-
Rake.application.in_namespace(:db) do
|
19
|
-
Rake::Task.define_task(:init_schema) do
|
20
|
-
gateway.run "CREATE SCHEMA IF NOT EXISTS \"#{engine_name}\""
|
21
|
-
puts "<= #{engine_name}:db:init_schema executed"
|
22
|
-
end
|
23
|
-
|
24
|
-
Rake::Task.define_task(:drop_schema) do
|
25
|
-
gateway.run "DROP SCHEMA \"#{engine_name}\" CASCADE"
|
26
|
-
puts "<= #{engine_name}:db:drop_schema executed"
|
27
|
-
end
|
28
|
-
|
29
|
-
Rake.application.last_description = 'Perform migration reset (full erase and migration up)'
|
30
|
-
Rake::Task.define_task(:reset) do
|
31
|
-
gateway.run_migrations(target: 0)
|
32
|
-
gateway.run_migrations
|
33
|
-
puts "<= #{engine_name}:db:reset executed"
|
34
|
-
end
|
35
|
-
|
36
|
-
Rake.application.last_description = 'Migrate the database (options [version_number])]'
|
37
|
-
Rake::Task.define_task(:migrate, %i[version]) do |_, args|
|
38
|
-
version = args[:version]
|
39
|
-
|
40
|
-
if version.nil?
|
41
|
-
gateway.run_migrations
|
42
|
-
puts "<= #{engine_name}:db:migrate executed"
|
43
|
-
else
|
44
|
-
gateway.run_migrations(target: version.to_i)
|
45
|
-
puts "<= #{engine_name}:db:migrate version=[#{version}] executed"
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
Rake.application.last_description = 'Perform migration down (removes all tables)'
|
50
|
-
Rake::Task.define_task(:clean) do
|
51
|
-
gateway.run_migrations(target: 0)
|
52
|
-
puts "<= #{engine_name}:db:clean executed"
|
53
|
-
end
|
54
|
-
|
55
|
-
Rake.application.last_description = 'Create a migration (parameters: NAME, VERSION)'
|
56
|
-
Rake::Task.define_task(:create_migration, %i[name version]) do |_, args|
|
57
|
-
name, version = args.values_at(:name, :version)
|
58
|
-
|
59
|
-
if name.nil?
|
60
|
-
puts "No NAME specified. Example usage:
|
61
|
-
`rake #{engine_name}:db:create_migration[create_users]`"
|
62
|
-
exit
|
63
|
-
end
|
64
|
-
|
65
|
-
path = gateway.migrator.create_file(*[name, version].compact)
|
66
|
-
puts "<= migration file created #{path}"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
# rubocop:enable Metrics/AbcSize, Metrics/BlockLength, Metrics/MethodLength
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'rom-sql'
|
4
|
-
require 'realm/persistence'
|
5
|
-
|
6
|
-
module Realm
|
7
|
-
module ROM
|
8
|
-
class ReadOnlyRelationWrapper
|
9
|
-
FORBIDDEN_METHODS = (::ROM::SQL::Relation::Writing.instance_methods(false) + [:command]).freeze
|
10
|
-
|
11
|
-
def initialize(relation)
|
12
|
-
@relation = relation
|
13
|
-
end
|
14
|
-
|
15
|
-
def method_missing(symbol, *args)
|
16
|
-
raise Persistence::RelationIsReadOnly, @relation if FORBIDDEN_METHODS.include?(symbol)
|
17
|
-
|
18
|
-
@relation.send(symbol, *args)
|
19
|
-
end
|
20
|
-
|
21
|
-
def respond_to_missing?(symbol)
|
22
|
-
!FORBIDDEN_METHODS.include?(symbol) && @relation.respond_to?(symbol)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'realm/persistence'
|
4
|
-
require_relative 'read_only_relation_wrapper'
|
5
|
-
|
6
|
-
module Realm
|
7
|
-
module ROM
|
8
|
-
class ReadOnlyRepositoryWrapper
|
9
|
-
def initialize(repo)
|
10
|
-
@repo = repo.clone
|
11
|
-
@repo.define_singleton_method(:root) { ReadOnlyRelationWrapper.new(super()) }
|
12
|
-
end
|
13
|
-
|
14
|
-
def method_missing(name, *args, &block)
|
15
|
-
@repo.send(name, *args, &block)
|
16
|
-
rescue Persistence::RelationIsReadOnly
|
17
|
-
raise Persistence::RepositoryIsReadOnly, @repo
|
18
|
-
end
|
19
|
-
|
20
|
-
def respond_to_missing?(*args)
|
21
|
-
@repo.respond_to?(*args)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/realm/rom/repository.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/string'
|
4
|
-
require 'rom-repository'
|
5
|
-
require 'rom-sql'
|
6
|
-
require 'realm/error'
|
7
|
-
require_relative 'read_only_repository_wrapper'
|
8
|
-
|
9
|
-
module Realm
|
10
|
-
module ROM
|
11
|
-
class Repository < ::ROM::Repository::Root
|
12
|
-
# Prevents leaking of persistence details into business logic
|
13
|
-
class Isolated
|
14
|
-
def initialize(repo)
|
15
|
-
@repo = repo
|
16
|
-
end
|
17
|
-
|
18
|
-
def method_missing(*args, &block)
|
19
|
-
result = @repo.send(*args, &block)
|
20
|
-
result.is_a?(::ROM::Relation) ? result.to_a : result
|
21
|
-
rescue ::ROM::SQL::UniqueConstraintError
|
22
|
-
raise Realm::UniqueConstraintError
|
23
|
-
end
|
24
|
-
|
25
|
-
def respond_to_missing?(*args)
|
26
|
-
@repo.respond_to?(*args)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.new(*)
|
31
|
-
Isolated.new(super)
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.repo_name(value = :not_provided)
|
35
|
-
@repo_name = value.to_sym unless value == :not_provided
|
36
|
-
@repo_name = name.demodulize.underscore unless defined?(@repo_name)
|
37
|
-
@repo_name
|
38
|
-
end
|
39
|
-
|
40
|
-
def readonly
|
41
|
-
@readonly ||= ROM::ReadOnlyRepositoryWrapper.new(self)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|