sessionm-cassandra_object 2.2.6

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.
Files changed (83) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG +3 -0
  3. data/Gemfile +2 -0
  4. data/LICENSE +13 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.markdown +12 -0
  7. data/Rakefile +15 -0
  8. data/lib/cassandra_object/associations/one_to_many.rb +146 -0
  9. data/lib/cassandra_object/associations/one_to_one.rb +85 -0
  10. data/lib/cassandra_object/associations.rb +50 -0
  11. data/lib/cassandra_object/attributes.rb +97 -0
  12. data/lib/cassandra_object/base.rb +97 -0
  13. data/lib/cassandra_object/batches.rb +31 -0
  14. data/lib/cassandra_object/callbacks.rb +27 -0
  15. data/lib/cassandra_object/collection.rb +8 -0
  16. data/lib/cassandra_object/connection.rb +29 -0
  17. data/lib/cassandra_object/consistency.rb +31 -0
  18. data/lib/cassandra_object/cursor.rb +90 -0
  19. data/lib/cassandra_object/dirty.rb +32 -0
  20. data/lib/cassandra_object/errors.rb +10 -0
  21. data/lib/cassandra_object/finder_methods.rb +72 -0
  22. data/lib/cassandra_object/generators/migration_generator.rb +31 -0
  23. data/lib/cassandra_object/generators/templates/migration.rb.erb +11 -0
  24. data/lib/cassandra_object/identity/abstract_key_factory.rb +36 -0
  25. data/lib/cassandra_object/identity/custom_key_factory.rb +50 -0
  26. data/lib/cassandra_object/identity/hashed_natural_key_factory.rb +10 -0
  27. data/lib/cassandra_object/identity/key.rb +20 -0
  28. data/lib/cassandra_object/identity/natural_key_factory.rb +51 -0
  29. data/lib/cassandra_object/identity/uuid_key_factory.rb +39 -0
  30. data/lib/cassandra_object/identity.rb +52 -0
  31. data/lib/cassandra_object/log_subscriber.rb +37 -0
  32. data/lib/cassandra_object/migrations/migration.rb +15 -0
  33. data/lib/cassandra_object/migrations.rb +66 -0
  34. data/lib/cassandra_object/mocking.rb +15 -0
  35. data/lib/cassandra_object/persistence.rb +138 -0
  36. data/lib/cassandra_object/railtie.rb +11 -0
  37. data/lib/cassandra_object/schema/migration.rb +106 -0
  38. data/lib/cassandra_object/schema/migration_proxy.rb +25 -0
  39. data/lib/cassandra_object/schema/migrator.rb +213 -0
  40. data/lib/cassandra_object/schema.rb +37 -0
  41. data/lib/cassandra_object/serialization.rb +6 -0
  42. data/lib/cassandra_object/tasks/column_family.rb +90 -0
  43. data/lib/cassandra_object/tasks/keyspace.rb +89 -0
  44. data/lib/cassandra_object/tasks/ks.rake +121 -0
  45. data/lib/cassandra_object/timestamps.rb +19 -0
  46. data/lib/cassandra_object/type.rb +19 -0
  47. data/lib/cassandra_object/types/array_type.rb +16 -0
  48. data/lib/cassandra_object/types/boolean_type.rb +23 -0
  49. data/lib/cassandra_object/types/date_type.rb +20 -0
  50. data/lib/cassandra_object/types/float_type.rb +19 -0
  51. data/lib/cassandra_object/types/hash_type.rb +16 -0
  52. data/lib/cassandra_object/types/integer_type.rb +19 -0
  53. data/lib/cassandra_object/types/set_type.rb +22 -0
  54. data/lib/cassandra_object/types/string_type.rb +16 -0
  55. data/lib/cassandra_object/types/time_type.rb +27 -0
  56. data/lib/cassandra_object/types/time_with_zone_type.rb +18 -0
  57. data/lib/cassandra_object/types/utf8_string_type.rb +18 -0
  58. data/lib/cassandra_object/types.rb +11 -0
  59. data/lib/cassandra_object/validations.rb +46 -0
  60. data/lib/cassandra_object.rb +49 -0
  61. data/sessionm-cassandra_object.gemspec +26 -0
  62. data/test/active_model_test.rb +9 -0
  63. data/test/base_test.rb +28 -0
  64. data/test/batches_test.rb +30 -0
  65. data/test/connection_test.rb +28 -0
  66. data/test/consistency_test.rb +20 -0
  67. data/test/finder_methods_test.rb +49 -0
  68. data/test/identity_test.rb +30 -0
  69. data/test/persistence_test.rb +84 -0
  70. data/test/test_helper.rb +31 -0
  71. data/test/timestamps_test.rb +27 -0
  72. data/test/types/array_type_test.rb +15 -0
  73. data/test/types/boolean_type_test.rb +23 -0
  74. data/test/types/date_type_test.rb +4 -0
  75. data/test/types/float_type_test.rb +4 -0
  76. data/test/types/hash_type_test.rb +4 -0
  77. data/test/types/integer_type_test.rb +18 -0
  78. data/test/types/set_type_test.rb +17 -0
  79. data/test/types/string_type_test.rb +4 -0
  80. data/test/types/time_type_test.rb +4 -0
  81. data/test/types/utf8_string_type_test.rb +4 -0
  82. data/test/validations_test.rb +15 -0
  83. metadata +183 -0
