stairwell 0.3.0 → 0.6.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
2
  SHA256:
3
- metadata.gz: e963ad4c2388946d0baae50090e6f3e9913e49dcdd896cdd18403861d72b9a40
4
- data.tar.gz: 29cb2a589732e6e4b0b43115da878d8b4463eb59a1ad46726d01595bc0f56f19
3
+ metadata.gz: c3a4932425e6273ba11f06755995cc39d7045566808bd60870e5ed3ae866bc1a
4
+ data.tar.gz: 5694267cbbc05428eb8161c244d7d9ead34c21ee6999156a3046c08a736e524d
5
5
  SHA512:
6
- metadata.gz: 0d21bd2ad1fc8a8b04de7da744dae787a474a33fbb42146a4b77d218d5ee493c25ed930da39b23a4ce45a67448920924e5d2a4006ba62978422caf3c43156395
7
- data.tar.gz: 229bc47578fea9e530d10291d79d94bcd042222e767f5627b45e4b7867af09e76958a34b9d4208b6763c1d89fcea5399317ad6c4047c547e2bae11e62361f61c
6
+ metadata.gz: fdcb61bf3e077028063dc94ecdef023aaccc709fd326cdce4354af181be15c84fbd805b492a324bd6d2117a84c6981b481835cf5ebb879ae84fda9ae2077cbca
7
+ data.tar.gz: cbb08179152c8bb7205c2d469afe0794e8505757bd65b248e53e7d6f6639fd42fa87a0523bd42993a64e97c47363d702bb90d48f72540ed63468624a49a5b4f4
data/.bin/bundle ADDED
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "rubygems"
12
+
13
+ m = Module.new do
14
+ module_function
15
+
16
+ def invoked_as_script?
17
+ File.expand_path($0) == File.expand_path(__FILE__)
18
+ end
19
+
20
+ def env_var_version
21
+ ENV["BUNDLER_VERSION"]
22
+ end
23
+
24
+ def cli_arg_version
25
+ return unless invoked_as_script? # don't want to hijack other binstubs
26
+ return unless "update".start_with?(ARGV.first || " ") # must be running `bundle update`
27
+ bundler_version = nil
28
+ update_index = nil
29
+ ARGV.each_with_index do |a, i|
30
+ if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
31
+ bundler_version = a
32
+ end
33
+ next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
34
+ bundler_version = $1
35
+ update_index = i
36
+ end
37
+ bundler_version
38
+ end
39
+
40
+ def gemfile
41
+ gemfile = ENV["BUNDLE_GEMFILE"]
42
+ return gemfile if gemfile && !gemfile.empty?
43
+
44
+ File.expand_path("../Gemfile", __dir__)
45
+ end
46
+
47
+ def lockfile
48
+ lockfile =
49
+ case File.basename(gemfile)
50
+ when "gems.rb" then gemfile.sub(/\.rb$/, ".locked")
51
+ else "#{gemfile}.lock"
52
+ end
53
+ File.expand_path(lockfile)
54
+ end
55
+
56
+ def lockfile_version
57
+ return unless File.file?(lockfile)
58
+ lockfile_contents = File.read(lockfile)
59
+ return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
60
+ Regexp.last_match(1)
61
+ end
62
+
63
+ def bundler_requirement
64
+ @bundler_requirement ||=
65
+ env_var_version ||
66
+ cli_arg_version ||
67
+ bundler_requirement_for(lockfile_version)
68
+ end
69
+
70
+ def bundler_requirement_for(version)
71
+ return "#{Gem::Requirement.default}.a" unless version
72
+
73
+ bundler_gem_version = Gem::Version.new(version)
74
+
75
+ bundler_gem_version.approximate_recommendation
76
+ end
77
+
78
+ def load_bundler!
79
+ ENV["BUNDLE_GEMFILE"] ||= gemfile
80
+
81
+ activate_bundler
82
+ end
83
+
84
+ def activate_bundler
85
+ gem_error = activation_error_handling do
86
+ gem "bundler", bundler_requirement
87
+ end
88
+ return if gem_error.nil?
89
+ require_error = activation_error_handling do
90
+ require "bundler/version"
91
+ end
92
+ return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
93
+ warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
94
+ exit 42
95
+ end
96
+
97
+ def activation_error_handling
98
+ yield
99
+ nil
100
+ rescue StandardError, LoadError => e
101
+ e
102
+ end
103
+ end
104
+
105
+ m.load_bundler!
106
+
107
+ if m.invoked_as_script?
108
+ load Gem.bin_path("bundler", "bundle")
109
+ end
data/.bin/coderay ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'coderay' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("coderay", "coderay")
data/.bin/pry ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'pry' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("pry", "pry")
data/.bin/rake ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
+
13
+ bundle_binstub = File.expand_path("bundle", __dir__)
14
+
15
+ if File.file?(bundle_binstub)
16
+ if File.read(bundle_binstub, 300).include?("This file was generated by Bundler")
17
+ load(bundle_binstub)
18
+ else
19
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
20
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
21
+ end
22
+ end
23
+
24
+ require "rubygems"
25
+ require "bundler/setup"
26
+
27
+ load Gem.bin_path("rake", "rake")
data/Gemfile CHANGED
@@ -1,8 +1,6 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in stairwell.gemspec
4
6
  gemspec
