sql_runner 0.1.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0fe73046f6047d45f926dcc2a2dfe481698d6c27
4
- data.tar.gz: fdabc17b0da986f3e0f1676dbc35d1b74ca0510c
2
+ SHA256:
3
+ metadata.gz: 7a50f9a5b18f7be9951324422fdeaeccc9c730bd4d65fcb4d35549ef1ce74fee
4
+ data.tar.gz: a4f6d679838c59c469cf456965d8e76bddc96b0a5747c3c9b7ce1a40ce6747c3
5
5
  SHA512:
6
- metadata.gz: 539aa4ac64c12629feb865ffde679507bc00a0951353261c42fbd4fcf547228593d2bc0675cf792c94f065ff908c9b8eb1f8239f673f883ff07d2c4789fa73aa
7
- data.tar.gz: 014fa997673cd75e241ca74e667d7f3fb31b7b40acb1a044c0f983272cd7543e8b61e31bbdebb092b362ae0771c73109776d491608981a47019bec73c28059ce
6
+ metadata.gz: 98aacdc458f23e6a47c462e5665c7c20dd9fc966af5d597e20aa1e572bf33b589407b415fe2e326c224c641103b3f4aba60ef5f720a2902dda1c5ab74249e5ef
7
+ data.tar.gz: 3972eba432a3cb7aa5f67796b80db01206e82f56770350054bb6c544f1ed5af93c198486f6bf520765ccf8b26e166b9a5fea82140da72c7f93064b922d6877a5
data/.gitignore CHANGED
@@ -1,6 +1,6 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
3
+ Gemfile.lock
4
4
  /_yardoc/
5
5
  /coverage/
6
6
  /doc/
@@ -0,0 +1,6 @@
1
+ ---
2
+ inherit_gem:
3
+ rubocop-fnando: .rubocop.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.6
@@ -1,13 +1,29 @@
1
+ ---
1
2
  language: ruby
2
3
  cache: bundler
3
4
  sudo: false
4
5
  rvm:
5
- - 2.3.1
6
+ - 2.7.0
7
+ services:
8
+ - mysql
9
+ addons:
10
+ postgresql: "10"
11
+ apt:
12
+ packages:
13
+ - postgresql-10
14
+ - postgresql-client-10
15
+ before_script:
16
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
17
+ - chmod +x ./cc-test-reporter
18
+ - "./cc-test-reporter before-build"
19
+ after_script:
20
+ - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
6
21
  before_install:
7
- - gem install bundler
8
- - createdb test
22
+ - gem install bundler
23
+ - createdb test
24
+ - mysql -e 'CREATE DATABASE IF NOT EXISTS test;'
9
25
  notifications:
10
26
  email: false
11
27
  env:
12
28
  global:
