sqb 1.0.6 → 1.0.7

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
- SHA256:
3
- metadata.gz: 3cf773939419d3f07b0b56d017ba8d044bd366922cecf7ef3aaa3f0dfe2fa852
4
- data.tar.gz: 3ee2271dadb659cf8b6fedf8e223da6e888284c431d99a8ee4d8f44f2a9cf4b0
2
+ SHA1:
3
+ metadata.gz: c682c36dc27d41519663b1caf06a97edd9cfdb6c
4
+ data.tar.gz: 92637092f8f29020c72d40b466b4acfbd43e9060
5
5
  SHA512:
6
- metadata.gz: 9149a4d5724ad99d3b892e21044b21629a55e05f1e6c6b1fef477bb4524ae5afe2244663cfe192c8f514dc3453449b1a898dddc37d1bc19dd63fa95a626b9866
7
- data.tar.gz: 4e3b753a1209acaf5101da975d3f8a969b7a1621524f8b561d5308be7d528dd409b2459978e63af0c728f4bc5b9a0b11be722447d48573fb2ff6183d95f5abe7
6
+ metadata.gz: cd376b13686ee0f7f27621c275cb52100bf9872de3df5cc9805e936f0c591f4ffea321e1076eb4a00b1fdb4a50949cb1c56fa1baa6e2db691f4716606c91f58e
7
+ data.tar.gz: f1e60e3a689895eb05c5305dc9fb803bb7d088281ce07ceef062222515e6e82151c04e19be92b6bb19ff269f4eff41484622214e1cad2f28d826406387832a8a
@@ -13,4 +13,7 @@ module SQB
13
13
 
14
14
  class NoValuesError < Error
15
15
  end
16
+
17
+ class QueryError < Error
18
+ end
16
19
  end
@@ -30,6 +30,8 @@ module SQB
30
30
  'NULL'
31
31
  elsif value.is_a?(Integer)
32
32
  value.to_i
33
+ elsif value.is_a?(SQB::SafeString)
34
+ value.to_s
33
35
  else
34
36
  @prepared_arguments << value.to_s
35
37
  '?'
@@ -38,7 +40,11 @@ module SQB
38
40
 
39
41
  def with_table_and_column(input, &block)
40
42
  if input.is_a?(Hash)
41
- input.each { |table, column| block.call(table, column) }
43
+ if input.size == 1
44
+ block.call(input.first[0], input.first[1])
45
+ else
46
+ raise QueryError, "Column names provided as a hash must only contain a single item"
47
+ end
42
48
  else
43
49
  block.call(@table_name, input)
44
50
  end
@@ -1,3 +1,5 @@
1
+ require 'sqb/where_dsl'
2
+
1
3
  module SQB
2
4
  module Filtering
3
5
 
@@ -5,12 +7,20 @@ module SQB
5
7
  #
6
8
  # @param hash [Hash]
7
9
  # @return [Query]
8
- def where(hash)
9
- if @where_within_or && @where_within_or.last
10
- @where_within_or.last << hash
10
+ def where(hash = nil, &block)
11
+ if hash
12
+ if @where_within_or && @where_within_or.last
13
+ @where_within_or.last << hash
14
+ else
15
+ @where ||= []
16
+ @where << hash_to_sql(hash)
17
+ end
18
+ elsif block_given?
19
+ dsl = WhereDSL.new
20
+ block.call(dsl)
21
+ where(dsl.hash)
11
22
  else
12
- @where ||= []
13
- @where << hash_to_sql(hash, @table_name)
23
+ raise QueryError, "Must provide a hash or a block to `where`"
14
24
  end
15
25
  self
16
26
  end
@@ -31,7 +41,7 @@ module SQB
31
41
  # executed within the block.
32
42
  if w = @where_within_or.pop
33
43
  @where_within_or_sql << w.map do |w|
34
- hash_to_sql(w, @table_name)
44
+ hash_to_sql(w)
35
45
  end.join(' OR ')
36
46
  end
37
47
 
@@ -47,71 +57,63 @@ module SQB
47
57
 
48
58
  private
49
59
 
50
- def hash_to_sql(hash, table, joiner = ' AND ')
60
+ def hash_to_sql(hash, joiner = ' AND ')
51
61
  sql = hash.map do |key, value|