5
-
6
- gem "rake", "~> 12.0"
7
- gem "minitest", "~> 5.0"
8
- gem "pry"
data/Gemfile.lock CHANGED
@@ -1,9 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- stairwell (0.3.0)
4
+ stairwell (0.6.0)
5
5
  activerecord (>= 4.2.11)
6
+ rake
6
7
  sqlite3
8
+ zeitwerk (~> 2.5)
7
9
 
8
10
  GEM
9
11
  remote: https://rubygems.org/
@@ -26,36 +28,27 @@ GEM
26
28
  tzinfo (~> 2.0)
27
29
  base64 (0.1.1)
28
30
  bigdecimal (3.1.4)
29
- coderay (1.1.3)
30
31
  concurrent-ruby (1.2.2)
31
32
  connection_pool (2.4.1)
32
33
  drb (2.1.1)
33
34
  ruby2_keywords
34
35
  i18n (1.14.1)
35
36
  concurrent-ruby (~> 1.0)
36
- method_source (1.0.0)
37
- mini_portile2 (2.8.5)
38
37
  minitest (5.20.0)
39
38
  mutex_m (0.1.2)
40
- pry (0.13.1)
41
- coderay (~> 1.1)
42
- method_source (~> 1.0)
43
- rake (12.3.3)
39
+ rake (13.1.0)
44
40
  ruby2_keywords (0.0.5)
45
- sqlite3 (1.6.7)
46
- mini_portile2 (~> 2.8.0)
41
+ sqlite3 (1.6.7-x86_64-darwin)
47
42
  timeout (0.4.0)
48
43
  tzinfo (2.0.6)
49
44
  concurrent-ruby (~> 1.0)
45
+ zeitwerk (2.6.12)
50
46
 
51
47
  PLATFORMS
52
- ruby
48
+ x86_64-darwin-20
53
49
 
54
50
  DEPENDENCIES
55
- minitest (~> 5.0)
56
- pry
57
- rake (~> 12.0)
58
51
  stairwell!
59
52
 
60
53
  BUNDLED WITH
61
- 2.1.4
54
+ 2.4.10
data/README.md CHANGED
@@ -83,6 +83,22 @@ They types of the binds are validated too.
83
83
  The names binds in your sql are also validated.
84
84
  All types are quoted using ActiveRecord quoting, which will be different depending on your database type (Mysql, postgres etc.)
85
85
 
86
+ ## SQL files
87
+ Support for sql files is being trialed. If you would like to reference raw sql file instead of quoting the sql in the ruby file, you can. You just have to place the file adjacent to the ruby file and name them the same eq: ruby file is `users_count.rb` the file would need to be in the same directory and named `users_count.sql`. You also need to set the path in your config:
88
+
89
+ ```ruby
90
+ # in ruby project:
91
+ Stairwell.configure do |config|
92
+ config.path = './app/queries/'
93
+ end
94
+
95
+ # in Rails:
96
+ Stairwell.configure do |config|
97
+ config.path = "#{Rails.root}/app/queries"
98
+ end
99
+
100
+ ```
101
+
86
102
  ## Supported Types
87
103
 
88
104
  | Type | Values Accepted | Info |
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
8
10
  end
9
11
 
10
- task :default => :test
12
+ task default: :test
data/bin/console CHANGED
@@ -1,14 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "stairwell"
4
+ require 'bundler/setup'
5
+ require 'stairwell'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
8
9
 
9
10
  # (If you use this, don't forget to add pry to your Gemfile!)
10
- require "pry"
11
- Pry.start
12
11
 
13
- # require "irb"
14
- # IRB.start(__FILE__)
12
+ require 'irb'
13
+ IRB.start(__FILE__)
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Stairwell
2
4
  class BindTransformer
3
-
4
- attr_accessor :sql, :bind_hash, :depleting_bind_hash, :converted_sql
5
+ attr_reader :sql, :bind_hash, :depleting_bind_hash, :converted_sql
5
6
 
6
7
  def initialize(sql, bind_hash)
7
8
  @sql = sql
@@ -16,32 +17,33 @@ module Stairwell
16
17
  # and error will raise
17
18
  # The sql string will then have the appropropriate values substituted
18
19
  # with quoted values to ensure safety.
19
- # Note: $2 is The match for the first, second, etc. parenthesized groups in the last regex
20
- def transform
20
+ def run
21
21
  convert_sql
22
22
  validate_bind_hash
23
23
  converted_sql
24
24
  end
25
25
 
26
+ private
27
+
26
28
  def convert_sql
27
- @converted_sql ||= sql.gsub(/(:?):([a-zA-Z]\w*)/) do |_|
28
- replace = $2.to_sym
29
+ @converted_sql = sql.gsub(/(:?):([a-zA-Z]\w*)/) do |_|
30
+ replace = ::Regexp.last_match(2).to_sym
29
31
  validate_sql(replace)
30
32
  bind_hash[replace].quote
31
33
  end
32
34
  end
33
35
 
34
- private
35
-
36
- def validate_sql(attr)
37
- raise SqlBindMismatch, ":#{attr} in your query is missing from your args" unless bind_hash[attr]
36
+ def validate_sql(attr)
37
+ raise SqlBindMismatch, ":#{attr} in your query is missing from your args" unless bind_hash[attr]
38
38
 
39
- depleting_bind_hash.delete(attr)
40
- end
39
+ depleting_bind_hash.delete(attr)
40
+ end
41
41
 
42
- def validate_bind_hash
43
- raise SqlBindMismatch, ":#{depleting_bind_hash.keys.join(', ')} in your bind hash is missing from your query: #{sql}" unless depleting_bind_hash.empty?
44
- end
42
+ def validate_bind_hash
43
+ return if depleting_bind_hash.empty?
45
44
 
45
+ raise SqlBindMismatch,
46
+ ":#{depleting_bind_hash.keys.join(', ')} in your bind hash is missing from your query: #{sql}"
47
+ end
46
48
  end
47
49
  end
@@ -1,62 +1,53 @@
1
- require "stairwell/bind_transformer"
2
- require "stairwell/types/boolean_type"
3
- require "stairwell/types/column_name_type"
4
- require "stairwell/types/date_time_type"
5
- require "stairwell/types/date_type"
6
- require "stairwell/types/float_type"
7
- require "stairwell/types/integer_type"
8
- require "stairwell/types/in_type"
9
- require "stairwell/types/string_type"
10
- require "stairwell/types/null_type"
11
- require "stairwell/types/table_name_type"
1
+ # frozen_string_literal: true
12
2
 
13
3
  module Stairwell
14
4
  class Query
15
-
16
5
  class << self
17
- attr_accessor :bind_hash, :all_validations, :sql_string
18
-
19
6
  def validate_type(*args)
20
7
  @all_validations ||= {}
21
8
  @all_validations.merge!(Hash[*args])
22
9
  end
23
10
 
24
11
  def sql(**args)
25
- @bind_hash = args
26
- validate!
27
- transformed_sql_string
12
+ set_sql_string_from_file
13
+ raise InvalidBindCount, 'Incorrect amount of args passed' if args.keys.sort != all_validations.keys.sort
14
+
15
+ @type_hash = args.each_with_object({}) do |(name, value), hash|
16
+ hash[name] = TypeObjectAssigner.run(name:, value:, all_validations:)
17
+ end
18
+ transformer.run
28
19
  end
29
20
 
30
21
  def query(string)
31
- @sql_string = string
22
+ @sql_string ||= string.squish
32
23
  end
33
24
 
34
25
  private
35
26
 
36
- def validate!
37
- raise InvalidBindCount.new("Incorrect amount of args passed") unless correct_args?
27
+ attr_reader :type_hash, :all_validations, :sql_string
38
28
 
39
- bind_hash.each do |bind_name, bind_value|
40
- type = all_validations[bind_name]
41
- if type.is_a?(Array)
42
- type = type.first
43
- type_object = Types::InType.new(bind_value, type)
44
- end
45
- type_object ||= Object.const_get(TYPE_CLASSES[type]).new(bind_value)
29
+ def transformer
30
+ BindTransformer.new(sql_string, type_hash)
31
+ end
46
32
 