13
- secure: S5CYGmnmHV6FE/P0W2H7sEJwR3jGcuW97wIzNLBSDkl1Nvmc2NAw6WynoqOGSEVafmauVjX+w+gOkF2UgJImBYwDjwGmSVcKSPj1SWuuT648pq5mJjW4kyS/lKnA8PaiqS1nMVAbGHtZjH3cEG0w0oFPilDN7nsCCzm4kztkRWtZgHhGPc/UU0EYjsGkUVq3gsYFNm09dzMxzmg9U8jdOLUM354mxP2FKqBQ795/HkEXtb5mGSKnSBWB4jdk9enmBe/M6/Vvo9X98drz4GRVdHpvy5LvWPwYSvwKNprErPcIasLxONOUXTEzA45/RSJZBLUuGlrNu7f9tA9JNbrUaVRp+vnhRpue5nNYIowPUVOnjxfE/qgx3X4k5K26pbO6wKfhdDYRK6Qh85rYNuHpd0caiEoTJJlXQp6sTo/wKQI5p9BF4b3FRG1RtCoMbjLFrQin4l0JwILoAyGyTbk50XdQvwDDlFs1lGiGxe0AK0lxX6s5yqdykaXkx5qwTSuWZqFc+9+bAEy6TNzEqBuT+r1mxIfVep8bNxynDLRg26NibGAFHzMHuqgEM4mLeOUkKnBDv1LghRJ0fzhroINJHAj5KBp145r6iJSVR7xRjKJpQptpIZ3asi5Xl37sQb98+p+1Pg4Wwzn9Y8lEyx49lml7oppDvabcbOCTy0LFuuk=
29
+ secure: 4dDrl8nCItKPRKpoA2KJVWsDm3o7U0pIsdY8t19pJXbziteT3zw5pEmFh+/qWGB1VszzFFZzXcZCIoKv3NX/x24g+LU+qvL7vLYLyhUR8ZjR4rGzGkwBCgEYBWgVtqg9ncYTbYsdbAqryt6f+HvpFj8EFvGSjIWVqJyh59qHdwAVT+BUKjllEH+t5Dbjd2knIQw83af+0A5ljP2uMziNcuHD7MUBIKY1DfFnBYQ5YA50o/mZe8sG5h6bZU/sf0pdoa+z2xDIJOPO7qaCwANACetDtsfs1DN39DsubvlFLg0s2z0XCuYyWSsJQ4zhRipHgnqYn+Rmpql17t0WmhVPA1xvLyk0/4X8rjRcYyYHMM3ryga5bnrpvSiPsqG+JFNhDczpN394KGa7o+/jCuNA0MVFcCzsvW2AMkYpUbPtADY7/Tl4iUJWmFbl0nO1n1wh5dDJ7Wo7mdkPAmdV7hNmMUmHbPeh8mSjMnuS2gcMc11wDgmR56TEMu/B7LUM31og7L+JouEJAOWtzThtpdYLpqDQ3Xe1G5uMl1oZ0lNOqag5Bg+AQCAIGr1N4G2m8fI74M9lUQUfhu87L+zycYMHInOH+Czc+RamlkH3vLl9Fu6aOKoXA0+zh85sVDj3Er+X2NEHaoRe4PSkOHOBNYSkAUd36TYMt8J5MgAD0w7HqmY=
data/Gemfile CHANGED
@@ -1,2 +1,4 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
  gemspec
data/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  # SQLRunner
2
2
 