52
- if key.is_a?(Hash)
53
- table = key.first[0]
54
- key = key.first[1]
55
- end
56
-
57
- key = escape_and_join(table, key)
58
-
59
- if value.is_a?(Array)
60
- escaped_values = value.map { |v| value_escape(v) }.join(', ')
61
- if escaped_values.empty?
62
- "1=0"
63
- else
64
- "#{key} IN (#{escaped_values})"
65
- end
66
- elsif value.is_a?(Hash)
67
- sql = []
68
- value.each do |operator, value|
69
- case operator
70
- when :not_equal
71
- if value.nil?
72
- sql << "#{key} IS NOT NULL"
73
- else
74
- sql << "#{key} != #{value_escape(value)}"
75
- end
76
- when :equal
77
- if value.nil?
78
- sql << "#{key} IS NULL"
79
- else
80
- sql << "#{key} = #{value_escape(value)}"
81
- end
82
- when :less_than
83
- sql << "#{key} < #{value_escape(value)}"
84
- when :greater_than
85
- sql << "#{key} > #{value_escape(value)}"
86
- when :less_than_or_equal_to
87
- sql << "#{key} <= #{value_escape(value)}"
88
- when :greater_than_or_equal_to
89
- sql << "#{key} >= #{value_escape(value)}"
90
- when :in, :not_in
91
- escaped_values = value.map { |v| value_escape(v) }.join(', ')
92
- if escaped_values.empty?
93
- # If there are no values to search from, don't find anything
94
- "1=0"
95
- else
96
- op = operator == :in ? "IN" : "NOT IN"
97
- sql << "#{key} #{op} (#{escaped_values})"
98
- end
99
- when :like
100
- sql << "#{key} LIKE #{value_escape(value)}"
101
- when :not_like
102
- sql << "#{key} NOT LIKE #{value_escape(value)}"
103
- else
104
- raise InvalidOperatorError, "Invalid operator '#{operator}'"
62
+ with_table_and_column(key) do |table, column|
63
+ key = escape_and_join(table, column)
64
+ if value.is_a?(Array)
65
+ condition(key, :in, value)
66
+ elsif value.is_a?(Hash)
67
+ sql = value.map do |operator, value|
68
+ condition(key, operator, value)
105
69
  end
70
+ sql.empty? ? "1=0" : sql.join(joiner)
71
+ else
72
+ condition(key, :equal, value)
106
73
  end
107
- sql.empty? ? "1=0" : sql.join(joiner)
108
- elsif value == nil
74
+ end
75
+ end.join(joiner)
76
+ "(#{sql})"
77
+ end
78
+
79
+ def condition(key, operator, value)
80
+ case operator
81
+ when :equal
82
+ if value.nil?
109
83
  "#{key} IS NULL"
110
84
  else
111
85
  "#{key} = #{value_escape(value)}"
112
86
  end
113
- end.join(joiner)
114
- "(#{sql})"
87
+ when :not_equal
88
+ if value.nil?
89
+ "#{key} IS NOT NULL"
90
+ else
91
+ "#{key} != #{value_escape(value)}"
92
+ end
93
+ when :less_than, :lt
94
+ "#{key} < #{value_escape(value)}"
95
+ when :greater_than, :gt
96
+ "#{key} > #{value_escape(value)}"
97
+ when :less_than_or_equal_to, :lte
98
+ "#{key} <= #{value_escape(value)}"
99
+ when :greater_than_or_equal_to, :gte
100
+ "#{key} >= #{value_escape(value)}"
101
+ when :in, :not_in
102
+ escaped_values = value.map { |v| value_escape(v) }.join(', ')
103
+ if escaped_values.empty?
104
+ # If there are no values to search from, don't find anything
105
+ "1=0"
106
+ else
107
+ op = operator == :in ? "IN" : "NOT IN"
108
+ "#{key} #{op} (#{escaped_values})"
109
+ end
110
+ when :like
111
+ "#{key} LIKE #{value_escape(value)}"
112
+ when :not_like
113
+ "#{key} NOT LIKE #{value_escape(value)}"
114
+ else
115
+ raise InvalidOperatorError, "Invalid operator '#{operator}'"
116
+ end
115
117
  end
116
118
 
117
119
  end
@@ -15,7 +15,7 @@ module SQB
15
15
  query << "SET"
16
16
  if @sets && !@sets.empty?
17
17
  query << @sets.map do |key, value|