@@ -0,0 +1,89 @@
1
+ module CassandraObject
2
+
3
+ module Tasks
4
+
5
+ class Keyspace
6
+
7
+ def self.parse(hash)
8
+ ks = Cassandra::Keyspace.new.with_fields hash
9
+ ks.cf_defs = []
10
+ hash['cf_defs'].each do |cf|
11
+ ks.cf_defs << Cassandra::ColumnFamily.new.with_fields(cf)
12
+ end
13
+ ks
14
+ end
15
+
16
+ def exists?(name)
17
+ connection.keyspaces.include? name.to_s
18
+ end
19
+
20
+ def create(name, options = {})
21
+ opts = { :name => name.to_s,
22
+ :strategy_class => 'org.apache.cassandra.locator.LocalStrategy',
23
+ :replication_factor => 1,
24
+ :cf_defs => [] }.merge(options)
25
+
26
+ ks = Cassandra::Keyspace.new.with_fields(opts)
27
+ connection.add_keyspace ks
28
+ end
29
+
30
+ def drop(name)
31
+ connection.drop_keyspace name.to_s
32
+ end
33
+
34
+ def set(name)
35
+ connection.keyspace = name.to_s
36
+ end
37
+
38
+ def get
39
+ connection.keyspace
40
+ end
41
+
42
+ def clear
43
+ return puts 'Cannot clear system keyspace' if connection.keyspace == 'system'
44
+
45
+ connection.clear_keyspace!
46
+ end
47
+
48
+ def schema_dump
49
+ connection.schema
50
+ end
51
+
52
+ def schema_load(schema)
53
+ connection.schema.cf_defs.each do |cf|
54
+ connection.drop_column_family cf.name
55
+ end
56
+
57
+ keyspace = get
58
+ schema.cf_defs.each do |cf|
59
+ cf.keyspace = keyspace
60
+ connection.add_column_family cf
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def connection
67
+ unless @connection
68
+ c = CassandraObject::Base.connection
69
+ @connection = Cassandra.new('system', c.servers, c.thrift_client_options)
70
+ end
71
+ @connection
72
+ end
73
+
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+
80
+ class Cassandra
81
+ class Keyspace
82
+ def with_fields(options)
83
+ struct_fields.collect { |f| f[1][:name] }.each do |f|
84
+ send("#{f}=", options[f.to_sym] || options[f.to_s])
85
+ end
86
+ self
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,121 @@
1
+ namespace :ks do
2
+ task :configure => :environment do
3
+ @configs = YAML.load_file(Rails.root.join("config", "cassandra.yml"))
4
+ @config = @configs[Rails.env || 'development']
5
+ end
6
+
7
+ #task :set_keyspace => :configure do
8
+ #set_keyspace
9
+ #end
10
+
11
+ desc 'Create the keyspace in config/cassandra.yml for the current environment'
12
+ task :create => :configure do
13
+ CassandraObject::Tasks::Keyspace.new.create @config['keyspace'], @config
14
+ puts "Created keyspace: #{@config['keyspace']}"
15
+ end
16
+
17
+ namespace :create do
18
+ desc 'Create keyspaces in config/cassandra.yml for all environments'
19
+ task :all => :configure do
20
+ created = []
21
+ @configs.values.each do |config|
22
+ CassandraObject::Tasks::Keyspace.new.create config['keyspace'], config
23
+ created << config['keyspace']
24
+ end
25
+ puts "Created keyspaces: #{created.join(', ')}"
26
+ end
27
+ end
28
+
29
+ desc 'Drop keyspace in config/cassandra.yml for the current environment'
30
+ task :drop => :configure do
31
+ CassandraObject::Tasks::Keyspace.new.drop @config['keyspace']
32
+ puts "Dropped keyspace: #{@config['keyspace']}"
33
+ end
34
+
35
+ namespace :drop do
36
+ desc 'Drop keyspaces in config/cassandra.yml for all environments'
37
+ task :all => :configure do
38
+ dropped = []
39
+ @configs.values.each do |config|
40
+ CassandraObject::Tasks::Keyspace.new.drop config['keyspace']
41
+ dropped << config['keyspace']
42
+ end
43
+ puts "Dropped keyspaces: #{dropped.join(', ')}"
44
+ end
45
+ end
46
+
47
+ desc 'Migrate the keyspace (options: VERSION=x)'
48
+ task :migrate => :configure do
49
+ version = ( ENV['VERSION'] ? ENV['VERSION'].to_i : nil )
50
+ CassandraObject::Schema::Migrator.migrate CassandraObject::Schema::Migrator.migrations_path, version
51
+ schema_dump
52
+ end
53
+
54
+ desc 'Rolls the schema back to the previous version (specify steps w/ STEP=n)'
55
+ task :rollback => :set_keyspace do
56
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
57
+ CassandraObject::Schema::Migrator.rollback CassandraObject::Schema::Migrator.migrations_path, step
58
+ schema_dump
59
+ end
60
+
61
+ desc 'Pushes the schema to the next version (specify steps w/ STEP=n)'
62
+ task :forward => :set_keyspace do
63
+ step = ENV['STEP'] ? ENV['STEP'].to_i : 1
64
+ CassandraObject::Schema::Migrator.forward CassandraObject::Schema::Migrator.migrations_path, step
65
+ schema_dump
66
+ end
67
+
68
+ namespace :schema do
69
+ desc 'Create ks/schema.json file that can be portably used against any Cassandra instance supported by CassandraObject'
70
+ task :dump => :configure do
71
+ schema_dump
72
+ end
73
+
74
+ desc 'Load ks/schema.json file into Cassandra'
75
+ task :load => :configure do
76
+ schema_load
77
+ end
78
+ end
79
+
80
+ namespace :test do
81
+ desc 'Load the development schema in to the test keyspace'
82
+ task :prepare => :configure do
83
+ schema_dump :development
84
+ schema_load :test
85
+ end
86
+ end
87
+
88
+ desc 'Retrieves the current schema version number'
89
+ task :version => :set_keyspace do
90
+ version = CassandraObject::Schema::Migrator.current_version
91
+ puts "Current version: #{version}"
92
+ end
93
+
94
+ private
95
+
96
+ def schema_dump(env = Rails.env)
97
+ ks = set_keyspace env
98
+ File.open "#{Rails.root}/ks/schema.json", 'w' do |file|
99
+ schema = ActiveSupport::JSON.decode(ks.schema_dump.to_json)
100
+ JSON.pretty_generate(schema).split(/\n/).each do |line|
101
+ file.puts line
102
+ end
103
+ end
104
+ end
105
+
106
+ def schema_load(env = Rails.env)
107
+ ks = set_keyspace env
108
+ File.open "#{Rails.root}/ks/schema.json", 'r' do |file|
109
+ hash = JSON.parse(file.read(nil))
110
+ ks.schema_load CassandraObject::Tasks::Keyspace.parse(hash)
111
+ end
112
+ end
113
+
114
+ def set_keyspace(env = Rails.env)
115
+ config = @configs[env.to_s || 'development']
116
+ ks = CassandraObject::Tasks::Keyspace.new
117
+ ks.set config['keyspace']
118
+ ks
119
+ end
120
+ end
121
+
@@ -0,0 +1,19 @@
1
+ module CassandraObject
2
+ module Timestamps
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attribute :created_at, type: :time#_with_zone
7
+ attribute :updated_at, type: :time#_with_zone
8
+
9
+ before_create do #|r|
10
+ self.created_at ||= Time.current
11
+ self.updated_at ||= Time.current
12
+ end
13
+
14
+ before_update if: :changed? do #|r|
15
+ self.updated_at = Time.current
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ module CassandraObject
2
+ class Type
3
+ class TypeMapping < Struct.new(:expected_type, :converter)
4
+ end
5
+
6
+ cattr_accessor :attribute_types
7
+ self.attribute_types = {}.with_indifferent_access
8
+
9
+ class << self
10
+ def register(name, expected_type, converter)
11
+ attribute_types[name] = TypeMapping.new(expected_type, converter)
12
+ end
13
+
14
+ def get_mapping(name)
15
+ attribute_types[name]
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module CassandraObject
2
+ module Types
3
+ module ArrayType
4
+ def encode(array)
5
+ raise ArgumentError.new("#{self} requires an Array") unless array.kind_of?(Array)
6
+ array.to_json
7
+ end
8
+ module_function :encode
9
+
10
+ def decode(str)
11
+ ActiveSupport::JSON.decode(str)
12
+ end
13
+ module_function :decode
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,23 @@
1
+ module CassandraObject
2
+ module Types
3
+ module BooleanType
4
+ TRUE_VALS = [true, 'true', '1']
5
+ FALSE_VALS = [false, 'false', '0', '', nil]
6
+ VALID_VALS = TRUE_VALS + FALSE_VALS
7
+
8
+ def encode(bool)
9
+ unless VALID_VALS.include?(bool)
10
+ raise ArgumentError.new("#{self} requires a boolean")
11
+ end
12
+ TRUE_VALS.include?(bool) ? '1' : '0'
13
+ end
14
+ module_function :encode
15
+
16
+ def decode(str)
17
+ raise ArgumentError.new("Cannot convert #{str} into a boolean") unless VALID_VALS.include?(str)
18
+ TRUE_VALS.include?(str)
19
+ end
20
+ module_function :decode
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module CassandraObject
2
+ module Types
3
+ module DateType
4
+ FORMAT = '%Y-%m-%d'
5
+ REGEX = /\A\d{4}-\d{2}-\d{2}\Z/
6
+ def encode(date)
7
+ raise ArgumentError.new("#{self} requires a Date") unless date.kind_of?(Date)
8
+ date.strftime(FORMAT)
9
+ end
10
+ module_function :encode
11
+
12
+ def decode(str)
13
+ return nil if str.empty?
14
+ raise ArgumentError.new("Cannot convert #{str} into a Date") unless str.kind_of?(String) && str.match(REGEX)
15
+ Date.strptime(str, FORMAT)
16
+ end
17
+ module_function :decode
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,19 @@
1
+ module CassandraObject
2
+ module Types
3
+ module FloatType
4
+ REGEX = /\A[-+]?\d+(\.\d+)?\Z/
5
+ def encode(float)
6
+ raise ArgumentError.new("#{self} requires a Float") unless float.kind_of?(Float)
7
+ float.to_s
8
+ end
9
+ module_function :encode
10
+
11
+ def decode(str)
12
+ return nil if str.empty?
13
+ raise ArgumentError.new("Cannot convert #{str} into a Float") unless str.kind_of?(String) && str.match(REGEX)
14
+ str.to_f
15
+ end
16
+ module_function :decode
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module CassandraObject
2
+ module Types
3
+ module HashType
4
+ def encode(hash)
5
+ raise ArgumentError.new("#{self} requires a Hash") unless hash.kind_of?(Hash)
6
+ ActiveSupport::JSON.encode(hash)
7
+ end
8
+ module_function :encode
9
+
10
+ def decode(str)
11
+ ActiveSupport::JSON.decode(str)
12
+ end
13
+ module_function :decode
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module CassandraObject
2
+ module Types
3
+ module IntegerType
4
+ REGEX = /\A[-+]?\d+\Z/
5
+ def encode(int)
6
+ raise ArgumentError.new("#{self} requires an Integer. You passed #{int.inspect}") unless int.kind_of?(Integer)
7
+ int.to_s
8
+ end
9
+ module_function :encode
10
+
11
+ def decode(str)
12
+ return nil if str.empty?
13
+ raise ArgumentError.new("Cannot convert #{str} into an Integer") unless str.kind_of?(String) && str.match(REGEX)
14
+ str.to_i
15
+ end
16
+ module_function :decode
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ module CassandraObject
2
+ module Types
3
+ module SetType
4
+ def encode(set)
5
+ if set.kind_of?(Set)
6
+ set.to_json
7
+ elsif set.kind_of?(Array)
8
+ set.uniq.to_json
9
+ else
10
+ raise ArgumentError.new("#{self} requires an Array or Set")
11
+ end
12
+ end
13
+ module_function :encode
14
+
15
+ def decode(str)
16
+ return str.to_a if str.kind_of?(Set)
17
+ ActiveSupport::JSON.decode(str)
18
+ end
19
+ module_function :decode
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,16 @@
1
+ module CassandraObject
2
+ module Types
3
+ module StringType
4
+ def encode(str)
5
+ raise ArgumentError.new("#{self} requires a String") unless str.kind_of?(String)
6
+ str.dup
7
+ end
8
+ module_function :encode
9
+
10
+ def decode(str)
11
+ str
12
+ end
13
+ module_function :decode
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,27 @@
1
+ module CassandraObject
2
+ module Types
3
+ module TimeType
4
+ # lifted from the implementation of Time.xmlschema and simplified
5
+ REGEX = /\A\s*
6
+ (-?\d+)-(\d\d)-(\d\d)
7
+ T
8
+ (\d\d):(\d\d):(\d\d)
9
+ (\.\d*)?
10
+ (Z|[+-]\d\d:\d\d)?
11
+ \s*\z/ix
12
+
13
+ def encode(time)
14
+ raise ArgumentError.new("#{self} requires a Time") unless time.kind_of?(Time)
15
+ time.xmlschema(6)
16
+ end
17
+ module_function :encode
18
+
19
+ def decode(str)
20
+ return nil if str.empty?
21
+ raise ArgumentError.new("Cannot convert #{str} into a Time") unless str.kind_of?(String) && str.match(REGEX)
22
+ Time.xmlschema(str)
23
+ end
24
+ module_function :decode
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ module CassandraObject
2
+ module Types
3
+ module TimeWithZoneType
4
+ def encode(time)
5
+ raise ArgumentError.new("#{self} requires a Time") unless time.kind_of?(Time)
6
+ time.utc.xmlschema(6)
7
+ end
8
+ module_function :encode
9
+
10
+ def decode(str)
11
+ return nil if str.empty?
12
+ raise ArgumentError.new("Cannot convert #{str} into a Time") unless str.kind_of?(String) && str.match(TimeType::REGEX)
13
+ Time.xmlschema(str).in_time_zone
14
+ end
15
+ module_function :decode
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module CassandraObject
2
+ module Types
3
+ module UTF8StringType
4
+ def encode(str)
5
+ # This is technically the most correct, but it is a pain to require utf-8 encoding for all strings. Should revisit.
6
+ #raise ArgumentError.new("#{self} requires a UTF-8 encoded String") unless str.kind_of?(String) && str.encoding == Encoding::UTF_8
7
+ raise ArgumentError.new("#{self} requires a String") unless str.kind_of?(String)
8
+ str.dup
9
+ end
10
+ module_function :encode
11
+
12
+ def decode(str)
13
+ str.force_encoding('UTF-8')
14
+ end
15
+ module_function :decode
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ CassandraObject::Type.register(:array, Array, CassandraObject::Types::ArrayType)
2
+ CassandraObject::Type.register(:boolean, Object, CassandraObject::Types::BooleanType)
3
+ CassandraObject::Type.register(:date, Date, CassandraObject::Types::DateType)
4
+ CassandraObject::Type.register(:float, Float, CassandraObject::Types::FloatType)
5
+ CassandraObject::Type.register(:hash, Hash, CassandraObject::Types::HashType)
6
+ CassandraObject::Type.register(:integer, Integer, CassandraObject::Types::IntegerType)
7
+ CassandraObject::Type.register(:set, Array, CassandraObject::Types::SetType)
8
+ CassandraObject::Type.register(:time, Time, CassandraObject::Types::TimeType)
9
+ CassandraObject::Type.register(:time_with_zone, ActiveSupport::TimeWithZone, CassandraObject::Types::TimeWithZoneType)
10
+ CassandraObject::Type.register(:string, String, CassandraObject::Types::UTF8StringType) #This could be changed to StringType to support non-utf8 strings
11
+ CassandraObject::Type.register(:utf8, String, CassandraObject::Types::UTF8StringType)
@@ -0,0 +1,46 @@
1
+ module CassandraObject
2
+ class RecordInvalid < StandardError
3
+ attr_reader :record
4
+ def initialize(record)
5
+ @record = record
6
+ super("Invalid record: #{@record.errors.full_messages.to_sentence}")
7
+ end
8
+ end
9
+
10
+ module Validations
11
+ extend ActiveSupport::Concern
12
+ include ActiveModel::Validations
13
+
14
+ included do
15
+ define_model_callbacks :validation
16
+ define_callbacks :validate, :scope => :name
17
+ end
18
+
19
+ module ClassMethods
20
+ def create!(attributes = {})
21
+ new(attributes).tap do |object|
22
+ object.save!
23
+ end
24
+ end
25
+ end
26
+
27
+ def valid?
28
+ run_callbacks :validation do
29
+ super
30
+ end
31
+ end
32
+
33
+ def save(options={})
34
+ perform_validations(options) ? super : false
35
+ end
36
+
37
+ def save!
38
+ save || raise(RecordInvalid.new(self))
39
+ end
40
+
41
+ protected
42
+ def perform_validations(options={})
43
+ (options[:validate] != false) ? valid? : true
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,49 @@
1
+ require 'rails/all'
2
+
3
+ module CassandraObject
4
+ extend ActiveSupport::Autoload
5
+
6
+ autoload :Base
7
+ autoload :Connection
8
+ autoload :Attributes
9
+ autoload :Dirty
10
+ autoload :Consistency
11
+ autoload :Persistence
12
+ autoload :Callbacks
13
+ autoload :Validations
14
+ autoload :Identity
15
+ autoload :Serialization
16
+ autoload :Associations
17
+ autoload :Migrations
18
+ autoload :Cursor
19
+ autoload :Collection
20
+ autoload :Mocking
21
+ autoload :Batches
22
+ autoload :FinderMethods
23
+ autoload :Timestamps
24
+ autoload :Type
25
+ autoload :Schema
26
+
27
+ module Tasks
28
+ extend ActiveSupport::Autoload
29
+ autoload :Keyspace
30
+ autoload :ColumnFamily
31
+ end
32
+
33
+ module Types
34
+ extend ActiveSupport::Autoload
35
+
36
+ autoload :ArrayType
37
+ autoload :BooleanType
38
+ autoload :DateType
39
+ autoload :FloatType
40
+ autoload :HashType
41
+ autoload :IntegerType
42
+ autoload :SetType
43
+ autoload :TimeType
44
+ autoload :TimeWithZoneType
45
+ autoload :UTF8StringType
46
+ end
47
+ end
48
+
49
+ require 'cassandra_object/railtie'
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'sessionm-cassandra_object'
5
+ s.version = '2.2.6'
6
+ s.description = 'Cassandra ActiveModel'
7
+ s.summary = 'Cassandra ActiveModel'
8
+
9
+ s.required_ruby_version = '>= 1.9.2'
10
+ s.required_rubygems_version = '>= 1.3.5'
11
+
12
+ s.authors = ["Michael Koziarski", "gotime", "sessionm"]
13
+ s.email = 'klange@sessionm.com'
14
+ s.homepage = 'http://github.com/sessionm/cassandra_object'
15
+
16
+ s.extra_rdoc_files = ["README.markdown"]
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.require_paths = ['lib']
20
+
21
+ s.add_runtime_dependency('rails', "~> 3.0")
22
+ s.add_runtime_dependency('cassandra', "~> 0.11.3")
23
+
24
+ s.add_development_dependency('bundler', "~> 1.0.0")
25
+ end
26
+
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveModelTest < CassandraObject::TestCase
4
+ include ActiveModel::Lint::Tests
5
+
6
+ def setup
7
+ @model = Issue.new
8
+ end
9
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::BaseTest < CassandraObject::TestCase
4
+ class Son < CassandraObject::Base
5
+ end
6
+
7
+ class Grandson < Son
8
+ end
9
+
10
+ test 'base_class' do
11
+ assert_equal Son, Son.base_class
12
+ assert_equal Son, Grandson.base_class
13
+ end
14
+
15
+ test 'column family' do
16
+ assert_equal 'CassandraObject::BaseTest::Sons', Son.column_family
17
+ end
18
+
19
+ test 'to_param' do
20
+ issue = Issue.create
21
+ assert_equal issue.id, issue.to_param
22
+ end
23
+
24
+ test 'hash' do
25
+ issue = Issue.create
26
+ assert_equal issue.id.hash, issue.hash
27
+ end
28
+ end
@@ -0,0 +1,30 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::BatchesTest < CassandraObject::TestCase
4
+ test 'find_each' do
5
+ Issue.create
6
+ Issue.create
7
+
8
+ issues = []
9
+ Issue.find_each do |issue|
10
+ issues << issue
11
+ end
12
+
13
+ assert_equal Issue.all.to_set, issues.to_set
14
+ end
15
+
16
+ test 'find_in_batches' do
17
+ Issue.create
18
+ Issue.create
19
+ Issue.create
20
+
21
+ issue_batches = []
22
+ Issue.find_in_batches(batch_size: 2) do |issues|
23
+ issue_batches << issues
24
+ end
25
+
26
+ assert_equal 2, issue_batches.size
27
+ assert issue_batches.any? { |issues| issues.size == 2 }
28
+ assert issue_batches.any? { |issues| issues.size == 1 }
29
+ end
30
+ end