bitfields 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fbae8863b34f3374742a6af0481aac9f284cf15b
4
+ data.tar.gz: 394e4e9db360d7eecfa030cf072047d3b687a768
5
+ SHA512:
6
+ metadata.gz: b32ed7e44546be81ae203e252564c3286bf80ba275de4b8a695ebe3b6d14017a4dca244469443f3edde593475ed89d97954a04314c0a3cca1f25167705c2c6b3
7
+ data.tar.gz: 7a63c7f78bb3d884fb9e88283ddc653d8963a1c347c17ec7b3f6a4efc27f345e8a8c5bf37027b4d5ff261e4cb65143c727532e6fc03e810625c95b4abe54af84
@@ -38,19 +38,6 @@ module Bitfields
38
38
  bitfields
39
39
  end
40
40
 
41
- def self.ar_3?
42
- defined?(ActiveRecord::VERSION::MAJOR) and ActiveRecord::VERSION::MAJOR >= 3
43
- end
44
-
45
- # AR 3+ -> :scope, below :named_scope
46
- def self.ar_scoping_method
47
- if ar_3?
48
- :scope
49
- else
50
- :named_scope
51
- end
52
- end
53
-
54
41
  module ClassMethods
55
42
  def bitfield(column, *args)
56
43
  column = column.to_sym
@@ -99,9 +86,8 @@ module Bitfields
99
86
  define_method("#{bit_name}=") { |value| set_bitfield_value(bit_name, value) }
100
87
 
101
88
  if options[:scopes] != false
102
- scoping_method = Bitfields.ar_scoping_method
103
- send scoping_method, bit_name, bitfield_scope_options(bit_name => true)
104
- send scoping_method, "not_#{bit_name}", bitfield_scope_options(bit_name => false)
89
+ scope bit_name, bitfield_scope_options(bit_name => true)
90
+ scope "not_#{bit_name}", bitfield_scope_options(bit_name => false)
105
91
  end
106
92
  end
107
93
 
@@ -109,13 +95,7 @@ module Bitfields
109
95
  end
110
96
 
111
97
  def bitfield_scope_options(bit_values)
112
- sql = bitfield_sql(bit_values)
113
-
114
- if Bitfields.ar_3?
115
- lambda { where(sql) }
116
- else
117
- {:conditions => sql}
118
- end
98
+ -> { where(bitfield_sql(bit_values)) }
119
99
  end
120
100
 
121
101
  def bitfield_sql_by_column(column, bit_values, options={})
@@ -167,6 +147,13 @@ module Bitfields
167
147
  Hash[self.class.bitfields[column.to_sym].map{|bit_name, _| [bit_name, bitfield_value(bit_name)]}]
168
148
  end
169
149
 
150
+ def bitfield_changes
151
+ self.class.bitfields.values.flat_map(&:keys).each_with_object({}) do |bit, changes|
152
+ old, current = bitfield_value_was(bit), bitfield_value(bit)
153
+ changes[bit.to_s] = [old, current] unless old == current
154
+ end
155
+ end
156
+
170
157
  private
171
158
 
172
159
  def bitfield_value(bit_name)
@@ -174,16 +161,17 @@ module Bitfields
174
161
  current_value & bit != 0
175
162
  end
176
163
 
164
+ def bitfield_value_was(bit_name)
165
+ column, bit, _ = bitfield_info(bit_name)
166
+ send("#{column}_was") & bit != 0
167
+ end
168
+
177
169
  def set_bitfield_value(bit_name, value)
178
170
  column, bit, current_value = bitfield_info(bit_name)
179
171
  new_value = TRUE_VALUES.include?(value)
180
172
  old_value = bitfield_value(bit_name)
181
173
  return if new_value == old_value
182
174
 
183
- if defined? changed_attributes
184
- send(:changed_attributes).merge!(bit_name.to_s => old_value)
185
- end
186
-
187
175
  # 8 + 1 == 9 // 8 + 8 == 8 // 1 - 8 == 1 // 8 - 8 == 0
188
176
  new_bits = if new_value then current_value | bit else (current_value | bit) - bit end
189
177
  send("#{column}=", new_bits)
@@ -6,16 +6,15 @@ RSpec::Matchers.define :have_a_bitfield do |field|
6
6
  klass.respond_to?("#{field}=")
7
7
  end
8
8
 
9
- failure_message_for_should do |klass|
9
+ failure_message do |klass|
10
10
  "expected #{expected.join} to be a bitfield property defined on #{klass}"
11
11
  end
12
12
 
13
- failure_message_for_should_not do |klass|
13
+ failure_message_when_negated do |klass|
14
14
  "expected #{expected.join} to NOT be a bitfield property defined on #{klass}"
15
15
  end
16
16
 
17
17
  description do
18
18
  "be a bitfield on #{expected}"
19
19
  end
20
-
21
20
  end
@@ -1,3 +1,3 @@
1
1
  module Bitfields
2
- Version = VERSION = "0.4.3"
2
+ Version = VERSION = "0.5.0"
3
3
  end
metadata CHANGED
@@ -1,75 +1,131 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitfields
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
5
- prerelease:
4
+ version: 0.5.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Michael Grosser
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-05-14 00:00:00.000000000 Z
13
- dependencies: []
11
+ date: 2015-01-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: wwtd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: sqlite3
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: bump
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
14
97
  description:
15
98
  email: michael@grosser.it
16
99
  executables: []
17
100
  extensions: []
18
101
  extra_rdoc_files: []
19
102
  files:
20
- - .travis.yml
21
- - Appraisals
22
- - Gemfile
23
- - Gemfile.lock
24
- - Rakefile
25
103
  - Readme.md
26
- - benchmark/bit_operator_vs_in.rb
27
- - bitfields.gemspec
28
- - gemfiles/activerecord_2.3.gemfile
29
- - gemfiles/activerecord_2.3.gemfile.lock
30
- - gemfiles/activerecord_3.0.gemfile
31
- - gemfiles/activerecord_3.0.gemfile.lock
32
- - gemfiles/activerecord_3.1.gemfile
33
- - gemfiles/activerecord_3.1.gemfile.lock
34
- - gemfiles/activerecord_3.2.gemfile
35
- - gemfiles/activerecord_3.2.gemfile.lock
36
- - gemfiles/activerecord_4.0.gemfile
37
- - gemfiles/activerecord_4.0.gemfile.lock
38
104
  - lib/bitfields.rb
39
105
  - lib/bitfields/rspec.rb
40
106
  - lib/bitfields/version.rb
41
- - spec/bitfields_spec.rb
42
- - spec/database.rb
43
- - spec/spec_helper.rb
44
- homepage: http://github.com/grosser/bitfields
107
+ homepage: https://github.com/grosser/bitfields
45
108
  licenses:
46
109
  - MIT
110
+ metadata: {}
47
111
  post_install_message:
48
112
  rdoc_options: []
49
113
  require_paths:
50
114
  - lib
51
115
  required_ruby_version: !ruby/object:Gem::Requirement
52
- none: false
53
116
  requirements:
54
- - - ! '>='
117
+ - - ">="
55
118
  - !ruby/object:Gem::Version
56
- version: '0'
57
- segments:
58
- - 0
59
- hash: 950427918472941761
119
+ version: 1.9.3
60
120
  required_rubygems_version: !ruby/object:Gem::Requirement
61
- none: false
62
121
  requirements:
63
- - - ! '>='
122
+ - - ">="
64
123
  - !ruby/object:Gem::Version
65
124
  version: '0'
66
- segments:
67
- - 0
68
- hash: 950427918472941761
69
125
  requirements: []
70
126
  rubyforge_project:
71
- rubygems_version: 1.8.25
127
+ rubygems_version: 2.2.2
72
128
  signing_key:
73
- specification_version: 3
129
+ specification_version: 4
74
130
  summary: Save migrations and columns by storing multiple booleans in a single integer
75
131
  test_files: []
@@ -1,19 +0,0 @@
1
- rvm:
2
- - 1.8.7
3
- - 1.9.3
4
- - 2.0.0
5
- gemfile:
6
- - gemfiles/activerecord_2.3.gemfile
7
- - gemfiles/activerecord_3.0.gemfile
8
- - gemfiles/activerecord_3.1.gemfile
9
- - gemfiles/activerecord_3.2.gemfile
10
- - gemfiles/activerecord_4.0.gemfile
11
- matrix:
12
- exclude:
13
- - rvm: 1.8.7
14
- gemfile: gemfiles/activerecord_4.0.gemfile
15
- - rvm: 2.0.0
16
- gemfile: gemfiles/activerecord_2.3.gemfile
17
- - rvm: 2.0.0
18
- gemfile: gemfiles/activerecord_3.0.gemfile
19
- script: rake spec
data/Appraisals DELETED
@@ -1,9 +0,0 @@
1
- ["2.3", "3.0", "3.1", "3.2"].each do |version|
2
- appraise "activerecord_#{version}" do
3
- gem "activerecord", "~> #{version}.0"
4
- end
5
- end
6
-
7
- appraise "activerecord_4.0" do
8
- gem "activerecord", "~> 4.0.0.rc"
9
- end
data/Gemfile DELETED
@@ -1,9 +0,0 @@
1
- source "https://rubygems.org"
2
- gemspec
3
-
4
- gem 'appraisal'
5
- gem 'activerecord'
6
- gem 'sqlite3'
7
- gem 'rake'
8
- gem 'rspec', '~>2'
9
- gem 'bump'
@@ -1,51 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- bitfields (0.4.3)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activemodel (3.2.11)
10
- activesupport (= 3.2.11)
11
- builder (~> 3.0.0)
12
- activerecord (3.2.11)
13
- activemodel (= 3.2.11)
14
- activesupport (= 3.2.11)
15
- arel (~> 3.0.2)
16
- tzinfo (~> 0.3.29)
17
- activesupport (3.2.11)
18
- i18n (~> 0.6)
19
- multi_json (~> 1.0)
20
- appraisal (0.5.1)
21
- bundler
22
- rake
23
- arel (3.0.2)
24
- builder (3.0.4)
25
- bump (0.3.9)
26
- diff-lcs (1.1.3)
27
- i18n (0.6.1)
28
- multi_json (1.5.0)
29
- rake (10.0.3)
30
- rspec (2.12.0)
31
- rspec-core (~> 2.12.0)
32
- rspec-expectations (~> 2.12.0)
33
- rspec-mocks (~> 2.12.0)
34
- rspec-core (2.12.2)
35
- rspec-expectations (2.12.1)
36
- diff-lcs (~> 1.1.3)
37
- rspec-mocks (2.12.1)
38
- sqlite3 (1.3.7)
39
- tzinfo (0.3.35)
40
-
41
- PLATFORMS
42
- ruby
43
-
44
- DEPENDENCIES
45
- activerecord
46
- appraisal
47
- bitfields!
48
- bump
49
- rake
50
- rspec (~> 2)
51
- sqlite3
data/Rakefile DELETED
@@ -1,11 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "bump/tasks"
3
- require "appraisal"
4
-
5
- task :spec do
6
- sh "rspec spec/"
7
- end
8
-
9
- task :default do
10
- sh "bundle exec rake appraisal:install && bundle exec rake appraisal spec"
11
- end
@@ -1,137 +0,0 @@
1
- bit_counts = [2,3,4,6,8,10,12,14]
2
- record_counts = (1..10).to_a.map{|i| i * 100_000 }
3
- use_index = true
4
- database = ARGV[0]
5
-
6
- puts "running#{' with index' if use_index} on #{database}"
7
-
8
- $LOAD_PATH.unshift File.expand_path('lib')
9
- require 'rubygems'
10
- gem 'gchartrb'
11
- require 'google_chart'
12
- require 'active_record'
13
- require 'bitfields'
14
-
15
- def benchmark
16
- t = Time.now.to_f
17
- yield
18
- Time.now.to_f - t
19
- end
20
-
21
- def create(bit_counts, count)
22
- count.times do |i|
23
- columns = bit_counts.map do |bits_count|
24
- ["bit_#{bits_count}", rand(2**(bits_count-1))]
25
- end
26
- User.create!(Hash[columns])
27
- end
28
- end
29
-
30
- def connect(db)
31
- if db == 'mysql'
32
- puts 'using mysql'
33
- ActiveRecord::Base.establish_connection(
34
- :adapter => "mysql",
35
- :database => "bitfields_benchmark"
36
- )
37
- else
38
- puts 'using sqlite'
39
- ActiveRecord::Base.establish_connection(
40
- :adapter => "sqlite3",
41
- :database => ":memory:"
42
- )
43
- end
44
- end
45
-
46
- def create_model_table(bit_counts, use_index)
47
- ActiveRecord::Schema.define(:version => 2) do
48
- drop_table :users rescue nil
49
- create_table :users do |t|
50
- bit_counts.each do |bit_count|
51
- t.integer "bit_#{bit_count}", :default => 0, :null => false
52
- end
53
- end
54
-
55
- if use_index
56
- bit_counts.each do |bit_count|
57
- add_index :users, "bit_#{bit_count}"
58
- end
59
- end
60
- end
61
- end
62
-
63
- def create_model_fields(bit_counts)
64
- puts "creating model"
65
- User.class_eval do
66
- include Bitfields
67
-
68
- # this takes long for 15/20 bits, maybe needs to be optimized..
69
- bit_counts.each do |bits_count|
70
- bits = {}
71
- 0.upto(bits_count-1) do |bit|
72
- bits[2**bit] = "bit_#{bits_count}_#{bit}"
73
- end
74
-
75
- bitfield "bit_#{bits_count}", bits
76
- end
77
- end
78
- end
79
-
80
- def test_speed(bit_counts, query_mode)
81
- result = bit_counts.map do |bit_count|
82
- sql = User.bitfield_sql({"bit_#{bit_count}_1" => true}, :query_mode => query_mode)
83
- sql = "select SQL_NO_CACHE count(*) from users where #{sql}"
84
- # puts User.connection.select_all("EXPLAIN #{sql}").inspect
85
- # puts sql[0..100]
86
- time = benchmark do
87
- User.connection.execute sql
88
- end
89
- puts "#{bit_count} -> #{time}"
90
- [bit_count, time]
91
- end
92
- Hash[result]
93
- end
94
-
95
- connect(database)
96
- create_model_table(bit_counts, use_index)
97
- class User < ActiveRecord::Base
98
- end
99
- create_model_fields(bit_counts)
100
-
101
- puts "creating test data"
102
- last = 0
103
-
104
- # collect graph data
105
- graphs = {:bit => {}, :in => {}}
106
- record_counts.each do |record_count|
107
- create(bit_counts, record_count-last)
108
- last = record_count
109
-
110
- puts "testing with #{record_count} records -- bit_operator"
111
- graphs[:bit][record_count] = test_speed(bit_counts, :bit_operator)
112
-
113
- puts "testing with #{record_count} records -- in_list"
114
- graphs[:in][record_count] = test_speed(bit_counts, :in_list)
115
- end
116
-
117
- # print them
118
- colors = {:bit => 'xx0000', :in => '0000xx'}
119
- alpha_num = (('0'..'9').to_a + ('a'..'f').to_a).reverse
120
- title = "bit-operator vs IN -- #{use_index ? 'with' : 'without'} index"
121
- url = GoogleChart::LineChart.new('600x500', title, false) do |line|
122
- max_y = 0
123
- graphs.each do |type, line_data|
124
- bit_counts.each do |bit_count|
125
- data = record_counts.map{|rc| line_data[rc][bit_count] }
126
- name = "#{bit_count}bits (#{type})"
127
- color = colors[type].sub('xx', alpha_num[bit_counts.index(bit_count)]*2)
128
- line.data(name, data, color)
129
- max_y = [data.max, max_y].max
130
- end
131
- end
132
-
133
- line.axis :x, :labels => record_counts.map{|c|"#{c/1000}K"}
134
- line.axis :y, :labels => ['0', "%.3fms" % [max_y*1000]]
135
- end.to_url
136
-
137
- puts url
@@ -1,12 +0,0 @@
1
- $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2
- name = "bitfields"
3
- require "#{name}/version"
4
-
5
- Gem::Specification.new name, Bitfields::VERSION do |s|
6
- s.summary = "Save migrations and columns by storing multiple booleans in a single integer"
7
- s.authors = ["Michael Grosser"]
8
- s.email = "michael@grosser.it"
9
- s.homepage = "http://github.com/grosser/#{name}"
10
- s.files = `git ls-files`.split("\n")
11
- s.license = 'MIT'
12
- end
@@ -1,12 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "sqlite3"
7
- gem "rake"
8
- gem "rspec", "~>2"
9
- gem "bump"
10
- gem "activerecord", "~> 2.3.0"
11
-
12
- gemspec :path=>"../"
@@ -1,38 +0,0 @@
1
- PATH
2
- remote: /Users/mgrosser/code/tools/bitfields
3
- specs:
4
- bitfields (0.4.2)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activerecord (2.3.15)
10
- activesupport (= 2.3.15)
11
- activesupport (2.3.15)
12
- appraisal (0.5.1)
13
- bundler
14
- rake
15
- bump (0.3.9)
16
- diff-lcs (1.1.3)
17
- rake (10.0.3)
18
- rspec (2.12.0)
19
- rspec-core (~> 2.12.0)
20
- rspec-expectations (~> 2.12.0)
21
- rspec-mocks (~> 2.12.0)
22
- rspec-core (2.12.2)
23
- rspec-expectations (2.12.1)
24
- diff-lcs (~> 1.1.3)
25
- rspec-mocks (2.12.1)
26
- sqlite3 (1.3.7)
27
-
28
- PLATFORMS
29
- ruby
30
-
31
- DEPENDENCIES
32
- activerecord (~> 2.3.0)
33
- appraisal
34
- bitfields!
35
- bump
36
- rake
37
- rspec (~> 2)
38
- sqlite3
@@ -1,12 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "sqlite3"
7
- gem "rake"
8
- gem "rspec", "~>2"
9
- gem "bump"
10
- gem "activerecord", "~> 3.0.0"
11
-
12
- gemspec :path=>"../"
@@ -1,49 +0,0 @@
1
- PATH
2
- remote: /Users/mgrosser/code/tools/bitfields
3
- specs:
4
- bitfields (0.4.2)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activemodel (3.0.19)
10
- activesupport (= 3.0.19)
11
- builder (~> 2.1.2)
12
- i18n (~> 0.5.0)
13
- activerecord (3.0.19)
14
- activemodel (= 3.0.19)
15
- activesupport (= 3.0.19)
16
- arel (~> 2.0.10)
17
- tzinfo (~> 0.3.23)
18
- activesupport (3.0.19)
19
- appraisal (0.5.1)
20
- bundler
21
- rake
22
- arel (2.0.10)
23
- builder (2.1.2)
24
- bump (0.3.9)
25
- diff-lcs (1.1.3)
26
- i18n (0.5.0)
27
- rake (10.0.3)
28
- rspec (2.12.0)
29
- rspec-core (~> 2.12.0)
30
- rspec-expectations (~> 2.12.0)
31
- rspec-mocks (~> 2.12.0)
32
- rspec-core (2.12.2)
33
- rspec-expectations (2.12.1)
34
- diff-lcs (~> 1.1.3)
35
- rspec-mocks (2.12.1)
36
- sqlite3 (1.3.7)
37
- tzinfo (0.3.35)
38
-
39
- PLATFORMS
40
- ruby
41
-
42
- DEPENDENCIES
43
- activerecord (~> 3.0.0)
44
- appraisal
45
- bitfields!
46
- bump
47
- rake
48
- rspec (~> 2)
49
- sqlite3
@@ -1,12 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "sqlite3"
7
- gem "rake"
8
- gem "rspec", "~>2"
9
- gem "bump"
10
- gem "activerecord", "~> 3.1.0"
11
-
12
- gemspec :path=>"../"
@@ -1,51 +0,0 @@
1
- PATH
2
- remote: /Users/mgrosser/code/tools/bitfields
3
- specs:
4
- bitfields (0.4.2)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activemodel (3.1.8)
10
- activesupport (= 3.1.8)
11
- builder (~> 3.0.0)
12
- i18n (~> 0.6)
13
- activerecord (3.1.8)
14
- activemodel (= 3.1.8)
15
- activesupport (= 3.1.8)
16
- arel (~> 2.2.3)
17
- tzinfo (~> 0.3.29)
18
- activesupport (3.1.8)
19
- multi_json (>= 1.0, < 1.3)
20
- appraisal (0.5.1)
21
- bundler
22
- rake
23
- arel (2.2.3)
24
- builder (3.0.4)
25
- bump (0.3.9)
26
- diff-lcs (1.1.3)
27
- i18n (0.6.1)
28
- multi_json (1.2.0)
29
- rake (10.0.3)
30
- rspec (2.12.0)
31
- rspec-core (~> 2.12.0)
32
- rspec-expectations (~> 2.12.0)
33
- rspec-mocks (~> 2.12.0)
34
- rspec-core (2.12.2)
35
- rspec-expectations (2.12.1)
36
- diff-lcs (~> 1.1.3)
37
- rspec-mocks (2.12.1)
38
- sqlite3 (1.3.7)
39
- tzinfo (0.3.35)
40
-
41
- PLATFORMS
42
- ruby
43
-
44
- DEPENDENCIES
45
- activerecord (~> 3.1.0)
46
- appraisal
47
- bitfields!
48
- bump
49
- rake
50
- rspec (~> 2)
51
- sqlite3
@@ -1,12 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "sqlite3"
7
- gem "rake"
8
- gem "rspec", "~>2"
9
- gem "bump"
10
- gem "activerecord", "~> 3.2.0"
11
-
12
- gemspec :path=>"../"
@@ -1,51 +0,0 @@
1
- PATH
2
- remote: /Users/mgrosser/code/tools/bitfields
3
- specs:
4
- bitfields (0.4.2)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activemodel (3.2.11)
10
- activesupport (= 3.2.11)
11
- builder (~> 3.0.0)
12
- activerecord (3.2.11)
13
- activemodel (= 3.2.11)
14
- activesupport (= 3.2.11)
15
- arel (~> 3.0.2)
16
- tzinfo (~> 0.3.29)
17
- activesupport (3.2.11)
18
- i18n (~> 0.6)
19
- multi_json (~> 1.0)
20
- appraisal (0.5.1)
21
- bundler
22
- rake
23
- arel (3.0.2)
24
- builder (3.0.4)
25
- bump (0.3.9)
26
- diff-lcs (1.1.3)
27
- i18n (0.6.1)
28
- multi_json (1.5.0)
29
- rake (10.0.3)
30
- rspec (2.12.0)
31
- rspec-core (~> 2.12.0)
32
- rspec-expectations (~> 2.12.0)
33
- rspec-mocks (~> 2.12.0)
34
- rspec-core (2.12.2)
35
- rspec-expectations (2.12.1)
36
- diff-lcs (~> 1.1.3)
37
- rspec-mocks (2.12.1)
38
- sqlite3 (1.3.7)
39
- tzinfo (0.3.35)
40
-
41
- PLATFORMS
42
- ruby
43
-
44
- DEPENDENCIES
45
- activerecord (~> 3.2.0)
46
- appraisal
47
- bitfields!
48
- bump
49
- rake
50
- rspec (~> 2)
51
- sqlite3
@@ -1,12 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "appraisal"
6
- gem "sqlite3"
7
- gem "rake"
8
- gem "rspec", "~>2"
9
- gem "bump"
10
- gem "activerecord", "~> 4.0.0.rc"
11
-
12
- gemspec :path=>"../"
@@ -1,59 +0,0 @@
1
- PATH
2
- remote: /Users/mgrosser/code/tools/bitfields
3
- specs:
4
- bitfields (0.4.2)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- activemodel (4.0.0.rc1)
10
- activesupport (= 4.0.0.rc1)
11
- builder (~> 3.1.0)
12
- activerecord (4.0.0.rc1)
13
- activemodel (= 4.0.0.rc1)
14
- activerecord-deprecated_finders (~> 1.0.2)
15
- activesupport (= 4.0.0.rc1)
16
- arel (~> 4.0.0)
17
- activerecord-deprecated_finders (1.0.2)
18
- activesupport (4.0.0.rc1)
19
- i18n (~> 0.6, >= 0.6.4)
20
- minitest (~> 4.2)
21
- multi_json (~> 1.3)
22
- thread_safe (~> 0.1)
23
- tzinfo (~> 0.3.37)
24
- appraisal (0.5.2)
25
- bundler
26
- rake
27
- arel (4.0.0)
28
- atomic (1.1.9)
29
- builder (3.1.4)
30
- bump (0.4.1)
31
- diff-lcs (1.2.4)
32
- i18n (0.6.4)
33
- minitest (4.7.4)
34
- multi_json (1.7.3)
35
- rake (10.0.4)
36
- rspec (2.13.0)
37
- rspec-core (~> 2.13.0)
38
- rspec-expectations (~> 2.13.0)
39
- rspec-mocks (~> 2.13.0)
40
- rspec-core (2.13.1)
41
- rspec-expectations (2.13.0)
42
- diff-lcs (>= 1.1.3, < 2.0)
43
- rspec-mocks (2.13.1)
44
- sqlite3 (1.3.7)
45
- thread_safe (0.1.0)
46
- atomic
47
- tzinfo (0.3.37)
48
-
49
- PLATFORMS
50
- ruby
51
-
52
- DEPENDENCIES
53
- activerecord (~> 4.0.0.rc)
54
- appraisal
55
- bitfields!
56
- bump
57
- rake
58
- rspec (~> 2)
59
- sqlite3
@@ -1,450 +0,0 @@
1
- require 'spec_helper'
2
-
3
- class User < ActiveRecord::Base
4
- include Bitfields
5
- bitfield :bits, 1 => :seller, 2 => :insane, 4 => :stupid
6
- end
7
-
8
- class UserWithBitfieldOptions < ActiveRecord::Base
9
- include Bitfields
10
- bitfield :bits, 1 => :seller, 2 => :insane, 4 => :stupid, :scopes => false
11
- end
12
-
13
- class MultiBitUser < ActiveRecord::Base
14
- self.table_name = 'users'
15
- include Bitfields
16
- bitfield :bits, 1 => :seller, 2 => :insane, 4 => :stupid
17
- bitfield :more_bits, 1 => :one, 2 => :two, 4 => :four
18
- end
19
-
20
- class UserWithoutScopes < ActiveRecord::Base
21
- self.table_name = 'users'
22
- include Bitfields
23
- bitfield :bits, 1 => :seller, 2 => :insane, 4 => :stupid, :scopes => false
24
- end
25
-
26
- class UserWithoutSetBitfield < ActiveRecord::Base
27
- self.table_name = 'users'
28
- include Bitfields
29
- end
30
-
31
- class InheritedUser < User
32
- end
33
-
34
- class GrandchildInheritedUser < InheritedUser
35
- end
36
-
37
- # other children should not disturb the inheritance
38
- class OtherInheritedUser < UserWithoutSetBitfield
39
- self.table_name = 'users'
40
- bitfield :bits, 1 => :seller_inherited
41
- end
42
-
43
- class InheritedUserWithoutSetBitfield < UserWithoutSetBitfield
44
- end
45
-
46
- class OverwrittenUser < User
47
- bitfield :bits, 1 => :seller_inherited
48
- end
49
-
50
- class BitOperatorMode < ActiveRecord::Base
51
- self.table_name = 'users'
52
- include Bitfields
53
- bitfield :bits, 1 => :seller, 2 => :insane, :query_mode => :bit_operator
54
- end
55
-
56
- class WithoutThePowerOfTwo < ActiveRecord::Base
57
- self.table_name = 'users'
58
- include Bitfields
59
- bitfield :bits, :seller, :insane, :stupid, :query_mode => :bit_operator
60
- end
61
-
62
- class WithoutThePowerOfTwoWithoutOptions < ActiveRecord::Base
63
- self.table_name = 'users'
64
- include Bitfields
65
- bitfield :bits, :seller, :insane
66
- end
67
-
68
- class CheckRaise < ActiveRecord::Base
69
- self.table_name = 'users'
70
- include Bitfields
71
- end
72
-
73
- class ManyBitsUser < User
74
- self.table_name = 'users'
75
- end
76
-
77
- class InitializedUser < User
78
- self.table_name = 'users'
79
- bitfield :bits, 1 => :seller, 2 => :insane, 4 => :stupid, :scopes => false
80
-
81
- after_initialize do
82
- self.seller = true
83
- self.insane = false
84
- end
85
- end
86
-
87
- describe Bitfields do
88
- before do
89
- User.delete_all
90
- end
91
-
92
- def pending_if(condition, &block)
93
- if condition
94
- pending(&block)
95
- else
96
- yield
97
- end
98
- end
99
-
100
- describe :bitfields do
101
- it "parses them correctly" do
102
- User.bitfields.should == {:bits => {:seller => 1, :insane => 2, :stupid => 4}}
103
- end
104
-
105
- it "is fast for huge number of bits" do
106
- bits = {}
107
- 0.upto(20) do |bit|
108
- bits[2**bit] = "my_bit_#{bit}"
109
- end
110
-
111
- Timeout.timeout(0.2) do
112
- ManyBitsUser.class_eval{ bitfield :bits, bits }
113
- end
114
- end
115
- end
116
-
117
- describe :bitfield_options do
118
- it "parses them correctly when not set" do
119
- User.bitfield_options.should == {:bits => {}}
120
- end
121
-
122
- it "parses them correctly when set" do
123
- UserWithBitfieldOptions.bitfield_options.should == {:bits => {:scopes => false}}
124
- end
125
- end
126
-
127
- describe :bitfield_column do
128
- it "raises a nice error when i use a unknown bitfield" do
129
- lambda{
130
- User.bitfield_column(:xxx)
131
- }.should raise_error(RuntimeError, 'Unknown bitfield xxx')
132
- end
133
- end
134
-
135
- describe :bitfield_values do
136
- it "contains all bits with values" do
137
- User.new.bitfield_values(:bits).should == {:insane=>false, :stupid=>false, :seller=>false}
138
- User.new(:bits => 15).bitfield_values(:bits).should == {:insane=>true, :stupid=>true, :seller=>true}
139
- end
140
- end
141
-
142
- describe 'attribute accessors' do
143
- it "has everything on false by default" do
144
- User.new.seller.should == false
145
- User.new.seller?.should == false
146
- end
147
-
148
- it "is true when set to true" do
149
- User.new(:seller => true).seller.should == true
150
- end
151
-
152
- it "is true when set to truthy" do
153
- User.new(:seller => 1).seller.should == true
154
- end
155
-
156
- it "is false when set to false" do
157
- User.new(:seller => false).seller.should == false
158
- end
159
-
160
- it "is false when set to falsy" do
161
- User.new(:seller => 'false').seller.should == false
162
- end
163
-
164
- it "stays true when set to true twice" do
165
- u = User.new
166
- u.seller = true
167
- u.seller = true
168
- u.seller.should == true
169
- u.bits.should == 1
170
- end
171
-
172
- it "stays false when set to false twice" do
173
- u = User.new(:bits => 3)
174
- u.seller = false
175
- u.seller = false
176
- u.seller.should == false
177
- u.bits.should == 2
178
- end
179
-
180
- it "changes the bits when setting to false" do
181
- user = User.new(:bits => 7)
182
- user.seller = false
183
- user.bits.should == 6
184
- end
185
-
186
- it "does not get negative when unsetting high bits" do
187
- user = User.new(:seller => true)
188
- user.stupid = false
189
- user.bits.should == 1
190
- end
191
-
192
- it "changes the bits when setting to true" do
193
- user = User.new(:bits => 2)
194
- user.seller = true
195
- user.bits.should == 3
196
- end
197
-
198
- it "does not get too high when setting high bits" do
199
- user = User.new(:bits => 7)
200
- user.seller = true
201
- user.bits.should == 7
202
- end
203
-
204
- describe 'changes' do
205
- it "has no changes by defaut" do
206
- User.new.changes.should == {}
207
- end
208
-
209
- it "records a change when setting" do
210
- User.new(:seller => true).changes.should == {'seller' => [false, true], 'bits' => [0,1]}
211
- end
212
-
213
- it "records a change when unsetting" do
214
- u = User.create!(:seller => true)
215
- u.seller = false
216
- u.changes.should == {'seller' => [true, false], 'bits' => [1,0]}
217
- end
218
-
219
- it "does not track duplicate changes" do
220
- User.create!(:seller => false).changes.should == {}
221
- end
222
- end
223
- end
224
-
225
- describe :bitfield_sql do
226
- it "includes true states" do
227
- User.bitfield_sql({:insane => true}, :query_mode => :in_list).should == 'users.bits IN (2,3,6,7)' # 2, 1+2, 2+4, 1+2+4
228
- end
229
-
230
- it "includes invalid states" do
231
- User.bitfield_sql({:insane => false}, :query_mode => :in_list).should == 'users.bits IN (0,1,4,5)' # 0, 1, 4, 4+1
232
- end
233
-
234
- it "can combine multiple fields" do
235
- User.bitfield_sql({:seller => true, :insane => true}, :query_mode => :in_list).should == 'users.bits IN (3,7)' # 1+2, 1+2+4
236
- end
237
-
238
- it "can combine multiple fields with different values" do
239
- User.bitfield_sql({:seller => true, :insane => false}, :query_mode => :in_list).should == 'users.bits IN (1,5)' # 1, 1+4
240
- end
241
-
242
- it "combines multiple columns into one sql" do
243
- sql = MultiBitUser.bitfield_sql({:seller => true, :insane => false, :one => true, :four => true}, :query_mode => :in_list)
244
- sql.should == 'users.bits IN (1,5) AND users.more_bits IN (5,7)' # 1, 1+4 AND 1+4, 1+2+4
245
- end
246
-
247
- it "produces working sql" do
248
- u1 = MultiBitUser.create!(:seller => true, :one => true)
249
- u2 = MultiBitUser.create!(:seller => true, :one => false)
250
- u3 = MultiBitUser.create!(:seller => false, :one => false)
251
- conditions = MultiBitUser.bitfield_sql({:seller => true, :one => false}, :query_mode => :in_list)
252
- result = if Bitfields.ar_3?
253
- MultiBitUser.where(conditions)
254
- else
255
- MultiBitUser.all(:conditions => conditions)
256
- end
257
- result.should == [u2]
258
- end
259
-
260
- describe 'with bit operator mode' do
261
- it "generates bit-operator sql" do
262
- BitOperatorMode.bitfield_sql(:seller => true).should == '(users.bits & 1) = 1'
263
- end
264
-
265
- it "generates sql for each bit" do
266
- BitOperatorMode.bitfield_sql(:seller => true, :insane => false).should == '(users.bits & 3) = 1'
267
- end
268
-
269
- it "generates working sql" do
270
- u1 = BitOperatorMode.create!(:seller => true, :insane => true)
271
- u2 = BitOperatorMode.create!(:seller => true, :insane => false)
272
- u3 = BitOperatorMode.create!(:seller => false, :insane => false)
273
-
274
- conditions = MultiBitUser.bitfield_sql(:seller => true, :insane => false)
275
- result = if Bitfields.ar_3?
276
- BitOperatorMode.where(conditions)
277
- else
278
- BitOperatorMode.all(:conditions => conditions)
279
- end
280
- result.should == [u2]
281
- end
282
- end
283
-
284
- describe 'without the power of two' do
285
- it 'uses correct bits' do
286
- u = WithoutThePowerOfTwo.create!(:seller => false, :insane => true, :stupid => true)
287
- u.bits.should == 6
288
- end
289
-
290
- it 'has all fields' do
291
- u = WithoutThePowerOfTwo.create!(:seller => false, :insane => true)
292
- u.seller.should == false
293
- u.insane.should == true
294
- WithoutThePowerOfTwo.bitfield_options.should == {:bits=>{:query_mode=>:bit_operator}}
295
- end
296
-
297
- it "can e built without options" do
298
- u = WithoutThePowerOfTwoWithoutOptions.create!(:seller => false, :insane => true)
299
- u.seller.should == false
300
- u.insane.should == true
301
- WithoutThePowerOfTwoWithoutOptions.bitfield_options.should == {:bits=>{}}
302
- end
303
- end
304
-
305
- it "checks that bitfields are unique" do
306
- lambda{
307
- CheckRaise.class_eval do
308
- bitfield :foo, :bar, :baz, :bar
309
- end
310
- }.should raise_error(Bitfields::DuplicateBitNameError)
311
- end
312
- end
313
-
314
- describe :set_bitfield_sql do
315
- it "sets a single bit" do
316
- User.set_bitfield_sql(:seller => true).should == 'bits = (bits | 1) - 0'
317
- end
318
-
319
- it "unsets a single bit" do
320
- User.set_bitfield_sql(:seller => false).should == 'bits = (bits | 1) - 1'
321
- end
322
-
323
- it "sets multiple bits" do
324
- User.set_bitfield_sql(:seller => true, :insane => true).should == 'bits = (bits | 3) - 0'
325
- end
326
-
327
- it "unsets multiple bits" do
328
- User.set_bitfield_sql(:seller => false, :insane => false).should == 'bits = (bits | 3) - 3'
329
- end
330
-
331
- it "sets and unsets in one command" do
332
- User.set_bitfield_sql(:seller => false, :insane => true).should == 'bits = (bits | 3) - 1'
333
- end
334
-
335
- it "sets and unsets for multiple columns in one sql" do
336
- sql = MultiBitUser.set_bitfield_sql(:seller => false, :insane => true, :one => true, :two => false)
337
- sql.should == "bits = (bits | 3) - 1, more_bits = (more_bits | 3) - 2"
338
- end
339
-
340
- it "produces working sql" do
341
- u = MultiBitUser.create!(:seller => true, :insane => true, :stupid => false, :one => true, :two => false, :four => false)
342
- sql = MultiBitUser.set_bitfield_sql(:seller => false, :insane => true, :one => true, :two => false)
343
- MultiBitUser.update_all(sql)
344
- u.reload
345
- u.seller.should == false
346
- u.insane.should == true
347
- u.stupid.should == false
348
- u.one.should == true
349
- u.two.should == false
350
- u.four.should == false
351
- end
352
- end
353
-
354
- describe 'named scopes' do
355
- before do
356
- @u1 = User.create!(:seller => true, :insane => false)
357
- @u2 = User.create!(:seller => true, :insane => true)
358
- end
359
-
360
- it "creates them when nothing was passed" do
361
- User.respond_to?(:seller).should == true
362
- User.respond_to?(:not_seller).should == true
363
- end
364
-
365
- it "does not create them when false was passed" do
366
- UserWithoutScopes.respond_to?(:seller).should == false
367
- UserWithoutScopes.respond_to?(:not_seller).should == false
368
- end
369
-
370
- it "produces working positive scopes" do
371
- User.insane.seller.to_a.should == [@u2]
372
- end
373
-
374
- it "produces working negative scopes" do
375
- User.not_insane.seller.to_a.should == [@u1]
376
- end
377
- end
378
-
379
- describe 'overwriting' do
380
- it "does not change base class" do
381
- OverwrittenUser.bitfields[:bits][:seller_inherited].should_not == nil
382
- User.bitfields[:bits][:seller_inherited].should == nil
383
- end
384
-
385
- it "has inherited methods" do
386
- User.respond_to?(:seller).should == true
387
- OverwrittenUser.respond_to?(:seller).should == true
388
- end
389
- end
390
-
391
- describe 'inheritance' do
392
- it "knows overwritten values and normal" do
393
- User.bitfields.should == {:bits=>{:seller=>1, :insane=>2, :stupid=>4}}
394
- OverwrittenUser.bitfields.should == {:bits=>{:seller_inherited=>1}}
395
- end
396
-
397
- it "knows overwritten values when overwriting" do
398
- OverwrittenUser.bitfield_column(:seller_inherited).should == :bits
399
- end
400
-
401
- it "does not know old values when overwriting" do
402
- expect{
403
- OverwrittenUser.bitfield_column(:seller)
404
- }.to raise_error
405
- end
406
-
407
- it "knows inherited values without overwriting" do
408
- InheritedUser.bitfield_column(:seller).should == :bits
409
- end
410
-
411
- it "has inherited scopes" do
412
- InheritedUser.should respond_to(:not_seller)
413
- end
414
-
415
- it "has inherited methods" do
416
- InheritedUser.new.should respond_to(:seller?)
417
- end
418
-
419
- it "knows grandchild inherited values without overwriting" do
420
- GrandchildInheritedUser.bitfield_column(:seller).should == :bits
421
- end
422
-
423
- it "inherits no bitfields for a user without bitfields set" do
424
- InheritedUserWithoutSetBitfield.bitfields.should be_nil
425
- end
426
- end
427
-
428
- describe 'initializers' do
429
- it "sets defaults" do
430
- pending_if(ActiveRecord::VERSION::MAJOR == 2) do
431
- InitializedUser.new.seller.should == true
432
- InitializedUser.new.insane.should == false
433
- end
434
- end
435
-
436
- it "can overwrite defaults in new" do
437
- pending_if(ActiveRecord::VERSION::MAJOR != 2) do
438
- InitializedUser.new(:seller => false).seller.should == false
439
- InitializedUser.new(:insane => true).insane.should == true
440
- end
441
- end
442
- end
443
-
444
- describe "rspec matchers" do
445
- subject { User.new }
446
-
447
- it { should have_a_bitfield :seller }
448
- it { should_not have_a_bitfield :pickle_eater }
449
- end
450
- end
@@ -1,16 +0,0 @@
1
- require 'active_record'
2
-
3
- # connect
4
- ActiveRecord::Base.establish_connection(
5
- :adapter => "sqlite3",
6
- :database => ":memory:"
7
- )
8
-
9
- # create tables
10
- ActiveRecord::Schema.verbose = false
11
- ActiveRecord::Schema.define(:version => 1) do
12
- create_table :users do |t|
13
- t.integer :bits, :default => 0, :null => false
14
- t.integer :more_bits, :default => 0, :null => false
15
- end
16
- end
@@ -1,14 +0,0 @@
1
- require 'rubygems'
2
- if ENV['VERSION']
3
- gem 'activerecord', ENV['VERSION']
4
- gem 'activesupport', ENV['VERSION']
5
- end
6
- $LOAD_PATH << 'lib'
7
- require 'bitfields/rspec'
8
- require 'bitfields'
9
- require 'timeout'
10
-
11
- require 'active_record'
12
- puts "Using ActiveRecord #{ActiveRecord::VERSION::STRING}"
13
-
14
- require File.expand_path('../database', __FILE__)