~ubuntu-branches/ubuntu/vivid/ruby-sequel/vivid

« back to all changes in this revision

Viewing changes to lib/sequel/extensions/core_refinements.rb

  • Committer: Package Import Robot
  • Author(s): Dmitry Borodaenko, Dmitry Borodaenko, Cédric Boutillier
  • Date: 2013-08-10 18:38:17 UTC
  • mfrom: (1.1.8)
  • Revision ID: package-import@ubuntu.com-20130810183817-iqanz804j32i5myi
Tags: 4.1.1-1
[ Dmitry Borodaenko ]
* New upstream release.
* Standards-Version upgraded to 3.9.4 (no changes).
* Added Build-Depend on ruby-sqlite3.

[ Cédric Boutillier ]
* debian/control: remove obsolete DM-Upload-Allowed flag.
* use canonical URI in Vcs-* fields.
* debian/copyright: use DEP5 copyright-format/1.0 official URL for Format
  field.
* Update debian/watch. Thanks Bart Martens.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# These are refinements to core classes that allow the Sequel
 
2
# DSL to be used without modifying the core classes directly.
 
3
# After loading the extension via:
 
4
#
 
5
#   Sequel.extension :core_refinements
 
6
#
 
7
# you can enable the refinements for particular files:
 
8
#
 
9
#   using Sequel::CoreRefinements
 
10
 
 
11
raise(Sequel::Error, "Refinements require ruby 2.0.0 or greater") unless RUBY_VERSION >= '2.0.0'
 
12
 
 
13
module Sequel::CoreRefinements
 
14
  refine Array do
 
15
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, not matching all of the
 
16
    # conditions.
 
17
    #
 
18
    #   ~[[:a, true]] # SQL: a IS NOT TRUE
 
19
    #   ~[[:a, 1], [:b, [2, 3]]] # SQL: a != 1 OR b NOT IN (2, 3)
 
20
    def ~
 
21
      Sequel.~(self)
 
22
    end
 
23
 
 
24
    # Return a <tt>Sequel::SQL::CaseExpression</tt> with this array as the conditions and the given
 
25
    # default value and expression.
 
26
    #
 
27
    #   [[{:a=>[2,3]}, 1]].case(0) # SQL: CASE WHEN a IN (2, 3) THEN 1 ELSE 0 END
 
28
    #   [[:a, 1], [:b, 2]].case(:d, :c) # SQL: CASE c WHEN a THEN 1 WHEN b THEN 2 ELSE d END
 
29
    def case(*args)
 
30
      ::Sequel::SQL::CaseExpression.new(self, *args)
 
31
    end
 
32
 
 
33
    # Return a <tt>Sequel::SQL::ValueList</tt> created from this array.  Used if this array contains
 
34
    # all two element arrays and you want it treated as an SQL value list (IN predicate) 
 
35
    # instead of as a conditions specifier (similar to a hash).  This is not necessary if you are using
 
36
    # this array as a value in a filter, but may be necessary if you are using it as a
 
37
    # value with placeholder SQL:
 
38
    #
 
39
    #   DB[:a].filter([:a, :b]=>[[1, 2], [3, 4]]) # SQL: (a, b) IN ((1, 2), (3, 4))
 
40
    #   DB[:a].filter('(a, b) IN ?', [[1, 2], [3, 4]]) # SQL: (a, b) IN ((1 = 2) AND (3 = 4))
 
41
    #   DB[:a].filter('(a, b) IN ?', [[1, 2], [3, 4]].sql_value_list) # SQL: (a, b) IN ((1, 2), (3, 4))
 
42
    def sql_value_list
 
43
      ::Sequel::SQL::ValueList.new(self)
 
44
    end
 
45
    
 
46
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, matching all of the
 
47
    # conditions.  Rarely do you need to call this explicitly, as Sequel generally
 
48
    # assumes that arrays of two element arrays specify this type of condition.  One case where
 
49
    # it can be necessary to use this is if you are using the object as a value in a filter hash
 
50
    # and want to use the = operator instead of the IN operator (which is used by default for
 
51
    # arrays of two element arrays).
 
52
    #
 
53
    #   [[:a, true]].sql_expr # SQL: a IS TRUE
 
54
    #   [[:a, 1], [:b, [2, 3]]].sql_expr # SQL: a = 1 AND b IN (2, 3)
 
55
    def sql_expr
 
