flag_shih_tzu 0.3.1 → 0.3.2

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.
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: