flag_shih_tzu 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +9 -0
- data/README.rdoc +33 -0
- data/lib/flag_shih_tzu.rb +20 -9
- data/lib/flag_shih_tzu/version.rb +1 -1
- data/test/flag_shih_tzu_test.rb +35 -6
- data/test/test_helper.rb +5 -0
- metadata +1 -1
data/CHANGELOG
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
Version 0.3.2 - NOV.06.2012
|
2
|
+
|
3
|
+
* Adds skip column check option :check_for_column - from arturaz
|
4
|
+
* Adds a 'smart' set_flag_sql method which will auto determine the correct column for the given flag - from arturaz
|
5
|
+
* Changes the behavior of sql_set_for_flag to not use table names in the generated SQL
|
6
|
+
- because it didn't actually work before
|
7
|
+
- Now there is a test ensuring that the generated SQL can be executed by a real DB
|
8
|
+
- This improved sql_set_for_flag underlies the public set_flag_sql method
|
9
|
+
|
1
10
|
Version 0.3.1 - NOV.06.2012
|
2
11
|
|
3
12
|
* Adds new methods (for a flag column named 'bar', with many individual flags within) - from ddidier
|
data/README.rdoc
CHANGED
@@ -302,6 +302,39 @@ operators in the SQL instead of an IN() list:
|
|
302
302
|
The drawback is that due to the bit operator, this query can not use an index
|
303
303
|
on the flags column.
|
304
304
|
|
305
|
+
===Updating flag column by raw sql
|
306
|
+
|
307
|
+
If you need to do mass updates without initializing object for each row, you can
|
308
|
+
use #set_flag_sql method on your class. Example:
|
309
|
+
|
310
|
+
Spaceship.set_flag_sql(:warpdrive, true) # "flags = flags | 1"
|
311
|
+
Spaceship.set_flag_sql(:shields, false) # "flags = flags & ~2"
|
312
|
+
|
313
|
+
And then use it in:
|
314
|
+
|
315
|
+
Spaceship.update_all Spaceship.set_flag_sql(:shields, false)
|
316
|
+
|
317
|
+
Beware that having multiple flag manipulation sql statements probably will not
|
318
|
+
bring required result (at least on sqlite3, not tested on other databases), so
|
319
|
+
you _should not_ do this:
|
320
|
+
|
321
|
+
Spaceship.update_all "#{Spaceship.set_flag_sql(:shields, false)},#{
|
322
|
+
Spaceship.set_flag_sql(:warpdrive, true)}"
|
323
|
+
|
324
|
+
General rule of thumb: issue only one flag update per update statement.
|
325
|
+
|
326
|
+
===Skipping flag column check
|
327
|
+
|
328
|
+
By default when you call has_flags in your code it will automatically check
|
329
|
+
your database to see if you have correct column defined.
|
330
|
+
|
331
|
+
Sometimes this may not be a wanted behaviour (e.g. when loading model without
|
332
|
+
database connection established) so you can set :check_for_column option to
|
333
|
+
false to avoid it.
|
334
|
+
|
335
|
+
has_flags 1 => :warpdrive,
|
336
|
+
2 => :shields,
|
337
|
+
:check_for_column => false
|
305
338
|
|
306
339
|
==Running the gem tests
|
307
340
|
|
data/lib/flag_shih_tzu.rb
CHANGED
@@ -27,11 +27,12 @@ module FlagShihTzu
|
|
27
27
|
:named_scopes => true,
|
28
28
|
:column => DEFAULT_COLUMN_NAME,
|
29
29
|
:flag_query_mode => :in_list,
|
30
|
-
:strict => false
|
30
|
+
:strict => false,
|
31
|
+
:check_for_column => true
|
31
32
|
}.update(opts)
|
32
33
|
colmn = opts[:column].to_s
|
33
34
|
|
34
|
-
return
|
35
|
+
return if opts[:check_for_column] && ! check_flag_column(colmn)
|
35
36
|
|
36
37
|
# options are stored in a class level hash and apply per-column
|
37
38
|
self.flag_options ||= {}
|
@@ -157,6 +158,21 @@ module FlagShihTzu
|
|
157
158
|
raise ArgumentError, "Invalid flag '#{flag}'" if flag_mapping[colmn].nil? || !flag_mapping[colmn].include?(flag)
|
158
159
|
end
|
159
160
|
|
161
|
+
# Returns SQL statement to enable/disable flag.
|
162
|
+
# Automatically determines the correct column.
|
163
|
+
def set_flag_sql(flag, value, colmn = nil, custom_table_name = self.table_name)
|
164
|
+
colmn = determine_flag_colmn_for(flag) if colmn.nil?
|
165
|
+
sql_set_for_flag(flag, colmn, value, custom_table_name)
|
166
|
+
end
|
167
|
+
|
168
|
+
def determine_flag_colmn_for(flag)
|
169
|
+
return DEFAULT_COLUMN_NAME if self.flag_mapping.nil?
|
170
|
+
self.flag_mapping.each_pair do |colmn, mapping|
|
171
|
+
return colmn if mapping.include?(flag)
|
172
|
+
end
|
173
|
+
raise NoSuchFlagException.new("determine_flag_colmn_for: Couldn't determine column for your flags!")
|
174
|
+
end
|
175
|
+
|
160
176
|
private
|
161
177
|
|
162
178
|
def parse_options(*args)
|
@@ -222,8 +238,7 @@ module FlagShihTzu
|
|
222
238
|
|
223
239
|
def sql_set_for_flag(flag, colmn, enabled = true, custom_table_name = self.table_name)
|
224
240
|
check_flag(flag, colmn)
|
225
|
-
|
226
|
-
"#{custom_table_name}.#{colmn} = #{custom_table_name}.#{colmn} #{enabled ? "| " : "& ~" }#{flag_mapping[colmn][flag]}"
|
241
|
+
"#{colmn} = #{colmn} #{enabled ? "| " : "& ~" }#{flag_mapping[colmn][flag]}"
|
227
242
|
end
|
228
243
|
|
229
244
|
def is_valid_flag_key(flag_key)
|
@@ -311,11 +326,7 @@ module FlagShihTzu
|
|
311
326
|
end
|
312
327
|
|
313
328
|
def determine_flag_colmn_for(flag)
|
314
|
-
|
315
|
-
self.class.flag_mapping.each_pair do |colmn, mapping|
|
316
|
-
return colmn if mapping.include?(flag)
|
317
|
-
end
|
318
|
-
raise NoSuchFlagException.new("determine_flag_colmn_for: Couldn't determine column for your flags!")
|
329
|
+
self.class.determine_flag_colmn_for(flag)
|
319
330
|
end
|
320
331
|
|
321
332
|
end
|
data/test/flag_shih_tzu_test.rb
CHANGED
@@ -250,6 +250,35 @@ class FlagShihTzuClassMethodsTest < Test::Unit::TestCase
|
|
250
250
|
assert_where_value "(spaceships.flags & 2 = 0)", SpaceshipWithBitOperatorQueryMode.not_shields
|
251
251
|
end
|
252
252
|
|
253
|
+
def test_should_work_with_raw_sql
|
254
|
+
spaceship = Spaceship.new
|
255
|
+
spaceship.enable_flag(:shields)
|
256
|
+
spaceship.enable_flag(:electrolytes)
|
257
|
+
spaceship.save!
|
258
|
+
|
259
|
+
Spaceship.update_all Spaceship.set_flag_sql(:warpdrive, true),
|
260
|
+
["id=?", spaceship.id]
|
261
|
+
spaceship.reload
|
262
|
+
|
263
|
+
assert_equal true, spaceship.warpdrive
|
264
|
+
assert_equal true, spaceship.shields
|
265
|
+
assert_equal true, spaceship.electrolytes
|
266
|
+
|
267
|
+
spaceship = Spaceship.new
|
268
|
+
spaceship.enable_flag(:warpdrive)
|
269
|
+
spaceship.enable_flag(:shields)
|
270
|
+
spaceship.enable_flag(:electrolytes)
|
271
|
+
spaceship.save!
|
272
|
+
|
273
|
+
Spaceship.update_all Spaceship.set_flag_sql(:shields, false),
|
274
|
+
["id=?", spaceship.id]
|
275
|
+
spaceship.reload
|
276
|
+
|
277
|
+
assert_equal true, spaceship.warpdrive
|
278
|
+
assert_equal false, spaceship.shields
|
279
|
+
assert_equal true, spaceship.electrolytes
|
280
|
+
end
|
281
|
+
|
253
282
|
def test_should_return_the_correct_number_of_items_from_a_named_scope
|
254
283
|
spaceship = Spaceship.new
|
255
284
|
spaceship.enable_flag(:warpdrive)
|
@@ -714,18 +743,18 @@ class FlagShihTzuInstanceMethodsTest < Test::Unit::TestCase
|
|
714
743
|
end
|
715
744
|
|
716
745
|
def test_column_guessing_for_default_column
|
717
|
-
assert_equal 'flags', @spaceship.
|
746
|
+
assert_equal 'flags', @spaceship.class.determine_flag_colmn_for(:warpdrive)
|
718
747
|
end
|
719
748
|
|
720
749
|
def test_column_guessing_for_default_column
|
721
750
|
assert_raises FlagShihTzu::NoSuchFlagException do
|
722
|
-
@spaceship.
|
751
|
+
@spaceship.class.determine_flag_colmn_for(:xxx)
|
723
752
|
end
|
724
753
|
end
|
725
754
|
|
726
755
|
def test_column_guessing_for_2_columns
|
727
|
-
assert_equal 'commanders', @big_spaceship.
|
728
|
-
assert_equal 'bits', @big_spaceship.
|
756
|
+
assert_equal 'commanders', @big_spaceship.class.determine_flag_colmn_for(:jeanlucpicard)
|
757
|
+
assert_equal 'bits', @big_spaceship.class.determine_flag_colmn_for(:warpdrive)
|
729
758
|
end
|
730
759
|
|
731
760
|
end
|
@@ -807,8 +836,8 @@ class FlagShihTzuDerivedClassTest < Test::Unit::TestCase
|
|
807
836
|
end
|
808
837
|
|
809
838
|
def test_should_return_a_sql_set_method_for_flag
|
810
|
-
assert_equal "
|
811
|
-
assert_equal "
|
839
|
+
assert_equal "flags = flags | 1", Spaceship.send( :sql_set_for_flag, :warpdrive, 'flags', true)
|
840
|
+
assert_equal "flags = flags & ~1", Spaceship.send( :sql_set_for_flag, :warpdrive, 'flags', false)
|
812
841
|
end
|
813
842
|
|
814
843
|
end
|
data/test/test_helper.rb
CHANGED
@@ -7,6 +7,11 @@ ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + "/debug.log")
|
|
7
7
|
ActiveRecord::Migration.verbose = false
|
8
8
|
|
9
9
|
configs = YAML.load_file(File.dirname(__FILE__) + "/database.yml")
|
10
|
+
if RUBY_PLATFORM == "java"
|
11
|
+
configs['sqlite']['adapter'] = 'jdbcsqlite3'
|
12
|
+
configs['mysql']['adapter'] = 'jdbcmysql'
|
13
|
+
configs['postgresql']['adapter'] = 'jdbcpostgresql'
|
14
|
+
end
|
10
15
|
ActiveRecord::Base.configurations = configs
|
11
16
|
|
12
17
|
db_name = ENV["DB"] || "sqlite"
|