47
- raise InvalidBindType.new("#{bind_name} is not #{all_validations[bind_name]}") unless type_object.valid?
33
+ def set_sql_string_from_file
34
+ return unless Stairwell.configuration.path && File.exist?(associated_sql_file)
48
35
 
49
- bind_hash[bind_name] = type_object
50
- end
51
- end
36
+ file = File.read(associated_sql_file)
37
+ @sql_string = file&.squish
38
+ end
52
39
 
53
- def transformed_sql_string
54
- BindTransformer.new(sql_string.squish!, bind_hash).transform
55
- end
40
+ def associated_sql_file
41
+ "#{Stairwell.configuration.path}#{camelized_class}.sql"
42
+ end
56
43
 
57
- def correct_args?
58
- bind_hash.keys.sort == all_validations.keys.sort
59
- end
44
+ def camelized_class
45
+ self.to_s.gsub(/::/, '/')
46
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
47
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
48
+ .tr("-", "_")
49
+ .downcase
50
+ end
60
51
  end
61
52
  end
62
53
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stairwell
4
+ class TypeObjectAssigner
5
+ attr_reader :name, :value, :all_validations
6
+
7
+ def self.run(...)
8
+ new(...).run
9
+ end
10
+
11
+ def initialize(name:, value:, all_validations:)
12
+ @name = name
13
+ @value = value
14
+ @all_validations = all_validations
15
+ end
16
+
17
+ def run
18
+ type_object
19
+ end
20
+
21
+ private
22
+
23
+ def proposed_type
24
+ all_validations[name]
25
+ end
26
+
27
+ def type_object
28
+ if proposed_type.is_a?(Array)
29
+ Types::InType.new(value, proposed_type.first)
30
+ else
31
+ Object.const_get(TYPE_CLASSES[proposed_type]).new(value)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,17 +1,32 @@
1
- module Stairwell::Types
2
- class BaseType
3
- attr_reader :value
1
+ # frozen_string_literal: true
4
2
 
5
- def initialize(value)
6
- @value = value
7
- end
3
+ module Stairwell
4
+ module Types
5
+ class BaseType
6
+ attr_reader :value
8
7
 
9
- def quote
10
- connection.quote(value)
11
- end
8
+ def initialize(value)
9
+ @value = value
10
+ validate!
11
+ end
12
+
13
+ def quote
14
+ connection.quote(value)
15
+ end
16
+
17
+ def connection
18
+ @connection ||= ActiveRecord::Base.connection
19
+ end
20
+
21
+ def validate!
22
+ return if valid?
23
+
24
+ raise InvalidBindType, "#{value} is not #{type_name}"
25
+ end
12
26
 
13
- def connection
14
- @connection ||= ActiveRecord::Base.connection
27
+ def type_name
28
+ self.class.name.split('::').last.gsub('Type', '').downcase
29
+ end
15
30
  end
16
31
  end
17
32
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class BooleanType < BaseType
5
- def valid?
6
- value.is_a?(TrueClass) || value.is_a?(FalseClass)
3
+ module Stairwell
4
+ module Types
5
+ class BooleanType < BaseType
6
+ def valid?
7
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,13 +1,15 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class ColumnNameType < BaseType
5
- def valid?
6
- value.is_a?(String)
7
- end
3
+ module Stairwell
4
+ module Types
5
+ class ColumnNameType < BaseType
6
+ def valid?
7
+ value.is_a?(String)
8
+ end
8
9
 
9
- def quote
10
- connection.quote_column_name(value)
10
+ def quote
11
+ connection.quote_column_name(value)
12
+ end
11
13
  end
12
14
  end
13
15
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class DateTimeType < BaseType
5
- def valid?
6
- value.is_a?(String)
3
+ module Stairwell
4
+ module Types
5
+ class DateTimeType < BaseType
6
+ def valid?
7
+ value.is_a?(String)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class DateType < BaseType
5
- def valid?
6
- value.is_a?(String)
3
+ module Stairwell
4
+ module Types
5
+ class DateType < BaseType
6
+ def valid?
7
+ value.is_a?(String)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class FloatType < BaseType
5
- def valid?
6
- value.is_a?(Float)
3
+ module Stairwell
4
+ module Types
5
+ class FloatType < BaseType
6
+ def valid?
7
+ value.is_a?(Float)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,28 +1,30 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class InType
5
- attr_reader :value, :type
3
+ module Stairwell
4
+ module Types
5
+ class InType
6
+ attr_reader :value, :type
6
7
 
