sql_runner 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: []