bitfields 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +4 -0
- data/Gemfile +5 -7
- data/Gemfile.lock +6 -6
- data/Rakefile +22 -17
- data/Readme.md +12 -1
- data/bitfields.gemspec +9 -38
- data/lib/bitfields.rb +59 -31
- data/lib/bitfields/version.rb +3 -0
- data/spec/bitfields_spec.rb +67 -4
- data/spec/spec_helper.rb +1 -1
- metadata +28 -42
- data/VERSION +0 -1
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
bitfields (0.4.1)
|
5
|
+
|
1
6
|
GEM
|
2
7
|
remote: http://rubygems.org/
|
3
8
|
specs:
|
@@ -17,12 +22,7 @@ GEM
|
|
17
22
|
bcrypt-ruby (2.1.4)
|
18
23
|
builder (3.0.0)
|
19
24
|
diff-lcs (1.1.2)
|
20
|
-
git (1.2.5)
|
21
25
|
i18n (0.6.0)
|
22
|
-
jeweler (1.6.2)
|
23
|
-
bundler (~> 1.0)
|
24
|
-
git (>= 1.2.5)
|
25
|
-
rake
|
26
26
|
multi_json (1.0.3)
|
27
27
|
rake (0.9.2)
|
28
28
|
rspec (2.6.0)
|
@@ -41,7 +41,7 @@ PLATFORMS
|
|
41
41
|
|
42
42
|
DEPENDENCIES
|
43
43
|
activerecord
|
44
|
-
|
44
|
+
bitfields!
|
45
45
|
rake
|
46
46
|
rspec (~> 2)
|
47
47
|
sqlite3
|
data/Rakefile
CHANGED
@@ -1,24 +1,29 @@
|
|
1
|
-
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
|
3
|
+
task :spec do
|
2
4
|
sh "rspec spec"
|
3
5
|
end
|
4
6
|
|
5
|
-
task :
|
6
|
-
sh "AR=2.3.
|
7
|
-
sh "AR=3.0.
|
8
|
-
sh "AR=3.1.
|
7
|
+
task :default do
|
8
|
+
sh "AR=2.3.14 && (bundle check || bundle install) && bundle exec rake spec"
|
9
|
+
sh "AR=3.0.12 && (bundle check || bundle install) && bundle exec rake spec"
|
10
|
+
sh "AR=3.1.4 && (bundle check || bundle install) && bundle exec rake spec"
|
11
|
+
sh "AR=3.2.3 && (bundle check || bundle install) && bundle exec rake spec"
|
9
12
|
end
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
14
|
+
# extracted from https://github.com/grosser/project_template
|
15
|
+
rule /^version:bump:.*/ do |t|
|
16
|
+
sh "git status | grep 'nothing to commit'" # ensure we are not dirty
|
17
|
+
index = ['major', 'minor','patch'].index(t.name.split(':').last)
|
18
|
+
file = 'lib/bitfields/version.rb'
|
19
|
+
|
20
|
+
version_file = File.read(file)
|
21
|
+
old_version, *version_parts = version_file.match(/(\d+)\.(\d+)\.(\d+)/).to_a
|
22
|
+
version_parts[index] = version_parts[index].to_i + 1
|
23
|
+
version_parts[2] = 0 if index < 2 # remove patch for minor
|
24
|
+
version_parts[1] = 0 if index < 1 # remove minor for major
|
25
|
+
new_version = version_parts * '.'
|
26
|
+
File.open(file,'w'){|f| f.write(version_file.sub(old_version, new_version)) }
|
20
27
|
|
21
|
-
|
22
|
-
rescue LoadError
|
23
|
-
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
|
28
|
+
sh "bundle && git add #{file} Gemfile.lock && git commit -m 'bump version to #{new_version}'"
|
24
29
|
end
|
data/Readme.md
CHANGED
@@ -26,6 +26,7 @@ Or as Rails plugin: ` rails plugin install git://github.com/grosser/bitfields.gi
|
|
26
26
|
|
27
27
|
### Migration
|
28
28
|
ALWAYS set a default, bitfield queries will not work for NULL
|
29
|
+
|
29
30
|
t.integer :my_bits, :default => 0, :null => false
|
30
31
|
OR
|
31
32
|
add_column :users, :my_bits, :integer, :default => 0, :null => false
|
@@ -33,19 +34,27 @@ ALWAYS set a default, bitfield queries will not work for NULL
|
|
33
34
|
Examples
|
34
35
|
========
|
35
36
|
Update all users
|
37
|
+
|
36
38
|
User.seller.not_stupid.update_all(User.set_bitfield_sql(:seller => true, :insane => true))
|
37
39
|
|
38
40
|
Delete the shop when a user is no longer a seller
|
41
|
+
|
39
42
|
before_save :delete_shop, :if => lambda{|u| u.changes['seller'] == [true, false]}
|
40
43
|
|
41
44
|
TIPS
|
42
45
|
====
|
43
46
|
- [Upgrading] in version 0.2.2 the first field(when not given as hash) used bit 2 -> add a bogus field in first position
|
47
|
+
- [Defaults] afaik it is not possible to have some bits true by default (without monkeypatching AR/see [tests](https://github.com/grosser/bitfields/commit/2170dc546e2c4f1187089909a80e8602631d0796)) -> choose a good naming like `xxx_on` / `xxx_off` to use the default 'false'
|
44
48
|
- Never do: "#{bitfield_sql(...)} AND #{bitfield_sql(...)}", merge both into one hash
|
45
49
|
- bit_operator is faster in most cases, use :query_mode => :in_list sparingly
|
46
50
|
- Standard mysql integer is 4 byte -> 32 bitfields
|
47
51
|
- If you are lazy or bad at math you can also do `bitfields :bits, :foo, :bar, :baz`
|
48
52
|
|
53
|
+
Query-mode Benchmark
|
54
|
+
=========
|
55
|
+
The `:query_mode => :in_list` is slower for most queries and scales mierably with the number of bits.<br/>
|
56
|
+
*Stay with the default query-mode*. Only use :in_list if your edge-case shows better performance.
|
57
|
+
|
49
58
|
![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)
|
50
59
|
|
51
60
|
TODO
|
@@ -59,4 +68,6 @@ Authors
|
|
59
68
|
|
60
69
|
[Michael Grosser](http://grosser.it)<br/>
|
61
70
|
michael@grosser.it<br/>
|
62
|
-
|
71
|
+
License: MIT<br/>
|
72
|
+
[![Build Status](https://secure.travis-ci.org/grosser/bitfields.png)](http://travis-ci.org/grosser/bitfields)
|
73
|
+
|
data/bitfields.gemspec
CHANGED
@@ -1,41 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
#
|
4
|
-
# -*- encoding: utf-8 -*-
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
2
|
+
name = "bitfields"
|
3
|
+
require "#{name}/version"
|
5
4
|
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.
|
8
|
-
s.version = "0.4.0"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
5
|
+
Gem::Specification.new name, Bitfields::VERSION do |s|
|
6
|
+
s.summary = "Save migrations and columns by storing multiple booleans in a single integer"
|
11
7
|
s.authors = ["Michael Grosser"]
|
12
|
-
s.
|
13
|
-
s.
|
14
|
-
s.files =
|
15
|
-
|
16
|
-
"Gemfile.lock",
|
17
|
-
"Rakefile",
|
18
|
-
"Readme.md",
|
19
|
-
"VERSION",
|
20
|
-
"benchmark/bit_operator_vs_in.rb",
|
21
|
-
"bitfields.gemspec",
|
22
|
-
"lib/bitfields.rb",
|
23
|
-
"spec/bitfields_spec.rb",
|
24
|
-
"spec/database.rb",
|
25
|
-
"spec/spec_helper.rb"
|
26
|
-
]
|
27
|
-
s.homepage = %q{http://github.com/grosser/bitfields}
|
28
|
-
s.require_paths = ["lib"]
|
29
|
-
s.rubygems_version = %q{1.6.2}
|
30
|
-
s.summary = %q{Save migrations and columns by storing multiple booleans in a single integer.}
|
31
|
-
|
32
|
-
if s.respond_to? :specification_version then
|
33
|
-
s.specification_version = 3
|
34
|
-
|
35
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
36
|
-
else
|
37
|
-
end
|
38
|
-
else
|
39
|
-
end
|
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'
|
40
12
|
end
|
41
|
-
|
data/lib/bitfields.rb
CHANGED
@@ -1,15 +1,29 @@
|
|
1
|
+
require 'bitfields/version'
|
1
2
|
require 'active_support'
|
2
3
|
require 'active_support/version'
|
3
4
|
|
4
5
|
module Bitfields
|
5
|
-
VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
|
6
6
|
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'] # taken from ActiveRecord::ConnectionAdapters::Column
|
7
7
|
class DuplicateBitNameError < ArgumentError; end
|
8
8
|
|
9
9
|
def self.included(base)
|
10
10
|
class << base
|
11
|
-
attr_accessor :bitfields, :bitfield_options
|
11
|
+
attr_accessor :bitfields, :bitfield_options, :bitfield_args
|
12
|
+
|
13
|
+
# all the args passed into .bitfield so children can initialize from parents
|
14
|
+
def bitfield_args
|
15
|
+
@bitfield_args ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
def inherited(klass)
|
19
|
+
super
|
20
|
+
klass.bitfield_args = bitfield_args.dup
|
21
|
+
klass.bitfield_args.each do |column, options|
|
22
|
+
klass.send :store_bitfield_values, column, options.dup
|
23
|
+
end
|
24
|
+
end
|
12
25
|
end
|
26
|
+
|
13
27
|
base.extend Bitfields::ClassMethods
|
14
28
|
end
|
15
29
|
|
@@ -26,56 +40,70 @@ module Bitfields
|
|
26
40
|
|
27
41
|
# AR 3+ -> :scope, below :named_scope
|
28
42
|
def self.ar_scoping_method
|
29
|
-
|
30
|
-
|
43
|
+
if defined?(ActiveRecord::VERSION::MAJOR) and ActiveRecord::VERSION::MAJOR >= 3
|
44
|
+
:scope
|
45
|
+
else
|
46
|
+
:named_scope
|
47
|
+
end
|
31
48
|
end
|
32
49
|
|
33
50
|
module ClassMethods
|
34
51
|
def bitfield(column, *args)
|
35
|
-
# prepare ...
|
36
52
|
column = column.to_sym
|
37
|
-
options =
|
38
|
-
|
39
|
-
|
40
|
-
# extract options
|
41
|
-
self.bitfields ||= {}
|
42
|
-
self.bitfield_options ||= {}
|
43
|
-
bitfields[column] = Bitfields.extract_bits(options)
|
44
|
-
bitfield_options[column] = options
|
53
|
+
options = extract_bitfield_options args
|
54
|
+
bitfield_args << [column, options.dup]
|
45
55
|
|
46
|
-
|
47
|
-
|
48
|
-
define_method(bit_name){ bitfield_value(bit_name) }
|
49
|
-
define_method("#{bit_name}?"){ bitfield_value(bit_name) }
|
50
|
-
define_method("#{bit_name}="){|value| set_bitfield_value(bit_name, value) }
|
51
|
-
if options[:scopes] != false
|
52
|
-
scoping_method = Bitfields.ar_scoping_method
|
53
|
-
send scoping_method, bit_name, :conditions => bitfield_sql(bit_name => true)
|
54
|
-
send scoping_method, "not_#{bit_name}", :conditions => bitfield_sql(bit_name => false)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
include Bitfields::InstanceMethods
|
56
|
+
store_bitfield_values column, options
|
57
|
+
add_bitfield_methods column, options
|
59
58
|
end
|
60
59
|
|
61
60
|
def bitfield_column(bit_name)
|
62
|
-
found = bitfields.detect{|
|
61
|
+
found = bitfields.detect{|_, bits| bits.keys.include?(bit_name.to_sym) }
|
63
62
|
raise "Unknown bitfield #{bit_name}" unless found
|
64
63
|
found.first
|
65
64
|
end
|
66
65
|
|
67
66
|
def bitfield_sql(bit_values, options={})
|
68
|
-
bits = group_bits_by_column(bit_values).sort_by{|c,
|
67
|
+
bits = group_bits_by_column(bit_values).sort_by{|c,_| c.to_s }
|
69
68
|
bits.map{|column, bit_values| bitfield_sql_by_column(column, bit_values, options) } * ' AND '
|
70
69
|
end
|
71
70
|
|
72
71
|
def set_bitfield_sql(bit_values)
|
73
|
-
bits = group_bits_by_column(bit_values).sort_by{|c,
|
72
|
+
bits = group_bits_by_column(bit_values).sort_by{|c,_| c.to_s }
|
74
73
|
bits.map{|column, bit_values| set_bitfield_sql_by_column(column, bit_values) } * ', '
|
75
74
|
end
|
76
75
|
|
77
76
|
private
|
78
77
|
|
78
|
+
def extract_bitfield_options(args)
|
79
|
+
options = (args.last.is_a?(Hash) ? args.pop.dup : {})
|
80
|
+
args.each_with_index{|field,i| options[2**i] = field } # add fields given in normal args to options
|
81
|
+
options
|
82
|
+
end
|
83
|
+
|
84
|
+
def store_bitfield_values(column, options)
|
85
|
+
self.bitfields ||= {}
|
86
|
+
self.bitfield_options ||= {}
|
87
|
+
bitfields[column] = Bitfields.extract_bits(options)
|
88
|
+
bitfield_options[column] = options
|
89
|
+
end
|
90
|
+
|
91
|
+
def add_bitfield_methods(column, options)
|
92
|
+
bitfields[column].keys.each do |bit_name|
|
93
|
+
define_method(bit_name) { bitfield_value(bit_name) }
|
94
|
+
define_method("#{bit_name}?") { bitfield_value(bit_name) }
|
95
|
+
define_method("#{bit_name}=") { |value| set_bitfield_value(bit_name, value) }
|
96
|
+
|
97
|
+
if options[:scopes] != false
|
98
|
+
scoping_method = Bitfields.ar_scoping_method
|
99
|
+
send scoping_method, bit_name, :conditions => bitfield_sql(bit_name => true)
|
100
|
+
send scoping_method, "not_#{bit_name}", :conditions => bitfield_sql(bit_name => false)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
include Bitfields::InstanceMethods
|
105
|
+
end
|
106
|
+
|
79
107
|
def bitfield_sql_by_column(column, bit_values, options={})
|
80
108
|
mode = options[:query_mode] || (bitfield_options[column][:query_mode] || :bit_operator)
|
81
109
|
case mode
|
@@ -122,13 +150,13 @@ module Bitfields
|
|
122
150
|
|
123
151
|
module InstanceMethods
|
124
152
|
def bitfield_values(column)
|
125
|
-
Hash[self.class.bitfields[column.to_sym].map{|bit_name,
|
153
|
+
Hash[self.class.bitfields[column.to_sym].map{|bit_name, _| [bit_name, bitfield_value(bit_name)]}]
|
126
154
|
end
|
127
155
|
|
128
156
|
private
|
129
157
|
|
130
158
|
def bitfield_value(bit_name)
|
131
|
-
|
159
|
+
_, bit, current_value = bitfield_info(bit_name)
|
132
160
|
current_value & bit != 0
|
133
161
|
end
|
134
162
|
|
data/spec/bitfields_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
class User < ActiveRecord::Base
|
4
4
|
include Bitfields
|
@@ -23,9 +23,26 @@ class UserWithoutScopes < ActiveRecord::Base
|
|
23
23
|
bitfield :bits, 1 => :seller, 2 => :insane, 4 => :stupid, :scopes => false
|
24
24
|
end
|
25
25
|
|
26
|
+
class UserWithoutSetBitfield < ActiveRecord::Base
|
27
|
+
set_table_name 'users'
|
28
|
+
include Bitfields
|
29
|
+
end
|
30
|
+
|
26
31
|
class InheritedUser < User
|
27
32
|
end
|
28
33
|
|
34
|
+
class GrandchildInheritedUser < InheritedUser
|
35
|
+
end
|
36
|
+
|
37
|
+
# other children should not disturb the inheritance
|
38
|
+
class OtherInheritedUser < UserWithoutSetBitfield
|
39
|
+
set_table_name 'users'
|
40
|
+
bitfield :bits, 1 => :seller_inherited
|
41
|
+
end
|
42
|
+
|
43
|
+
class InheritedUserWithoutSetBitfield < UserWithoutSetBitfield
|
44
|
+
end
|
45
|
+
|
29
46
|
class OverwrittenUser < User
|
30
47
|
bitfield :bits, 1 => :seller_inherited
|
31
48
|
end
|
@@ -57,6 +74,16 @@ class ManyBitsUser < User
|
|
57
74
|
set_table_name 'users'
|
58
75
|
end
|
59
76
|
|
77
|
+
class InitializedUser < User
|
78
|
+
set_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
|
+
|
60
87
|
describe Bitfields do
|
61
88
|
before do
|
62
89
|
User.delete_all
|
@@ -346,12 +373,48 @@ describe Bitfields do
|
|
346
373
|
OverwrittenUser.bitfields.should == {:bits=>{:seller_inherited=>1}}
|
347
374
|
end
|
348
375
|
|
349
|
-
|
350
|
-
OverwrittenUser.bitfield_column(:
|
376
|
+
it "knows overwritten values when overwriting" do
|
377
|
+
OverwrittenUser.bitfield_column(:seller_inherited).should == :bits
|
351
378
|
end
|
352
379
|
|
353
|
-
|
380
|
+
it "does not know old values when overwriting" do
|
381
|
+
expect{
|
382
|
+
OverwrittenUser.bitfield_column(:seller)
|
383
|
+
}.to raise_error
|
384
|
+
end
|
385
|
+
|
386
|
+
it "knows inherited values without overwriting" do
|
354
387
|
InheritedUser.bitfield_column(:seller).should == :bits
|
355
388
|
end
|
389
|
+
|
390
|
+
it "has inherited scopes" do
|
391
|
+
InheritedUser.should respond_to(:not_seller)
|
392
|
+
end
|
393
|
+
|
394
|
+
it "has inherited methods" do
|
395
|
+
InheritedUser.new.should respond_to(:seller?)
|
396
|
+
end
|
397
|
+
|
398
|
+
it "knows grandchild inherited values without overwriting" do
|
399
|
+
GrandchildInheritedUser.bitfield_column(:seller).should == :bits
|
400
|
+
end
|
401
|
+
|
402
|
+
it "inherits no bitfields for a user without bitfields set" do
|
403
|
+
InheritedUserWithoutSetBitfield.bitfields.should be_nil
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
describe 'initializers' do
|
408
|
+
it "sets defaults" do
|
409
|
+
InitializedUser.new.seller.should == true
|
410
|
+
InitializedUser.new.insane.should == false
|
411
|
+
end
|
412
|
+
|
413
|
+
it "can overwrite defaults in new" do
|
414
|
+
pending do
|
415
|
+
InitializedUser.new(:seller => false).seller.should == false
|
416
|
+
InitializedUser.new(:insane => true).insane.should == true
|
417
|
+
end
|
418
|
+
end
|
356
419
|
end
|
357
420
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,77 +1,63 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitfields
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.4.1
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 4
|
9
|
-
- 0
|
10
|
-
version: 0.4.0
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Michael Grosser
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
date: 2011-06-21 00:00:00 +02:00
|
19
|
-
default_executable:
|
12
|
+
date: 2012-05-26 00:00:00.000000000 Z
|
20
13
|
dependencies: []
|
21
|
-
|
22
14
|
description:
|
23
|
-
email:
|
15
|
+
email: michael@grosser.it
|
24
16
|
executables: []
|
25
|
-
|
26
17
|
extensions: []
|
27
|
-
|
28
18
|
extra_rdoc_files: []
|
29
|
-
|
30
|
-
|
19
|
+
files:
|
20
|
+
- .travis.yml
|
31
21
|
- Gemfile
|
32
22
|
- Gemfile.lock
|
33
23
|
- Rakefile
|
34
24
|
- Readme.md
|
35
|
-
- VERSION
|
36
25
|
- benchmark/bit_operator_vs_in.rb
|
37
26
|
- bitfields.gemspec
|
38
27
|
- lib/bitfields.rb
|
28
|
+
- lib/bitfields/version.rb
|
39
29
|
- spec/bitfields_spec.rb
|
40
30
|
- spec/database.rb
|
41
31
|
- spec/spec_helper.rb
|
42
|
-
has_rdoc: true
|
43
32
|
homepage: http://github.com/grosser/bitfields
|
44
|
-
licenses:
|
45
|
-
|
33
|
+
licenses:
|
34
|
+
- MIT
|
46
35
|
post_install_message:
|
47
36
|
rdoc_options: []
|
48
|
-
|
49
|
-
require_paths:
|
37
|
+
require_paths:
|
50
38
|
- lib
|
51
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
40
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
|
57
|
-
segments:
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
segments:
|
58
46
|
- 0
|
59
|
-
|
60
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
47
|
+
hash: 4196443429503694670
|
48
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
49
|
none: false
|
62
|
-
requirements:
|
63
|
-
- -
|
64
|
-
- !ruby/object:Gem::Version
|
65
|
-
|
66
|
-
segments:
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
segments:
|
67
55
|
- 0
|
68
|
-
|
56
|
+
hash: 4196443429503694670
|
69
57
|
requirements: []
|
70
|
-
|
71
58
|
rubyforge_project:
|
72
|
-
rubygems_version: 1.
|
59
|
+
rubygems_version: 1.8.24
|
73
60
|
signing_key:
|
74
61
|
specification_version: 3
|
75
|
-
summary: Save migrations and columns by storing multiple booleans in a single integer
|
62
|
+
summary: Save migrations and columns by storing multiple booleans in a single integer
|
76
63
|
test_files: []
|
77
|
-
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.4.0
|