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 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 unless check_flag_column(colmn)
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
- return DEFAULT_COLUMN_NAME if self.class.flag_mapping.nil?
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
@@ -1,3 +1,3 @@
1
1
  module FlagShihTzu
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -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.send(:determine_flag_colmn_for, :warpdrive)
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.send(:determine_flag_colmn_for, :xxx)
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.send(:determine_flag_colmn_for, :jeanlucpicard)
728
- assert_equal 'bits', @big_spaceship.send(:determine_flag_colmn_for, :warpdrive)
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 "spaceships.flags = spaceships.flags | 1", Spaceship.send( :sql_set_for_flag, :warpdrive, 'flags', true)
811
- assert_equal "spaceships.flags = spaceships.flags & ~1", Spaceship.send( :sql_set_for_flag, :warpdrive, 'flags', false)
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"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flag_shih_tzu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: