bitfields 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +2 -3
- data/{README.markdown → Readme.md} +9 -5
- data/VERSION +1 -1
- data/bitfields.gemspec +3 -6
- data/lib/bitfields.rb +5 -2
- data/spec/bitfields_spec.rb +41 -0
- metadata +7 -7
data/Rakefile
CHANGED
@@ -11,12 +11,11 @@ end
|
|
11
11
|
|
12
12
|
begin
|
13
13
|
require 'jeweler'
|
14
|
-
project_name = 'bitfields'
|
15
14
|
Jeweler::Tasks.new do |gem|
|
16
|
-
gem.name =
|
15
|
+
gem.name = 'bitfields'
|
17
16
|
gem.summary = "Save migrations and columns by storing multiple booleans in a single integer."
|
18
17
|
gem.email = "grosser.michael@gmail.com"
|
19
|
-
gem.homepage = "http://github.com/grosser/#{
|
18
|
+
gem.homepage = "http://github.com/grosser/#{gem.name}"
|
20
19
|
gem.authors = ["Michael Grosser"]
|
21
20
|
end
|
22
21
|
|
@@ -42,7 +42,8 @@ TIPS
|
|
42
42
|
====
|
43
43
|
- Never do: "#{bitfield_sql(...)} AND #{bitfield_sql(...)}", merge both into one hash
|
44
44
|
- bit_operator is faster in most cases, use :query_mode => :in_list sparingly
|
45
|
-
-
|
45
|
+
- Standard mysql integer is 4 byte -> 32 bitfields
|
46
|
+
- If you are lazy or bad at math you can also do `bitfields :bits, :foo, :bar, :baz`
|
46
47
|
|
47
48
|
![performance](http://chart.apis.google.com/chart?chtt=bit-operator+vs+IN+--+with+index&chd=s:CEGIKNPRUW,DEHJLOQSVX,CFHKMPSYXZ,DHJMPSVYbe,DHLPRVZbfi,FKOUZeinsx,FLQWbglqw2,HNTZfkqw19,BDEGHJLMOP,BDEGIKLNOQ,BDFGIKLNPQ,BDFGILMNPR,BDFHJKMOQR,BDFHJLMOQS,BDFHJLNPRT,BDFHJLNPRT&chxt=x,y&chxl=0:|100K|200K|300K|400K|500K|600K|700K|800K|900K|1000K|1:|0|1441.671ms&cht=lc&chs=600x500&chdl=2bits+%28in%29|3bits+%28in%29|4bits+%28in%29|6bits+%28in%29|8bits+%28in%29|10bits+%28in%29|12bits+%28in%29|14bits+%28in%29|2bits+%28bit%29|3bits+%28bit%29|4bits+%28bit%29|6bits+%28bit%29|8bits+%28bit%29|10bits+%28bit%29|12bits+%28bit%29|14bits+%28bit%29&chco=0000ff,0000ee,0000dd,0000cc,0000bb,0000aa,000099,000088,ff0000,ee0000,dd0000,cc0000,bb0000,aa0000,990000,880000)
|
48
49
|
|
@@ -50,8 +51,11 @@ TODO
|
|
50
51
|
====
|
51
52
|
- convenient named scope `User.with_bitfields(:xxx=>true, :yy=>false)`
|
52
53
|
|
53
|
-
|
54
|
-
|
55
|
-
[
|
56
|
-
|
54
|
+
Authors
|
55
|
+
=======
|
56
|
+
### [Contributors](http://github.com/grosser/bitfields/contributors)
|
57
|
+
- [Hellekin O. Wolf](https://github.com/hellekin)
|
58
|
+
|
59
|
+
[Michael Grosser](http://grosser.it)
|
60
|
+
michael@grosser.it
|
57
61
|
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.2
|
data/bitfields.gemspec
CHANGED
@@ -5,18 +5,15 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{bitfields}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Michael Grosser"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-02-04}
|
13
13
|
s.email = %q{grosser.michael@gmail.com}
|
14
|
-
s.extra_rdoc_files = [
|
15
|
-
"README.markdown"
|
16
|
-
]
|
17
14
|
s.files = [
|
18
|
-
"README.markdown",
|
19
15
|
"Rakefile",
|
16
|
+
"Readme.md",
|
20
17
|
"VERSION",
|
21
18
|
"benchmark/bit_operator_vs_in.rb",
|
22
19
|
"bitfields.gemspec",
|
data/lib/bitfields.rb
CHANGED
@@ -3,6 +3,7 @@ require 'active_support'
|
|
3
3
|
module Bitfields
|
4
4
|
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
5
5
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'] # taken from ActiveRecord::ConnectionAdapters::Column
|
6
|
+
class DuplicateBitNameError < ArgumentError; end
|
6
7
|
|
7
8
|
def self.included(base)
|
8
9
|
base.class_inheritable_accessor :bitfields, :bitfield_options
|
@@ -14,6 +15,7 @@ module Bitfields
|
|
14
15
|
options.keys.select{|key| key.is_a?(Fixnum) }.each do |bit|
|
15
16
|
raise "#{bit} is not a power of 2 !!" unless bit.to_s(2).scan('1').size == 1
|
16
17
|
bit_name = options.delete(bit).to_sym
|
18
|
+
raise DuplicateBitNameError if bitfields.include?(bit_name)
|
17
19
|
bitfields[bit_name] = bit
|
18
20
|
end
|
19
21
|
bitfields
|
@@ -26,10 +28,11 @@ module Bitfields
|
|
26
28
|
end
|
27
29
|
|
28
30
|
module ClassMethods
|
29
|
-
def bitfield(column,
|
31
|
+
def bitfield(column, *args)
|
30
32
|
# prepare ...
|
31
33
|
column = column.to_sym
|
32
|
-
options =
|
34
|
+
options = (args.last.is_a?(Hash) ? args.pop.dup : {}) # since we will modify them...
|
35
|
+
args.each_with_index{|field,i| options[2**(i+1)] = field } # add fields given in normal args to options
|
33
36
|
|
34
37
|
# extract options
|
35
38
|
self.bitfields ||= {}
|
data/spec/bitfields_spec.rb
CHANGED
@@ -36,6 +36,23 @@ class BitOperatorMode < ActiveRecord::Base
|
|
36
36
|
bitfield :bits, 1 => :seller, 2 => :insane, :query_mode => :bit_operator
|
37
37
|
end
|
38
38
|
|
39
|
+
class WithoutThePowerOfTwo < ActiveRecord::Base
|
40
|
+
set_table_name 'users'
|
41
|
+
include Bitfields
|
42
|
+
bitfield :bits, :seller, :insane, :query_mode => :bit_operator
|
43
|
+
end
|
44
|
+
|
45
|
+
class WithoutThePowerOfTwoWithoutOptions < ActiveRecord::Base
|
46
|
+
set_table_name 'users'
|
47
|
+
include Bitfields
|
48
|
+
bitfield :bits, :seller, :insane
|
49
|
+
end
|
50
|
+
|
51
|
+
class CheckRaise < ActiveRecord::Base
|
52
|
+
set_table_name 'users'
|
53
|
+
include Bitfields
|
54
|
+
end
|
55
|
+
|
39
56
|
class ManyBitsUser < User
|
40
57
|
set_table_name 'users'
|
41
58
|
end
|
@@ -215,6 +232,30 @@ describe Bitfields do
|
|
215
232
|
BitOperatorMode.all(:conditions => MultiBitUser.bitfield_sql(:seller => true, :insane => false)).should == [u2]
|
216
233
|
end
|
217
234
|
end
|
235
|
+
|
236
|
+
describe 'without the power of two' do
|
237
|
+
it 'has all fields' do
|
238
|
+
u = WithoutThePowerOfTwo.create!(:seller => false, :insane => true)
|
239
|
+
u.seller.should == false
|
240
|
+
u.insane.should == true
|
241
|
+
WithoutThePowerOfTwo.bitfield_options.should == {:bits=>{:query_mode=>:bit_operator}}
|
242
|
+
end
|
243
|
+
|
244
|
+
it "can e built without options" do
|
245
|
+
u = WithoutThePowerOfTwoWithoutOptions.create!(:seller => false, :insane => true)
|
246
|
+
u.seller.should == false
|
247
|
+
u.insane.should == true
|
248
|
+
WithoutThePowerOfTwoWithoutOptions.bitfield_options.should == {:bits=>{}}
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
it "checks that bitfields are unique" do
|
253
|
+
lambda{
|
254
|
+
CheckRaise.class_eval do
|
255
|
+
bitfield :foo, :bar, :baz, :bar
|
256
|
+
end
|
257
|
+
}.should raise_error(Bitfields::DuplicateBitNameError)
|
258
|
+
end
|
218
259
|
end
|
219
260
|
|
220
261
|
describe :set_bitfield_sql do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitfields
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Michael Grosser
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-02-04 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -25,11 +25,11 @@ executables: []
|
|
25
25
|
|
26
26
|
extensions: []
|
27
27
|
|
28
|
-
extra_rdoc_files:
|
29
|
-
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
30
|
files:
|
31
|
-
- README.markdown
|
32
31
|
- Rakefile
|
32
|
+
- Readme.md
|
33
33
|
- VERSION
|
34
34
|
- benchmark/bit_operator_vs_in.rb
|
35
35
|
- bitfields.gemspec
|