7
- def initialize(value, type)
8
- @value = value
9
- @type = type
10
- end
8
+ def initialize(value, type)
9
+ @value = value
10
+ @type = type
11
+ end
11
12
 
12
- def quote
13
- contained_values.map(&:quote).join(", ")
14
- end
13
+ def quote
14
+ contained_values.map(&:quote).join(', ')
15
+ end
15
16
 
16
- def valid?
17
- value.is_a?(Array) && contained_values.all?(&:valid?)
18
- end
17
+ def valid?
18
+ value.is_a?(Array) && contained_values.all?(&:valid?)
19
+ end
19
20
 
20
- private
21
+ private
21
22
 
22
23
  def contained_values
23
24
  value.map do |contained|
24
25
  Object.const_get(Stairwell::TYPE_CLASSES[type]).new(contained)
25
26
  end
26
27
  end
28
+ end
27
29
  end
28
30
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class IntegerType < BaseType
5
- def valid?
6
- value.is_a?(Integer)
3
+ module Stairwell
4
+ module Types
5
+ class IntegerType < BaseType
6
+ def valid?
7
+ value.is_a?(Integer)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class NullType < BaseType
5
- def valid?
6
- value.is_a?(NilClass)
3
+ module Stairwell
4
+ module Types
5
+ class NullType < BaseType
6
+ def valid?
7
+ value.is_a?(NilClass)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,9 +1,11 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class StringType < BaseType
5
- def valid?
6
- value.is_a?(String)
3
+ module Stairwell
4
+ module Types
5
+ class StringType < BaseType
6
+ def valid?
7
+ value.is_a?(String)
8
+ end
7
9
  end
8
10
  end
9
11
  end
@@ -1,13 +1,15 @@
1
- require "stairwell/types/base_type"
1
+ # frozen_string_literal: true
2
2
 
3
- module Stairwell::Types
4
- class TableNameType < BaseType
5
- def valid?
6
- value.is_a?(String)
7
- end
3
+ module Stairwell
4
+ module Types
5
+ class TableNameType < BaseType
6
+ def valid?
7
+ value.is_a?(String)
8
+ end
8
9
 
9
- def quote
10
- connection.quote_table_name(value)
10
+ def quote
11
+ connection.quote_table_name(value)
12
+ end
11
13
  end
12
14
  end
13
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Stairwell
2
- VERSION = "0.3.0"
4
+ VERSION = '0.6.0'
3
5
  end
data/lib/stairwell.rb CHANGED
@@ -1,7 +1,6 @@
1
- require "active_record"
2
- require "date"
3
- require "stairwell/query"
4
- require "stairwell/version"
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record'
5
4
 
6
5
  module Stairwell
7
6
  class Error < StandardError; end
@@ -10,22 +9,40 @@ module Stairwell
10
9
  class SqlBindMismatch < StandardError; end
11
10
 
12
11
  TYPE_CLASSES = {
13
- string: "Stairwell::Types::StringType",
14
- integer: "Stairwell::Types::IntegerType",
15
- boolean: "Stairwell::Types::BooleanType",
16
- float: "Stairwell::Types::FloatType",
17
- date: "Stairwell::Types::DateType",
18
- date_time: "Stairwell::Types::DateTimeType",
19
- null: "Stairwell::Types::NullType",
20
- column_name: "Stairwell::Types::ColumnNameType",
21
- table_name: "Stairwell::Types::TableNameType"
12
+ string: 'Stairwell::Types::StringType',
13
+ integer: 'Stairwell::Types::IntegerType',
14
+ boolean: 'Stairwell::Types::BooleanType',
15
+ float: 'Stairwell::Types::FloatType',
16
+ date: 'Stairwell::Types::DateType',
17
+ date_time: 'Stairwell::Types::DateTimeType',
18
+ null: 'Stairwell::Types::NullType',
19
+ column_name: 'Stairwell::Types::ColumnNameType',
20
+ table_name: 'Stairwell::Types::TableNameType'
22
21
  }.freeze
23
22
 
23
+ class << self
24
+ def configuration
25
+ @configuration ||= Configuration.new
26
+ end
27
+
28
+ def configure
29
+ yield configuration
30
+ end
31
+ end
32
+
24
33
  # for development and testing