3
- [![Travis-CI](https://travis-ci.org/fnando/sql_runner.png)](https://travis-ci.org/fnando/sql_runner)
3
+ [![Travis-CI](https://travis-ci.org/fnando/sql_runner.svg)](https://travis-ci.org/fnando/sql_runner)
4
4
  [![Code Climate](https://codeclimate.com/github/fnando/sql_runner/badges/gpa.svg)](https://codeclimate.com/github/fnando/sql_runner)
5
5
  [![Test Coverage](https://codeclimate.com/github/fnando/sql_runner/badges/coverage.svg)](https://codeclimate.com/github/fnando/sql_runner/coverage)
6
6
  [![Gem](https://img.shields.io/gem/v/sql_runner.svg)](https://rubygems.org/gems/sql_runner)
7
7
  [![Gem](https://img.shields.io/gem/dt/sql_runner.svg)](https://rubygems.org/gems/sql_runner)
8
8
 
9
- SQLRunner allows you to load your queries out of SQL files, without using ORMs. Available only for PostgreSQL.
9
+ SQLRunner allows you to load your queries out of SQL files, without using ORMs. Available for PostgreSQL and MySQL.
10
10
 
11
11
  ## Installation
12
12
 
@@ -145,8 +145,11 @@ module ReverseRecords
145
145
  super(**bind_vars).to_a.reverse
146
146
  end
147
147
  end
148
+ ```
148
149
 
149
150
  # Register the plugin.
151
+
152
+ ```ruby
150
153
  SQLRunner::Query.register_plugin :reverse, ReverseRecords
151
154
 
152
155
  class Users < SQLRunner::Query
@@ -157,7 +160,7 @@ end
157
160
  Users.call
158
161
  ```
159
162
 
160
- If you plugin can receive options, you can call it as `plugin reverse: options`, where `options` can be anything (e.g. `Hash`, `Array`, `Object`, etc).
163
+ If your plugin can receive options, you can call it as `plugin reverse: options`, where `options` can be anything (e.g. `Hash`, `Array`, `Object`, etc).
161
164
 
162
165
  ## Benchmarks
163
166
 
data/Rakefile CHANGED
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
2
4
  require "rake/testtask"
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
7
  t.libs << "test"
6
8
  t.libs << "lib"
7
- t.test_files = FileList['test/**/*_test.rb']
9
+ t.test_files = FileList["test/**/*_test.rb"]
8
10
  t.warning = false
9
11
  end
10
12
 
11
- task :default => :test
13
+ task default: :test
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
4
  require "bundler/setup"
4
5
  require "sql_runner"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.push File.expand_path("#{__dir__}/../lib")
2
4
  require "sql_runner"
3
5
  require "virtus"
@@ -13,7 +15,9 @@ SQLRunner.pool = 25
13
15
  SQLRunner.timeout = 10
14
16
  SQLRunner.root_dir = "#{__dir__}/sql"
15
17
 
16
- ActiveRecord::Base.establish_connection("#{connection_string}&prepared_statements=false&pool=25")
18
+ ActiveRecord::Base.establish_connection(
19
+ "#{connection_string}&prepared_statements=false&pool=25"
20
+ )
17
21
 
18
22
  module Types
19
23
  include Dry::Types.module
@@ -77,10 +81,22 @@ class Users < SQLRunner::Query
77
81
  end
78
82
 
79
83
  Benchmark.ips do |x|
80
- x.report("activerecord - find one ") { User.find_by_email("me@fnando.com") }
81
- x.report(" sql_runner - find one (dry-types)") { FindUserDry.call(email: "me@fnando.com") }
82
- x.report(" sql_runner - find one (virtus) ") { FindUserVirtus.call(email: "me@fnando.com") }
83
- x.report(" sql_runner - find one (raw) ") { FindUser.call(email: "me@fnando.com") }
84
+ x.report("activerecord - find one") do
85
+ User.find_by_email("me@fnando.com")
86
+ end
87
+
88
+ x.report(" sql_runner - find one (dry-types)") do
89
+ FindUserDry.call(email: "me@fnando.com")
90
+ end
91
+
92
+ x.report(" sql_runner - find one (virtus)") do
93
+ FindUserVirtus.call(email: "me@fnando.com")
94
+ end
95
+
96
+ x.report(" sql_runner - find one (raw)") do
97
+ FindUser.call(email: "me@fnando.com")
98
+ end
99
+
84
100
  x.compare!
85
101
  end
86
102
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.push File.expand_path("#{__dir__}/../lib")
2
4
  require "sql_runner"
3
5
  require "ruby-prof"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.push File.expand_path("#{__dir__}/../lib")
2
4
  require "sql_runner"
3
5
  require "virtus"
@@ -7,15 +9,17 @@ SQLRunner.pool = 25
7
9
  SQLRunner.timeout = 10
8
10
  SQLRunner.root_dir = "#{__dir__}/sql"
9
11
 
10
- result = SQLRunner.execute "select application_name from pg_stat_activity where pid = pg_backend_pid();"
12
+ result = SQLRunner.execute(
13
+ "select application_name from pg_stat_activity where pid = pg_backend_pid();"
14
+ )
11
15
  p result.to_a
12
16
 
13
- result = SQLRunner.execute <<-SQL, name: "john", age: 18
14
- select
15
- 'hello'::text as message,
16
- :name::text as name,
17
- :age::integer as age,
18
- :name::text as name2
17
+ result = SQLRunner.execute <<~SQL, name: "john", age: 18
18
+ select
19
+ 'hello'::text as message,
20
+ :name::text as name,
21
+ :age::integer as age,
22
+ :name::text as name2
19
23
  SQL
20
24
  p result.to_a
21
25
 
@@ -86,8 +90,8 @@ p FindCustomer.call!(email: "me@fnando.com")
86
90
 
87
91
  begin
88
92
  FindUser.call!(email: "me@fnando.coms")
89
- rescue SQLRunner::RecordNotFound => error
90
- p error
93
+ rescue SQLRunner::RecordNotFound => e
94
+ p e
91
95
  end
92
96
 
93
97
  SQLRunner.disconnect
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "uri"
2
4
  require "connection_pool"
3
5
 
@@ -17,11 +19,13 @@ module SQLRunner
17
19
 
18
20
  Adapters.register("postgres", Adapters::PostgreSQL)
19
21
  Adapters.register("postgresql", Adapters::PostgreSQL)
22
+ Adapters.register("mysql", Adapters::MySQL)
23
+ Adapters.register("mysql2", Adapters::MySQL)
20
24
 
21
25
  Query.register_plugin :one, Query::One
22
26
  Query.register_plugin :many, Query::Many
23
27
  Query.register_plugin :model, Query::Model
24
28
 
25
- self.timeout = ENV.fetch("SQL_CONNECTION_TIMEOUT", 5)
26
- self.pool = ENV.fetch("SQL_CONNECTION_POOL", 5)
29
+ self.timeout = Integer(ENV.fetch("SQL_CONNECTION_TIMEOUT", 5))
30
+ self.pool = Integer(ENV.fetch("SQL_CONNECTION_POOL", 5))
27
31
  end
@@ -1,20 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  UnsupportedDatabase = Class.new(StandardError)
3
- MissingDependency = Class.new(StandardError)
5
+ MissingDependency = Class.new(StandardError)
6
+
7
+ def self.adapter_registry
8
+ @adapter_registry ||= {}
9
+ end
4
10
 
5
11
  module Adapters
6
12
  require "sql_runner/adapters/postgresql"
7
-
8
- ADAPTERS = {}
13
+ require "sql_runner/adapters/mysql"
9
14
 
10
15
  def self.register(name, adapter)
11
- ADAPTERS[name] = adapter
16
+ SQLRunner.adapter_registry[name] = adapter
12
17
  end
13
18
 
14
19
  def self.find(name)
15
- ADAPTERS
16
- .fetch(name) { fail UnsupportedDatabase, "#{name} is not supported by SQLRunner" }
17
- .tap {|adapter| adapter.load }
20
+ adapter = SQLRunner.adapter_registry.fetch(name) do
21
+ raise UnsupportedDatabase, "#{name} is not supported by SQLRunner"
22
+ end
23
+
24
+ adapter.tap(&:load)
18
25
  end
19
26
  end
20
27
  end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SQLRunner
4
+ module Adapters
5
+ class MySQL
6
+ InvalidPreparedStatement = Class.new(StandardError)
7
+
8
+ def self.load
9
+ require "mysql2"
10
+ rescue LoadError
11
+ raise MissingDependency, "make sure the `mysql2` gem is available"
12
+ end
13
+
14
+ def initialize(connection_string)
15
+ @connection_string = connection_string
16
+ @uri = URI.parse(@connection_string)
17
+ connect
18
+ end
19
+
20
+ def connect(started = Process.clock_gettime(Process::CLOCK_MONOTONIC))
21
+ @connection = Mysql2::Client.new(
22
+ host: @uri.host,
23
+ port: @uri.port,
24
+ username: @uri.user,
25
+ password: @uri.password,
26
+ database: @uri.path[1..-1]
27
+ )
28
+ rescue Mysql2::Error
29
+ ended = Process.clock_gettime(Process::CLOCK_MONOTONIC)
30
+
31
+ raise unless ended - started < SQLRunner.timeout
32
+
33
+ sleep 0.1
34
+ connect(started)
35
+ end
36
+
37
+ def disconnect
38
+ @connection&.close && (@connection = nil)
39
+ end
40
+
41
+ def reconnect
42
+ disconnect
43
+ connect
44
+ end
45
+
46
+ def execute(query, **bind_vars)
47
+ bound_query, bindings, names = parse(query, bind_vars)
48
+ validate_bindings(query, bind_vars, names)
49
+
50
+ statement = @connection.prepare(bound_query)
51
+ statement.execute(*bindings, cast: true)
52
+ rescue Mysql2::Error
53
+ reconnect
54
+ execute(query, **bind_vars)
55
+ end
56
+
57
+ def active?
58
+ !@connection&.closed?
59
+ rescue Mysql2::Error
60
+ false
61
+ end
62
+
63
+ def to_s
64
+ %[#<#{self.class.name} #{format('0x00%x', (object_id << 1))}>]
65
+ end
66
+
67
+ def inspect
68
+ to_s
69
+ end
70
+
71
+ def parse(query, bind_vars)
72
+ bindings = []
73
+ names = []
74
+
75
+ parsed_query = query.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
76
+ next match if Regexp.last_match(1) == ":" # skip type casting
77
+
78
+ name = match[1..-1]
79
+ sym_name = name.to_sym
80
+ names << sym_name
81
+ bindings << bind_vars[sym_name]
82
+
83
+ "?"
84
+ end
85
+
86
+ [parsed_query, bindings, names]
87
+ end
88
+
89
+ private def validate_bindings(query, bind_vars, names)
90
+ names.each do |name|
91
+ next if bind_vars.key?(name)
92
+
93
+ raise InvalidPreparedStatement,
94
+ "missing value for :#{name} in #{query}"
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  module Adapters
3
5
  class PostgreSQL
@@ -6,7 +8,7 @@ module SQLRunner
6
8
  def self.load
7
9
  require "pg"
8
10
  rescue LoadError
9
- fail MissingDependency, "make sure the pg gem is available"
11
+ raise MissingDependency, "make sure the `pg` gem is available"
10
12
  end
11
13
 
12
14
  def initialize(connection_string)
@@ -19,16 +21,14 @@ module SQLRunner
19
21
  rescue PG::ConnectionBad
20
22
  ended = Process.clock_gettime(Process::CLOCK_MONOTONIC)
21
23
 
22
- if ended - started < SQLRunner.timeout
23
- sleep 0.1
24
- connect(started)
25
- else
26
- raise
27
- end
24
+ raise unless ended - started < SQLRunner.timeout
25
+
26
+ sleep 0.1
27
+ connect(started)
28
28
  end
29
29
 
30
30
  def disconnect
31
- @connection && @connection.close && (@connection = nil)
31
+ @connection&.close && (@connection = nil)
32
32
  end
33
33
 
34
34
  def reconnect
@@ -36,14 +36,10 @@ module SQLRunner
36
36
  connect
37
37
  end
38
38
 
39
- def connection
40
- @connection
41
- end
42
-
43
39
  def execute(query, **bind_vars)
44
- query, bindings = parse(query)
40
+ bound_query, bindings = parse(query)
45
41
  args = extract_args(query, bindings, bind_vars)
46
- @connection.exec_params(query, args)
42
+ @connection.exec_params(bound_query, args)
47
43
  rescue PG::ConnectionBad
48
44
  reconnect
49
45
  execute(query, **bind_vars)
@@ -56,24 +52,24 @@ module SQLRunner
56
52
  end
57
53
 
58
54
  def to_s
59
- %[#<#{self.class.name} #{"0x00%x" % (object_id << 1)}>]
55
+ %[#<#{self.class.name} #{format('0x00%x', (object_id << 1))}>]
60
56
  end
61
57
 
62
58
  def inspect
63
59
  to_s
64
60
  end
65
61
 
66
- def parse(query)
62
+ def parse(query) # rubocop:disable Metrics/MethodLength
67
63
  bindings = {}
68
64
  count = 0
69
65
 
70
66
  parsed_query = query.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
71
- next match if $1 == ":" # skip type casting
67
+ next match if Regexp.last_match(1) == ":" # skip type casting
72
68
 
73
69
  name = match[1..-1]
74
70
  sym_name = name.to_sym
75
71
 
76
- if (!index = bindings[sym_name])
72
+ unless (index = bindings[sym_name])
77
73
  index = (count += 1)
78
74
  bindings[sym_name] = index
79
75
  end
@@ -86,7 +82,10 @@ module SQLRunner
86
82
 
87
83
  private def extract_args(query, bindings, bind_vars)
88
84
  bindings.each_with_object([]) do |(name, position), buffer|
89
- buffer[position - 1] = bind_vars.fetch(name) { fail InvalidPreparedStatement, "missing value for :#{name} in #{query}" }
85
+ buffer[position - 1] = bind_vars.fetch(name) do
86
+ raise InvalidPreparedStatement,
87
+ "missing value for :#{name} in #{query}"
88
+ end
90
89
  end
91
90
  end
92
91
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  module Configuration
3
5
  attr_accessor :root_dir
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  module Connection
3
5
  def self.call(connection_string)
@@ -18,7 +20,7 @@ module SQLRunner
18
20
  end
19
21
 
20
22
  def disconnect
21
- connection_pool && connection_pool.shutdown {|conn| conn.disconnect } && (@connection_pool = nil)
23
+ connection_pool&.shutdown(&:disconnect) && (@connection_pool = nil)
22
24
  end
23
25
 
24
26
  def connection_pool
@@ -1,12 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
- RecordNotFound = Class.new(StandardError)
3
- PluginNotFound = Class.new(StandardError)
4
+ RecordNotFound = Class.new(StandardError)
5
+ PluginNotFound = Class.new(StandardError)
4
6
  InvalidPluginOrder = Class.new(StandardError)
7
+ NotImplemented = Class.new(StandardError)
8
+
9
+ def self.plugin_registry
10
+ @plugin_registry ||= {}
11
+ end
5
12
 
6
13
  class Query
7
14
  extend Runner
8
15
 
9
- PLUGINS = {}
16
+ def self.inherited(subclass)
17
+ subclass.instance_variable_set(:@connection_pool, @connection_pool)
18
+ subclass.instance_variable_set(:@root_dir, @root_dir)
19
+ end
10
20
 
11
21
  def self.query_name(*values)
12
22
  @query_name = values.first if values.any?
@@ -14,9 +24,13 @@ module SQLRunner
14
24
  end
15
25
 
16
26
  def self.query_name_from_class
27
+ replacer = proc do
28
+ "#{Regexp.last_match(1)}_#{Regexp.last_match(2).downcase}"
29
+ end
30
+
17
31
  name
18
32
  .gsub("::", "/")
19
- .gsub(/([a-z0-9])([A-Z])/) { "#{$1}_#{$2.downcase}" }
33
+ .gsub(/([a-z0-9])([A-Z])/, &replacer)
20
34
  .downcase
21
35
  end
22
36
 
@@ -39,24 +53,27 @@ module SQLRunner
39
53
  end
40
54
 
41
55
  def self.register_plugin(name, mod)
42
- PLUGINS[name] = mod
56
+ SQLRunner.plugin_registry[name] = mod
43
57
  end
44
58
 
45
59
  def self.plugin(*names)
46
- plugins *names
60
+ plugins(*names)
47
61
  end
48
62
 
49
63
  def self.plugins(*names)
50
64
  names = prepare_plugins_with_options(names)
51
65
 
52
66
  names.each do |name, options|
53
- plugin = PLUGINS.fetch(name) { fail PluginNotFound, "#{name.inspect} wasn't found" }
67
+ plugin = SQLRunner.plugin_registry.fetch(name) do
68
+ raise PluginNotFound, "#{name.inspect} wasn't found"
69
+ end
70
+
54
71
  plugin.activate(self, options)
55
72
  end
56
73
  end
57
74
 
58
75
  def self.prepare_plugins_with_options(plugins)
59
- return plugins unless plugins.last.kind_of?(Hash)
76
+ return plugins unless plugins.last.is_a?(Hash)
60
77
 
61
78
  plugins_with_options = plugins.pop
62
79
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  class Query
3
5
  module Many
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  class Query
3
5
  module Model
@@ -13,7 +15,7 @@ module SQLRunner
13
15
  def call(**bind_vars)
14
16
  result = super(**bind_vars)
15
17
  return unless result
16
- return model.new(result) if result.kind_of?(Hash)
18
+ return model.new(result) if result.is_a?(Hash)
17
19
 
18
20
  result.to_a.map do |attrs|
19
21
  model.new(attrs)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  class Query
3
5
  module One
@@ -11,7 +13,14 @@ module SQLRunner
11
13
  end
12
14
 
13
15
  def call!(**bind_vars)
14
- call(**bind_vars) or fail SQLRunner::RecordNotFound, "#{name}: record was not found with #{bind_vars.inspect} arguments"
16
+ result = call(**bind_vars)
17
+
18
+ return if result
19
+
20
+ raise(
21
+ SQLRunner::RecordNotFound,
22
+ "#{name}: record was not found with #{bind_vars.inspect} arguments"
23
+ )
15
24
  end
16
25
  end
17
26
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
4
  module Runner
3
5
  include Connection
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module SQLRunner
2
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
3
5
  end
@@ -1,28 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "./lib/sql_runner/version"
2
4
 
3
5
  Gem::Specification.new do |spec|
4
6
  spec.name = "sql_runner"
5
7
  spec.version = SQLRunner::VERSION
6
8
  spec.authors = ["Nando Vieira"]
7
- spec.email = ["fnando.vieira@gmail.com"]
9
+ spec.email = ["me@fnando.com"]
10
+
11
+ spec.summary = <<~TEXT.gsub(/\n/, " ")
12
+ SQLRunner allows you to load your queries out of SQL files, without using
13
+ ORMs.
14
+ TEXT
8
15
 
9
- spec.summary = "SQLRunner allows you to load your queries out of SQL files, without using ORMs. Available only for PostgreSQL."
10
16
  spec.description = spec.summary
11
17
  spec.homepage = "https://github.com/fnando/sql_runner"
12
18
  spec.license = "MIT"
13
19
 
14
- spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
20
+ spec.files = `git ls-files -z`
21
+ .split("\x0")
22
+ .reject {|f| f.match(%r{^(test|spec|features)/}) }
15
23
  spec.bindir = "exe"
16
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
24
+ spec.executables = spec.files.grep(%r{^exe/}) {|f| File.basename(f) }
17
25
  spec.require_paths = ["lib"]
18
26
 
19
27
  spec.add_dependency "connection_pool"
20
28
 
21
29
  spec.add_development_dependency "bundler"
22
- spec.add_development_dependency "rake"
23
30
  spec.add_development_dependency "minitest-utils"
24
- spec.add_development_dependency "pry-meta"
25
- spec.add_development_dependency "pg"
26
31
  spec.add_development_dependency "mocha"
27
- spec.add_development_dependency "codeclimate-test-reporter"
32
+ spec.add_development_dependency "mysql2"
33
+ spec.add_development_dependency "pg"
34
+ spec.add_development_dependency "pry-meta"
35
+ spec.add_development_dependency "rake"
36
+ spec.add_development_dependency "simplecov"
28
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sql_runner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-06-07 00:00:00.000000000 Z
11
+ date: 2020-01-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rake
42
+ name: minitest-utils
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: minitest-utils
56
+ name: mocha
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: pry-meta
70
+ name: mysql2
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -95,7 +95,21 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: mocha
98
+ name: pry-meta
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
115
  - - ">="
@@ -109,7 +123,7 @@ dependencies:
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
- name: codeclimate-test-reporter
126
+ name: simplecov
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
129
  - - ">="
@@ -123,17 +137,19 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  description: SQLRunner allows you to load your queries out of SQL files, without using
126
- ORMs. Available only for PostgreSQL.
140
+ ORMs.
127
141
  email:
128
- - fnando.vieira@gmail.com
142
+ - me@fnando.com
129
143
  executables: []
130
144
  extensions: []
131
145
  extra_rdoc_files: []
132
146
  files:
133
147
  - ".gitignore"
148
+ - ".rubocop.yml"
134
149
  - ".travis.yml"
135
150
  - CODE_OF_CONDUCT.md
136
151
  - Gemfile
152
+ - Gemfile.lock
137
153
  - LICENSE.txt
138
154
  - README.md
139
155
  - Rakefile
@@ -148,6 +164,7 @@ files:
148
164
  - examples/test.rb
149
165
  - lib/sql_runner.rb
150
166
  - lib/sql_runner/adapters.rb
167
+ - lib/sql_runner/adapters/mysql.rb
151
168
  - lib/sql_runner/adapters/postgresql.rb
152
169
  - lib/sql_runner/configuration.rb
153
170
  - lib/sql_runner/connection.rb
@@ -177,10 +194,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
177
194
  - !ruby/object:Gem::Version
178
195
  version: '0'
179
196
  requirements: []
180
- rubyforge_project:
181
- rubygems_version: 2.5.1
197
+ rubygems_version: 3.1.2
182
198
  signing_key:
183
199
  specification_version: 4
184
200
  summary: SQLRunner allows you to load your queries out of SQL files, without using
185
- ORMs. Available only for PostgreSQL.
201
+ ORMs.
186
202
  test_files: []