56
      Sequel.expr(self)
 
57
    end
 
58
 
 
59
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, matching none
 
60
    # of the conditions.
 
61
    #
 
62
    #   [[:a, true]].sql_negate # SQL: a IS NOT TRUE
 
63
    #   [[:a, 1], [:b, [2, 3]]].sql_negate # SQL: a != 1 AND b NOT IN (2, 3)
 
64
    def sql_negate
 
65
      Sequel.negate(self)
 
66
    end
 
67
 
 
68
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this array, matching any of the
 
69
    # conditions.
 
70
    #
 
71
    #   [[:a, true]].sql_or # SQL: a IS TRUE
 
72
    #   [[:a, 1], [:b, [2, 3]]].sql_or # SQL: a = 1 OR b IN (2, 3)
 
73
    def sql_or
 
74
      Sequel.or(self)
 
75
    end
 
76
 
 
77
    # Return a <tt>Sequel::SQL::StringExpression</tt> representing an SQL string made up of the
 
78
    # concatenation of this array's elements.  If an argument is passed
 
79
    # it is used in between each element of the array in the SQL
 
80
    # concatenation.
 
81
    #
 
82
    #   [:a].sql_string_join # SQL: a
 
83
    #   [:a, :b].sql_string_join # SQL: a || b
 
84
    #   [:a, 'b'].sql_string_join # SQL: a || 'b'
 
85
    #   ['a', :b].sql_string_join(' ') # SQL: 'a' || ' ' || b
 
86
    def sql_string_join(joiner=nil)
 
87
      Sequel.join(self, joiner)
 
88
    end
 
89
  end
 
90
 
 
91
  refine Hash do
 
92
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this hash, matching
 
93
    # all of the conditions in this hash and the condition specified by
 
94
    # the given argument.
 
95
    #
 
96
    #   {:a=>1} & :b # SQL: a = 1 AND b
 
97
    #   {:a=>true} & ~:b # SQL: a IS TRUE AND NOT b
 
98
    def &(ce)
 
99
      ::Sequel::SQL::BooleanExpression.new(:AND, self, ce)
 
100
    end
 
101
 
 
102
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this hash, matching
 
103
    # all of the conditions in this hash or the condition specified by
 
104
    # the given argument.
 
105
    #
 
106
    #   {:a=>1} | :b # SQL: a = 1 OR b
 
107
    #   {:a=>true} | ~:b # SQL: a IS TRUE OR NOT b
 
108
    def |(ce)
 
109
      ::Sequel::SQL::BooleanExpression.new(:OR, self, ce)
 
110
    end
 
111
 
 
112
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this hash, not matching all of the
 
113
    # conditions.
 
114
    #
 
115
    #   ~{:a=>true} # SQL: a IS NOT TRUE
 
116
    #   ~{:a=>1, :b=>[2, 3]} # SQL: a != 1 OR b NOT IN (2, 3)
 
117
    def ~
 
118
      ::Sequel::SQL::BooleanExpression.from_value_pairs(self, :OR, true)
 
119
    end
 
120
 
 
121
    # Return a <tt>Sequel::SQL::CaseExpression</tt> with this hash as the conditions and the given
 
122
    # default value.  Note that the order of the conditions will be arbitrary on ruby 1.8, so all
 
123
    # conditions should be orthogonal.
 
124
    #
 
125
    #   {{:a=>[2,3]}=>1}.case(0) # SQL: CASE WHEN a IN (2, 3) THEN 1 ELSE 0 END
 
126
    #   {:a=>1, :b=>2}.case(:d, :c) # SQL: CASE c WHEN a THEN 1 WHEN b THEN 2 ELSE d END
 
127
    #                                 #  or: CASE c WHEN b THEN 2 WHEN a THEN 1 ELSE d END
 
128
    def case(*args)
 
129
      ::Sequel::SQL::CaseExpression.new(to_a, *args)
 
130
    end
 
131
 
 
132
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this hash, matching all of the
 
133
    # conditions.  Rarely do you need to call this explicitly, as Sequel generally
 
134
    # assumes that hashes specify this type of condition.
 
135
    #
 
136
    #   {:a=>true}.sql_expr # SQL: a IS TRUE
 
137
    #   {:a=>1, :b=>[2, 3]}.sql_expr # SQL: a = 1 AND b IN (2, 3)
 
138
    def sql_expr
 