25
34
  unless defined?(Rails)
26
- ActiveRecord::Base.establish_connection(
35
+ ::ActiveRecord::Base.establish_connection(
27
36
  adapter: 'sqlite3',
28
37
  database: 'test.db'
29
38
  )
30
39
  end
31
40
  end
41
+
42
+ require 'date'
43
+ require 'zeitwerk'
44
+
45
+ loader = Zeitwerk::Loader.for_gem
46
+ loader.ignore("#{__dir__}/kamal/sshkit_with_ext.rb")
47
+ loader.setup
48
+ loader.eager_load # We need all commands loaded.
data/stairwell.gemspec CHANGED
@@ -1,35 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/stairwell/version'
2
4
 
3
5
  Gem::Specification.new do |spec|
4
- spec.name = "stairwell"
6
+ spec.name = 'stairwell'
5
7
  spec.version = Stairwell::VERSION
6
- spec.authors = ["tobyond"]
8
+ spec.authors = ['tobyond']
7
9
 
8
- spec.summary = %q{stairwell for sql}
9
- spec.description = %q{Sanitize and quote raw SQL for rails and any project in ruby}
10
- spec.homepage = "https://github.com/tobyond/stairwell"
11
- spec.license = "MIT"
12
- spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
10
+ spec.summary = 'stairwell for sql'
11
+ spec.description = 'I actually like SQL, and want to use it in my Ruby projects.'
12
+ spec.homepage = 'https://github.com/tobyond/stairwell'
13
+ spec.license = 'MIT'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.2.0')
13
15
 
14
16
  # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
15
17
 
16
- spec.metadata["homepage_uri"] = spec.homepage
17
- spec.metadata["source_code_uri"] = "https://github.com/tobyond/stairwell"
18
+ spec.metadata['homepage_uri'] = spec.homepage
19
+ spec.metadata['source_code_uri'] = 'https://github.com/tobyond/stairwell'
18
20
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
19
21
 
20
22
  # Specify which files should be added to the gem when it is released.
21
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
24
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
23
25
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
26
  end
25
- spec.bindir = "exe"
27
+ spec.bindir = 'exe'
26
28
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
- spec.require_paths = ["lib"]
29
+ spec.require_paths = ['lib']
28
30
 
29
31
  spec.add_dependency 'activerecord', '>= 4.2.11'
32
+ spec.add_dependency 'rake'
33
+ spec.add_dependency 'zeitwerk', '~> 2.5'
30
34
 
31
35
  # for development and testing
32
- unless defined?(Rails)
33
- spec.add_dependency 'sqlite3'
34
- end
36
+ spec.add_dependency 'sqlite3' unless defined?(Rails)
35
37
  end
data/test.db CHANGED
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stairwell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tobyond
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-10-25 00:00:00.000000000 Z
11
+ date: 2023-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 4.2.11
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: zeitwerk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '2.5'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '2.5'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: sqlite3
29
57
  requirement: !ruby/object:Gem::Requirement
@@ -38,12 +66,16 @@ dependencies:
38
66
  - - ">="
39
67
  - !ruby/object:Gem::Version
40
68
  version: '0'
41
- description: Sanitize and quote raw SQL for rails and any project in ruby
69
+ description: I actually like SQL, and want to use it in my Ruby projects.
42
70
  email:
43
71
  executables: []
44
72
  extensions: []
45
73
  extra_rdoc_files: []
46
74
  files:
75
+ - ".bin/bundle"
76
+ - ".bin/coderay"
77
+ - ".bin/pry"
78
+ - ".bin/rake"
47
79
  - ".gitignore"
48
80
  - ".travis.yml"
49
81
  - Gemfile
@@ -56,6 +88,7 @@ files:
56
88
  - lib/stairwell.rb
57
89
  - lib/stairwell/bind_transformer.rb
58
90
  - lib/stairwell/query.rb
91
+ - lib/stairwell/type_object_assigner.rb
59
92
  - lib/stairwell/types/base_type.rb
60
93
  - lib/stairwell/types/boolean_type.rb
61
94
  - lib/stairwell/types/column_name_type.rb
@@ -84,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
117
  requirements:
85
118
  - - ">="
86
119
  - !ruby/object:Gem::Version
87
- version: 2.3.0
120
+ version: 3.2.0
88
121
  required_rubygems_version: !ruby/object:Gem::Requirement
89
122
  requirements:
90
123
  - - ">="