18
- "#{escape_and_join(@table_name, key)} = #{value_escape(value)}"
18
+ "#{escape_and_join(@table_name, key)} = #{value}"
19
19
  end.join(', ')
20
20
  else
21
21
  raise NoValuesError, "No values have been updated. Use `set` to set the values to update."
@@ -41,9 +41,13 @@ module SQB
41
41
  # @param key [String]
42
42
  # @param value [String, nil]
43
43
  def set(hash)
44
+ if @where
45
+ raise QueryError, "Filtering has already been provided. Must filter after setting values."
46
+ end
47
+
44
48
  @sets ||= {}
45
49
  hash.each do |key, value|
46
- @sets[key] = value
50
+ @sets[key] = value_escape(value)
47
51
  end
48
52
  self
49
53
  end
@@ -1,3 +1,3 @@
1
1
  module SQB
2
- VERSION = '1.0.6'
2
+ VERSION = '1.0.7'
3
3
  end
@@ -0,0 +1,85 @@
1
+ module SQB
2
+ class WhereDSL
3
+
4
+ attr_reader :hash
5
+
6
+ def initialize
7
+ @hash = {}
8
+ end
9
+
10
+ def method_missing(name, value = nil)
11
+ if name =~ /(.*)\=\z/
12
+ attribute_name = $1
13
+ @hash[attribute_name.to_sym] ||= {}
14
+ @hash[attribute_name.to_sym][:equal] = value
15
+ else
16
+ @hash[name.to_sym] ||= {}
17
+ attribute = PositiveAttribute.new(name.to_sym, @hash)
18
+ end
19
+ end
20
+
21
+ class Attribute
22
+
23
+ def initialize(attribute_name, hash)
24
+ @attribute_name = attribute_name
25
+ @hash = hash
26
+ end
27
+
28
+ end
29
+
30
+ class PositiveAttribute < Attribute
31
+ def =~(value)
32
+ @hash[@attribute_name][:like] = value
33
+ end
34
+ alias_method :like, :=~
35
+
36
+ def <(value)
37
+ @hash[@attribute_name][:less_than] = value
38
+ end
39
+ alias_method :less_than, :<
40
+
41
+ def <=(value)
42
+ @hash[@attribute_name][:less_than_or_equal_to] = value
43
+ end
44
+ alias_method :less_than_or_equal_to, :<=
45
+
46
+ def >(value)
47
+ @hash[@attribute_name][:greater_than] = value
48
+ end
49
+ alias_method :greater_than, :>
50
+
51
+ def >=(value)
52
+ @hash[@attribute_name][:greater_than_or_equal_to] = value
53
+ end
54
+ alias_method :greater_than_or_equal_to, :>=
55
+
56
+ def includes(*values)
57
+ @hash[@attribute_name][:in] = values
58
+ end
59
+ alias_method :in, :includes
60
+
61
+ def not
62
+ NegativeAttribute.new(@attribute_name, @hash)
63
+ end
64
+ alias_method :does_not, :not
65
+
66
+ def not=(value)
67
+ @hash[@attribute_name][:not_equal] = value
68
+ end
69
+
70
+ end
71
+
72
+ class NegativeAttribute < Attribute
73
+ def =~(value)
74
+ @hash[@attribute_name][:not_like] = value
75
+ end
76
+ alias_method :like, :=~
77
+
78
+ def includes(*values)
79
+ @hash[@attribute_name][:not_in] = values
80
+ end
81
+ alias_method :in, :includes
82
+ end
83
+
84
+ end
85
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sqb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Cooke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-01 00:00:00.000000000 Z
11
+ date: 2018-04-03 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A friendly SQL builder for MySQL.
14
14
  email:
@@ -36,6 +36,7 @@ files:
36
36
  - lib/sqb/select.rb
37
37
  - lib/sqb/update.rb
38
38
  - lib/sqb/version.rb
39
+ - lib/sqb/where_dsl.rb
39
40
  homepage: https://github.com/adamcooke/sqb
40
41
  licenses:
41
42
  - MIT
@@ -56,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
57
  version: '0'
57
58
  requirements: []
58
59
  rubyforge_project:
59
- rubygems_version: 2.7.4
60
+ rubygems_version: 2.5.2.3
60
61
  signing_key:
61
62
  specification_version: 4
62
63
  summary: This gem provides a friendly DSL for constructing MySQL queries.