139
      ::Sequel::SQL::BooleanExpression.from_value_pairs(self)
 
140
    end
 
141
 
 
142
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this hash, matching none
 
143
    # of the conditions.
 
144
    #
 
145
    #   {:a=>true}.sql_negate # SQL: a IS NOT TRUE
 
146
    #   {:a=>1, :b=>[2, 3]}.sql_negate # SQL: a != 1 AND b NOT IN (2, 3)
 
147
    def sql_negate
 
148
      ::Sequel::SQL::BooleanExpression.from_value_pairs(self, :AND, true)
 
149
    end
 
150
 
 
151
    # Return a <tt>Sequel::SQL::BooleanExpression</tt> created from this hash, matching any of the
 
152
    # conditions.
 
153
    #
 
154
    #   {:a=>true}.sql_or # SQL: a IS TRUE
 
155
    #   {:a=>1, :b=>[2, 3]}.sql_or # SQL: a = 1 OR b IN (2, 3)
 
156
    def sql_or
 
157
      ::Sequel::SQL::BooleanExpression.from_value_pairs(self, :OR)
 
158
    end
 
159
  end
 
160
 
 
161
  refine String do
 
162
    include Sequel::SQL::AliasMethods
 
163
    include Sequel::SQL::CastMethods
 
164
 
 
165
    # Converts a string into a <tt>Sequel::LiteralString</tt>, in order to override string
 
166
    # literalization, e.g.:
 
167
    #
 
168
    #   DB[:items].filter(:abc => 'def').sql #=>
 
169
    #     "SELECT * FROM items WHERE (abc = 'def')"
 
170
    #
 
171
    #   DB[:items].filter(:abc => 'def'.lit).sql #=>
 
172
    #     "SELECT * FROM items WHERE (abc = def)"
 
173
    #
 
174
    # You can also provide arguments, to create a <tt>Sequel::SQL::PlaceholderLiteralString</tt>:
 
175
    #
 
176
    #    DB[:items].select{|o| o.count('DISTINCT ?'.lit(:a))}.sql #=>
 
177
    #      "SELECT count(DISTINCT a) FROM items"
 
178
    def lit(*args)
 
179
      args.empty? ? Sequel::LiteralString.new(self) : Sequel::SQL::PlaceholderLiteralString.new(self, args)
 
180
    end
 
181
    
 
182
    # Returns a <tt>Sequel::SQL::Blob</tt> that holds the same data as this string. Blobs provide proper
 
183
    # escaping of binary data.
 
184
    def to_sequel_blob
 
185
      ::Sequel::SQL::Blob.new(self)
 
186
    end
 
187
  end
 
188
 
 
189
  refine Symbol do
 
190
    include Sequel::SQL::AliasMethods
 
191
    include Sequel::SQL::CastMethods
 
192
    include Sequel::SQL::OrderMethods
 
193
    include Sequel::SQL::BooleanMethods
 
194
    include Sequel::SQL::NumericMethods
 
195
    include Sequel::SQL::QualifyingMethods
 
196
    include Sequel::SQL::StringMethods
 
197
    include Sequel::SQL::SubscriptMethods
 
198
    include Sequel::SQL::ComplexExpressionMethods
 
199
 
 
200
    # Returns receiver wrapped in an <tt>Sequel::SQL::Identifier</tt>.  Usually used to
 
201
    # prevent splitting the symbol.
 
202
    #
 
203
    #   :a__b # SQL: "a"."b"
 
204
    #   :a__b.identifier # SQL: "a__b"
 
205
    def identifier
 
206
      Sequel::SQL::Identifier.new(self)
 
207
    end
 
208
 
 
209
    # Returns a <tt>Sequel::SQL::Function</tt> with this as the function name,
 
210
    # and the given arguments. This is aliased as <tt>Symbol#[]</tt> if the RUBY_VERSION
 
211
    # is less than 1.9.0. Ruby 1.9 defines <tt>Symbol#[]</tt>, and Sequel
 
212
    # doesn't override methods defined by ruby itself.
 
213
    #
 
214
    #   :now.sql_function # SQL: now()
 
215
    #   :sum.sql_function(:a) # SQL: sum(a)
 
216
    #   :concat.sql_function(:a, :b) # SQL: concat(a, b)
 
217
    def sql_function(*args)
 
218
      Sequel::SQL::Function.new(self, *args)
 
219
    end
 
220
  end
 
221
end