rom-yesql 0.5.1 → 1.1.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 +5 -5
- data/.action_hero.yml +20 -0
- data/.devtools/templates/README.md.erb +29 -0
- data/.devtools/templates/changelog.erb +43 -0
- data/.devtools/templates/release.erb +36 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/ISSUE_TEMPLATE/bug-report.md +26 -0
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/SUPPORT.md +3 -0
- data/.github/workflows/ci.yml +61 -0
- data/.github/workflows/docsite.yml +63 -0
- data/.github/workflows/rubocop.yml +46 -0
- data/.github/workflows/sync_configs.yml +53 -0
- data/.rspec +2 -0
- data/.rubocop.yml +210 -37
- data/CHANGELOG.md +41 -12
- data/CODEOWNERS +1 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +29 -0
- data/Gemfile +9 -7
- data/Gemfile.devtools +20 -0
- data/Guardfile +7 -5
- data/LICENSE +20 -0
- data/README.md +13 -26
- data/Rakefile +5 -3
- data/changelog.yml +38 -0
- data/lib/rom/yesql/dataset.rb +2 -0
- data/lib/rom/yesql/gateway.rb +21 -18
- data/lib/rom/yesql/relation/class_interface.rb +5 -4
- data/lib/rom/yesql/relation.rb +10 -13
- data/lib/rom/yesql/version.rb +3 -1
- data/lib/rom/yesql.rb +4 -2
- data/lib/rom-yesql.rb +4 -2
- data/project.yml +2 -0
- data/rakelib/rubocop.rake +5 -3
- data/rom-yesql.gemspec +9 -8
- data/spec/integration/adapter_spec.rb +26 -24
- data/spec/shared/database_setup.rb +5 -3
- data/spec/shared/repository_setup.rb +8 -6
- data/spec/shared/users_and_tasks.rb +9 -7
- data/spec/spec_helper.rb +13 -19
- data/spec/support/coverage.rb +15 -0
- data/spec/support/rspec_options.rb +16 -0
- data/spec/support/warnings.rb +10 -0
- data/spec/unit/rom/yesql/repository_spec.rb +12 -10
- metadata +37 -53
- data/.rubocop_todo.yml +0 -21
- data/.travis.yml +0 -30
- data/LICENSE.txt +0 -22
data/lib/rom/yesql/gateway.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "sequel"
|
4
4
|
|
5
|
-
require
|
6
|
-
|
5
|
+
require "rom/initializer"
|
6
|
+
|
7
|
+
require "rom/yesql/dataset"
|
8
|
+
require "rom/yesql/relation"
|
7
9
|
|
8
10
|
module ROM
|
9
11
|
module Yesql
|
@@ -13,7 +15,7 @@ module ROM
|
|
13
15
|
# expose access to gateway's queries.
|
14
16
|
#
|
15
17
|
# @api public
|
16
|
-
class Gateway < ROM::Gateway
|
18
|
+
class Gateway < ::ROM::Gateway
|
17
19
|
extend Initializer
|
18
20
|
|
19
21
|
adapter :yesql
|
@@ -69,9 +71,9 @@ module ROM
|
|
69
71
|
# @option :query_proc [Proc]
|
70
72
|
#
|
71
73
|
# @api public
|
72
|
-
def initialize(
|
74
|
+
def initialize(*, **)
|
73
75
|
super
|
74
|
-
@connection = Sequel.connect(uri, options)
|
76
|
+
@connection = ::Sequel.connect(uri, options)
|
75
77
|
@queries = @queries.merge(load_queries(path)).freeze
|
76
78
|
Relation.query_proc(query_proc)
|
77
79
|
Relation.load_queries(queries)
|
@@ -96,7 +98,7 @@ module ROM
|
|
96
98
|
#
|
97
99
|
# @api private
|
98
100
|
def dataset?(_name)
|
99
|
-
|
101
|
+
!@dataset.nil?
|
100
102
|
end
|
101
103
|
|
102
104
|
private
|
@@ -108,20 +110,21 @@ module ROM
|
|
108
110
|
if path.nil?
|
109
111
|
{}
|
110
112
|
else
|
111
|
-
Dir["#{path}/*"].
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
113
|
+
::Dir["#{path}/*"].to_h do |dir|
|
114
|
+
[
|
115
|
+
::File.basename(dir).to_sym,
|
116
|
+
::Dir["#{dir}/**/*.sql"].to_h do |file|
|
117
|
+
query_name = ::File.basename(file, ".*").to_sym
|
118
|
+
sql = ::File.read(file).strip
|
119
|
+
|
120
|
+
[query_name, sql]
|
121
|
+
end
|
122
|
+
]
|
120
123
|
end
|
121
124
|
end
|
122
125
|
end
|
123
126
|
end
|
124
127
|
end
|
125
128
|
|
126
|
-
register_adapter(:yesql,
|
129
|
+
register_adapter(:yesql, Yesql)
|
127
130
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ROM
|
2
4
|
module Yesql
|
3
|
-
class Relation < ROM::Relation
|
5
|
+
class Relation < ::ROM::Relation
|
4
6
|
module ClassInterface
|
5
7
|
# Sets dataset name for the relation class
|
6
8
|
#
|
@@ -14,10 +16,9 @@ module ROM
|
|
14
16
|
#
|
15
17
|
# @api public
|
16
18
|
def dataset(name = Undefined)
|
17
|
-
|
18
|
-
@dataset = name
|
19
|
+
name = relation_name.to_sym if name == Undefined
|
19
20
|
define_query_methods(self, Relation.queries[name] || {})
|
20
|
-
|
21
|
+
->(*) { self }
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
data/lib/rom/yesql/relation.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
|
3
|
+
require "dry/core/class_attributes"
|
4
|
+
|
5
|
+
require "rom/relation"
|
6
|
+
require "rom/yesql/relation/class_interface"
|
5
7
|
|
6
8
|
module ROM
|
7
9
|
module Yesql
|
@@ -30,14 +32,14 @@ module ROM
|
|
30
32
|
# rom.relations[:reports] # use like a normal rom relation
|
31
33
|
#
|
32
34
|
# @api public
|
33
|
-
class Relation < ROM::Relation
|
35
|
+
class Relation < ::ROM::Relation
|
34
36
|
adapter :yesql
|
35
37
|
|
36
|
-
extend Dry::Core::ClassAttributes
|
38
|
+
extend ::Dry::Core::ClassAttributes
|
37
39
|
|
38
40
|
defines :query_proc
|
39
41
|
|
40
|
-
Materialized = Class.new(ROM::Relation)
|
42
|
+
Materialized = ::Class.new(::ROM::Relation)
|
41
43
|
|
42
44
|
# Extends a relation with query methods
|
43
45
|
#
|
@@ -49,7 +51,6 @@ module ROM
|
|
49
51
|
def self.inherited(klass)
|
50
52
|
super
|
51
53
|
klass.extend(ClassInterface)
|
52
|
-
define_query_methods(klass, queries[klass.dataset] || {})
|
53
54
|
end
|
54
55
|
|
55
56
|
# Extends provided klass with query methods
|
@@ -83,13 +84,9 @@ module ROM
|
|
83
84
|
#
|
84
85
|
# @api private
|
85
86
|
def self.load_queries(queries)
|
86
|
-
@queries =
|
87
|
-
|
88
|
-
@queries[ds] = ds_queries.each_with_object({}) do |(name, query), h|
|
89
|
-
h[name] = query
|
90
|
-
end
|
87
|
+
@queries = queries.to_h do |ds, ds_queries|
|
88
|
+
[ds, ds_queries.to_h { |name, query| [name, query] }]
|
91
89
|
end
|
92
|
-
@queries
|
93
90
|
end
|
94
91
|
|
95
92
|
# Returns query proc set on a relation class
|
data/lib/rom/yesql/version.rb
CHANGED
data/lib/rom/yesql.rb
CHANGED
data/lib/rom-yesql.rb
CHANGED
data/project.yml
ADDED
data/rakelib/rubocop.rake
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
4
|
require "rubocop/rake_task"
|
3
5
|
|
@@ -8,11 +10,11 @@ begin
|
|
8
10
|
end
|
9
11
|
|
10
12
|
namespace :rubocop do
|
11
|
-
desc
|
13
|
+
desc "Generate a configuration file acting as a TODO list."
|
12
14
|
task :auto_gen_config do
|
13
15
|
exec "bundle exec rubocop --auto-gen-config"
|
14
16
|
end
|
15
17
|
end
|
16
|
-
|
17
|
-
|
18
|
+
rescue LoadError
|
19
|
+
# rubocop is not available
|
18
20
|
end
|
data/rom-yesql.gemspec
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path("lib", __dir__)
|
2
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
-
require
|
5
|
+
require "rom/yesql/version"
|
4
6
|
|
5
7
|
Gem::Specification.new do |spec|
|
6
8
|
spec.name = "rom-yesql"
|
7
9
|
spec.version = ROM::Yesql::VERSION.dup
|
8
10
|
spec.authors = ["Piotr Solnica"]
|
9
11
|
spec.email = ["piotr.solnica@gmail.com"]
|
10
|
-
spec.summary =
|
12
|
+
spec.summary = "Yesql adapter for ROM"
|
11
13
|
spec.description = spec.summary
|
12
14
|
spec.homepage = "http://rom-rb.org"
|
13
15
|
spec.license = "MIT"
|
@@ -16,10 +18,9 @@ Gem::Specification.new do |spec|
|
|
16
18
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
19
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
20
|
spec.require_paths = ["lib"]
|
21
|
+
spec.required_ruby_version = ">= 3.1.0"
|
19
22
|
|
20
|
-
spec.add_runtime_dependency "
|
21
|
-
spec.add_runtime_dependency "
|
22
|
-
spec.add_runtime_dependency "sequel", "~>
|
23
|
-
spec.add_development_dependency "bundler"
|
24
|
-
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
+
spec.add_runtime_dependency "dry-core", "~>1.1"
|
24
|
+
spec.add_runtime_dependency "rom", "~> 5.4"
|
25
|
+
spec.add_runtime_dependency "sequel", "~> 5"
|
25
26
|
end
|
@@ -1,59 +1,61 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe "ROM / Yesql" do
|
6
|
+
include_context "users and tasks"
|
5
7
|
|
6
8
|
let(:container) { ROM.container(configuration) }
|
7
9
|
|
8
10
|
let!(:configuration) do
|
9
|
-
ROM::Configuration.new(:yesql,
|
11
|
+
ROM::Configuration.new(:yesql, uri, path: path, queries: {reports: report_queries})
|
10
12
|
end
|
11
13
|
|
12
|
-
let(:report_queries) { {
|
14
|
+
let(:report_queries) { {all_users: "SELECT * FROM users ORDER BY %{order}"} }
|
13
15
|
|
14
|
-
let(:users) { container.
|
15
|
-
let(:tasks) { container.
|
16
|
-
let(:reports) { container.
|
16
|
+
let(:users) { container.relations[:users] }
|
17
|
+
let(:tasks) { container.relations[:tasks] }
|
18
|
+
let(:reports) { container.relations[:reports] }
|
17
19
|
|
18
20
|
before do
|
19
21
|
configuration.relation(:users)
|
20
22
|
configuration.relation(:tasks) do
|
21
|
-
query_proc(proc { |_name, query, opts| query.gsub(
|
23
|
+
query_proc(proc { |_name, query, opts| query.gsub(":id:", opts[:id].to_s) })
|
22
24
|
end
|
23
25
|
|
24
26
|
module Test
|
25
27
|
class Reports < ROM::Relation[:yesql]
|
26
|
-
|
28
|
+
schema :reports, infer: true
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
30
32
|
configuration.register_relation(Test::Reports)
|
31
33
|
end
|
32
34
|
|
33
|
-
describe
|
34
|
-
it
|
35
|
-
expect(users.by_name(name:
|
36
|
-
{
|
35
|
+
describe "query method" do
|
36
|
+
it "uses hash-based interpolation by default" do
|
37
|
+
expect(users.by_name(name: "Jane")).to match_array([
|
38
|
+
{id: 1, name: "Jane"}
|
37
39
|
])
|
38
40
|
end
|
39
41
|
|
40
|
-
it
|
42
|
+
it "uses provided proc to preprocess a query" do
|
41
43
|
expect(tasks.by_id(id: 1)).to match_array([
|
42
|
-
{
|
44
|
+
{id: 1, title: "Task One"}
|
43
45
|
])
|
44
46
|
end
|
45
47
|
|
46
|
-
it
|
47
|
-
expect(reports.all_users(order:
|
48
|
-
{
|
49
|
-
{
|
50
|
-
{
|
48
|
+
it "uses queries provided explicitly during setup" do
|
49
|
+
expect(reports.all_users(order: "name").to_a).to eql([
|
50
|
+
{id: 3, name: "Jade"},
|
51
|
+
{id: 1, name: "Jane"},
|
52
|
+
{id: 2, name: "Joe"}
|
51
53
|
])
|
52
54
|
end
|
53
55
|
|
54
|
-
it
|
55
|
-
relation = users.by_name(name:
|
56
|
-
expect(relation).to match_array([
|
56
|
+
it "returns rom relation" do
|
57
|
+
relation = users.by_name(name: "Jane") >> proc { |r| r.map { |t| t[:name] } }
|
58
|
+
expect(relation).to match_array(["Jane"])
|
57
59
|
end
|
58
60
|
end
|
59
61
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_context "database setup" do
|
4
|
+
include_context "gateway setup"
|
3
5
|
|
4
6
|
let!(:conn) { Sequel.connect(uri) }
|
5
7
|
|
6
8
|
def drop_tables
|
7
|
-
[
|
9
|
+
%i[users tasks].each { |name| conn.drop_table?(name) }
|
8
10
|
end
|
9
11
|
|
10
12
|
before do
|
@@ -1,10 +1,12 @@
|
|
1
|
-
|
2
|
-
let(:root) { Pathname(__FILE__).dirname.join('../..') }
|
3
|
-
let(:path) { root.join('spec/fixtures') }
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
RSpec.shared_context "gateway setup" do
|
4
|
+
let(:root) { Pathname(__FILE__).dirname.join("../..") }
|
5
|
+
let(:path) { root.join("spec/fixtures") }
|
6
|
+
|
7
|
+
if RUBY_ENGINE == "jruby"
|
8
|
+
let(:uri) { "jdbc:sqlite://#{root.join("db/test.sqlite")}" }
|
7
9
|
else
|
8
|
-
let(:uri) { "sqlite://#{root.join(
|
10
|
+
let(:uri) { "sqlite://#{root.join("db/test.sqlite")}" }
|
9
11
|
end
|
10
12
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.shared_context "users and tasks" do
|
4
|
+
include_context "database setup"
|
3
5
|
|
4
6
|
before do
|
5
|
-
conn[:users].insert id: 1, name:
|
6
|
-
conn[:users].insert id: 2, name:
|
7
|
-
conn[:users].insert id: 3, name:
|
7
|
+
conn[:users].insert id: 1, name: "Jane"
|
8
|
+
conn[:users].insert id: 2, name: "Joe"
|
9
|
+
conn[:users].insert id: 3, name: "Jade"
|
8
10
|
|
9
|
-
conn[:tasks].insert id: 1, title:
|
10
|
-
conn[:tasks].insert id: 2, title:
|
11
|
+
conn[:tasks].insert id: 1, title: "Task One"
|
12
|
+
conn[:tasks].insert id: 2, title: "Task Two"
|
11
13
|
end
|
12
14
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,29 +1,23 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "bundler"
|
2
4
|
Bundler.setup
|
3
5
|
|
4
|
-
|
5
|
-
require 'yaml'
|
6
|
-
rubies = YAML.load(File.read(File.join(__dir__, '..', '.travis.yml')))['rvm']
|
7
|
-
latest_mri = rubies.select { |v| v =~ /\A\d+\.\d+.\d+\z/ }.max
|
6
|
+
require_relative "support/coverage" if ENV["COVERAGE"] == "true"
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
add_filter '/spec/'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
8
|
+
require_relative "support/warnings"
|
9
|
+
|
10
|
+
Warning.process { |w| raise w } if ENV["FAIL_ON_WARNINGS"].eql?("true")
|
16
11
|
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require 'logger'
|
12
|
+
require "rom-yesql"
|
13
|
+
require "logger"
|
20
14
|
|
21
15
|
begin
|
22
|
-
require
|
23
|
-
rescue LoadError
|
16
|
+
require "byebug"
|
17
|
+
rescue LoadError
|
24
18
|
end
|
25
19
|
|
26
|
-
LOGGER = Logger.new(File.open(
|
20
|
+
LOGGER = Logger.new(File.open("./log/test.log", "a"))
|
27
21
|
|
28
22
|
root = Pathname(__FILE__).dirname
|
29
23
|
|
@@ -41,4 +35,4 @@ RSpec.configure do |config|
|
|
41
35
|
config.warnings = true
|
42
36
|
end
|
43
37
|
|
44
|
-
Dir[root.join(
|
38
|
+
Dir[root.join("shared/*.rb").to_s].each { |f| require f }
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# this file is managed by rom-rb/devtools
|
4
|
+
|
5
|
+
if ENV["COVERAGE"] == "true"
|
6
|
+
require "simplecov"
|
7
|
+
require "simplecov-cobertura"
|
8
|
+
|
9
|
+
SimpleCov.formatter = SimpleCov::Formatter::CoberturaFormatter
|
10
|
+
|
11
|
+
SimpleCov.start do
|
12
|
+
add_filter "/spec/"
|
13
|
+
enable_coverage :branch
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
RSpec.configure do |config|
|
2
|
+
# When no filter given, search and run focused tests
|
3
|
+
config.filter_run_when_matching :focus
|
4
|
+
|
5
|
+
# Disables rspec monkey patches (no reason for their existence tbh)
|
6
|
+
config.disable_monkey_patching!
|
7
|
+
|
8
|
+
# Run ruby in verbose mode
|
9
|
+
config.warnings = true
|
10
|
+
|
11
|
+
# Collect all failing expectations automatically,
|
12
|
+
# without calling aggregate_failures everywhere
|
13
|
+
config.define_derived_metadata do |meta|
|
14
|
+
meta[:aggregate_failures] = true
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# this file is managed by rom-rb/devtools project
|
4
|
+
|
5
|
+
require "warning"
|
6
|
+
|
7
|
+
Warning.ignore(%r{rspec/core})
|
8
|
+
Warning.ignore(%r{rspec/mocks})
|
9
|
+
Warning.ignore(/codacy/)
|
10
|
+
Warning[:experimental] = false if Warning.respond_to?(:[])
|
@@ -1,36 +1,38 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
2
4
|
|
3
5
|
RSpec.describe ROM::Yesql::Gateway do
|
4
|
-
include_context
|
6
|
+
include_context "gateway setup"
|
5
7
|
|
6
|
-
it
|
8
|
+
it "loads queries from file system when :path is provided" do
|
7
9
|
gateway = ROM::Yesql::Gateway.new(uri, path: path)
|
8
10
|
|
9
11
|
expect(gateway.queries.keys).to match_array([:users, :tasks])
|
10
12
|
end
|
11
13
|
|
12
|
-
it
|
13
|
-
queries = {
|
14
|
+
it "combines queries from :queries option and loaded from provided :path" do
|
15
|
+
queries = {reports: {true: "SELECT 1"}}
|
14
16
|
gateway = ROM::Yesql::Gateway.new(uri, path: path, queries: queries)
|
15
17
|
|
16
18
|
expect(gateway.queries.keys).to match_array([:users, :tasks, :reports])
|
17
19
|
end
|
18
20
|
|
19
|
-
it
|
20
|
-
queries = {
|
21
|
+
it "loads queries from :queries option" do
|
22
|
+
queries = {reports: {true: "SELECT 1"}}
|
21
23
|
gateway = ROM::Yesql::Gateway.new(uri, queries: queries)
|
22
24
|
|
23
25
|
expect(gateway.queries).to eql(queries)
|
24
26
|
end
|
25
27
|
|
26
|
-
it
|
28
|
+
it "loads empty queries hash when no options were provided" do
|
27
29
|
gateway = ROM::Yesql::Gateway.new(uri)
|
28
30
|
|
29
31
|
expect(gateway.queries).to eql({})
|
30
32
|
end
|
31
33
|
|
32
|
-
it
|
33
|
-
queries = {
|
34
|
+
it "freezes queries" do
|
35
|
+
queries = {reports: {true: "SELECT 1"}}
|
34
36
|
gateway = ROM::Yesql::Gateway.new(uri, queries: queries)
|
35
37
|
|
36
38
|
expect(gateway.queries).to be_frozen
|