extendi-cassandra_object 1.0.0

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 (104) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/.travis.yml +23 -0
  4. data/CHANGELOG +0 -0
  5. data/Gemfile +17 -0
  6. data/LICENSE +13 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +177 -0
  9. data/Rakefile +12 -0
  10. data/extendi-cassandra_object.gemspec +26 -0
  11. data/lib/cassandra_object.rb +73 -0
  12. data/lib/cassandra_object/adapters/abstract_adapter.rb +61 -0
  13. data/lib/cassandra_object/adapters/cassandra_adapter.rb +269 -0
  14. data/lib/cassandra_object/adapters/cassandra_schemaless_adapter.rb +306 -0
  15. data/lib/cassandra_object/attribute_methods.rb +96 -0
  16. data/lib/cassandra_object/attribute_methods/definition.rb +22 -0
  17. data/lib/cassandra_object/attribute_methods/dirty.rb +36 -0
  18. data/lib/cassandra_object/attribute_methods/primary_key.rb +25 -0
  19. data/lib/cassandra_object/attribute_methods/typecasting.rb +59 -0
  20. data/lib/cassandra_object/base.rb +33 -0
  21. data/lib/cassandra_object/base_schema.rb +11 -0
  22. data/lib/cassandra_object/base_schemaless.rb +11 -0
  23. data/lib/cassandra_object/base_schemaless_dynamic.rb +11 -0
  24. data/lib/cassandra_object/belongs_to.rb +63 -0
  25. data/lib/cassandra_object/belongs_to/association.rb +49 -0
  26. data/lib/cassandra_object/belongs_to/builder.rb +40 -0
  27. data/lib/cassandra_object/belongs_to/reflection.rb +30 -0
  28. data/lib/cassandra_object/callbacks.rb +29 -0
  29. data/lib/cassandra_object/core.rb +63 -0
  30. data/lib/cassandra_object/errors.rb +10 -0
  31. data/lib/cassandra_object/identity.rb +26 -0
  32. data/lib/cassandra_object/inspect.rb +25 -0
  33. data/lib/cassandra_object/log_subscriber.rb +44 -0
  34. data/lib/cassandra_object/model.rb +60 -0
  35. data/lib/cassandra_object/persistence.rb +203 -0
  36. data/lib/cassandra_object/railtie.rb +33 -0
  37. data/lib/cassandra_object/railties/controller_runtime.rb +45 -0
  38. data/lib/cassandra_object/schema.rb +83 -0
  39. data/lib/cassandra_object/schemaless.rb +83 -0
  40. data/lib/cassandra_object/scope.rb +86 -0
  41. data/lib/cassandra_object/scope/finder_methods.rb +54 -0
  42. data/lib/cassandra_object/scope/query_methods.rb +69 -0
  43. data/lib/cassandra_object/scoping.rb +27 -0
  44. data/lib/cassandra_object/serialization.rb +6 -0
  45. data/lib/cassandra_object/tasks/ks.rake +54 -0
  46. data/lib/cassandra_object/timestamps.rb +19 -0
  47. data/lib/cassandra_object/type.rb +16 -0
  48. data/lib/cassandra_object/types.rb +8 -0
  49. data/lib/cassandra_object/types/array_type.rb +16 -0
  50. data/lib/cassandra_object/types/base_type.rb +26 -0
  51. data/lib/cassandra_object/types/boolean_type.rb +20 -0
  52. data/lib/cassandra_object/types/date_type.rb +22 -0
  53. data/lib/cassandra_object/types/float_type.rb +16 -0
  54. data/lib/cassandra_object/types/integer_type.rb +20 -0
  55. data/lib/cassandra_object/types/json_type.rb +13 -0
  56. data/lib/cassandra_object/types/string_type.rb +19 -0
  57. data/lib/cassandra_object/types/time_type.rb +16 -0
  58. data/lib/cassandra_object/types/type_helper.rb +39 -0
  59. data/lib/cassandra_object/validations.rb +44 -0
  60. data/test/support/cassandra.rb +63 -0
  61. data/test/support/issue.rb +12 -0
  62. data/test/support/issue_dynamic.rb +12 -0
  63. data/test/support/issue_schema.rb +17 -0
  64. data/test/support/issue_schema_child.rb +17 -0
  65. data/test/support/issue_schema_father.rb +13 -0
  66. data/test/test_helper.rb +41 -0
  67. data/test/unit/active_model_test.rb +18 -0
  68. data/test/unit/adapters/adapter_test.rb +6 -0
  69. data/test/unit/attribute_methods/definition_test.rb +13 -0
  70. data/test/unit/attribute_methods/dirty_test.rb +72 -0
  71. data/test/unit/attribute_methods/primary_key_test.rb +26 -0
  72. data/test/unit/attribute_methods/typecasting_test.rb +119 -0
  73. data/test/unit/attribute_methods_test.rb +51 -0
  74. data/test/unit/base_test.rb +20 -0
  75. data/test/unit/belongs_to/reflection_test.rb +12 -0
  76. data/test/unit/belongs_to_test.rb +63 -0
  77. data/test/unit/callbacks_test.rb +46 -0
  78. data/test/unit/connection_test.rb +6 -0
  79. data/test/unit/connections/connections_test.rb +55 -0
  80. data/test/unit/core_test.rb +55 -0
  81. data/test/unit/identity_test.rb +26 -0
  82. data/test/unit/inspect_test.rb +26 -0
  83. data/test/unit/log_subscriber_test.rb +25 -0
  84. data/test/unit/persistence_schema_test.rb +156 -0
  85. data/test/unit/persistence_test.rb +266 -0
  86. data/test/unit/railties/controller_runtime_test.rb +48 -0
  87. data/test/unit/schema/tasks_test.rb +32 -0
  88. data/test/unit/schema_test.rb +115 -0
  89. data/test/unit/schemaless_test.rb +100 -0
  90. data/test/unit/scope/finder_methods_test.rb +117 -0
  91. data/test/unit/scope/query_methods_test.rb +32 -0
  92. data/test/unit/scoping_test.rb +7 -0
  93. data/test/unit/timestamps_test.rb +27 -0
  94. data/test/unit/types/array_type_test.rb +17 -0
  95. data/test/unit/types/base_type_test.rb +19 -0
  96. data/test/unit/types/boolean_type_test.rb +24 -0
  97. data/test/unit/types/date_type_test.rb +15 -0
  98. data/test/unit/types/float_type_test.rb +17 -0
  99. data/test/unit/types/integer_type_test.rb +19 -0
  100. data/test/unit/types/json_type_test.rb +23 -0
  101. data/test/unit/types/string_type_test.rb +25 -0
  102. data/test/unit/types/time_type_test.rb +14 -0
  103. data/test/unit/validations_test.rb +27 -0
  104. metadata +202 -0
@@ -0,0 +1,12 @@
1
+ class Issue < CassandraObject::BaseSchemaless
2
+ string :description
3
+ string :title
4
+
5
+ before_create { self.description ||= 'funny' }
6
+
7
+ self.allow_filtering = true
8
+
9
+ def self.for_key key
10
+ where_ids(key)
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ class IssueDynamic < CassandraObject::BaseSchemalessDynamic
2
+ string :description
3
+ string :title
4
+
5
+ before_create { self.description ||= 'funny' }
6
+
7
+ self.allow_filtering = true
8
+
9
+ def self.for_key key
10
+ where_ids(key)
11
+ end
12
+ end
@@ -0,0 +1,17 @@
1
+ class IssueSchema < CassandraObject::BaseSchema
2
+ string :id
3
+ string :description
4
+ string :title
5
+ float :field
6
+ integer :intero
7
+
8
+ before_create { self.description ||= 'funny' }
9
+
10
+ validates :title, presence: true
11
+
12
+ self.keys = '(id)'
13
+
14
+ def self.for_key key
15
+ where_ids(key)
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ class IssueSchemaChild < CassandraObject::BaseSchema
2
+ string :id
3
+ string :description
4
+ string :title
5
+ float :field
6
+
7
+ belongs_to :issue_schema_father
8
+ string :issue_schema_father_id
9
+
10
+ validates :title, presence: true
11
+
12
+ self.keys = '(id)'
13
+
14
+ def self.for_key key
15
+ where_ids(key)
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ class IssueSchemaFather < CassandraObject::BaseSchema
2
+ string :id
3
+ string :title
4
+ float :field
5
+
6
+ validates :title, presence: true
7
+
8
+ self.keys = '(id)'
9
+
10
+ def self.for_key key
11
+ where_ids(key)
12
+ end
13
+ end
@@ -0,0 +1,41 @@
1
+ require 'bundler/setup'
2
+ Bundler.require(:default, :test)
3
+
4
+ require 'rails/test_help'
5
+ require 'mocha/setup'
6
+
7
+ require 'cassandra_object'
8
+ require 'support/cassandra'
9
+ require 'support/issue'
10
+ require 'support/issue_dynamic'
11
+ require 'support/issue_schema'
12
+ require 'support/issue_schema_child'
13
+ require 'support/issue_schema_father'
14
+
15
+ module CassandraObject
16
+ class TestCase < ActiveSupport::TestCase
17
+
18
+ def temp_object(&block)
19
+ Class.new(CassandraObject::Base) do
20
+ self.column_family = 'Issues'
21
+ string :force_save
22
+ before_save { self.force_save = 'junk' }
23
+
24
+ def self.name
25
+ 'Issue'
26
+ end
27
+
28
+ instance_eval(&block) if block_given?
29
+ end
30
+ end
31
+ end
32
+
33
+ module Types
34
+ class TestCase < CassandraObject::TestCase
35
+ attr_accessor :coder
36
+ setup do
37
+ @coder = self.class.name.sub(/Test$/, '').constantize.new
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ require 'test_helper'
2
+
3
+ class ActiveModelTest < CassandraObject::TestCase
4
+
5
+ include ActiveModel::Lint::Tests
6
+
7
+ # overrides ActiveModel::Lint::Tests#test_to_param
8
+ def test_to_param
9
+ end
10
+
11
+ # overrides ActiveModel::Lint::Tests#test_to_key
12
+ def test_to_key
13
+ end
14
+
15
+ def setup
16
+ @model = Issue.new
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::Adapters::AdapterTest < CassandraObject::TestCase
4
+ test 'create_table' do
5
+ end
6
+ end
@@ -0,0 +1,13 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::AttributeMethods::DefinitionTest < CassandraObject::TestCase
4
+ class TestType < CassandraObject::Types::BaseType
5
+ end
6
+
7
+ test 'typecast' do
8
+ definition = CassandraObject::AttributeMethods::Definition.new(:foo, TestType, {a: :b})
9
+
10
+ assert_equal 'foo', definition.name
11
+ assert_kind_of TestType, definition.coder
12
+ end
13
+ end
@@ -0,0 +1,72 @@
1
+ # require 'test_helper'
2
+ #
3
+ # class CassandraObject::AttributeMethods::DirtyTest < CassandraObject::TestCase
4
+ # test 'save clears dirty' do
5
+ # record = temp_object do
6
+ # string :name
7
+ # end.new name: 'foo'
8
+ #
9
+ # assert record.changed?
10
+ #
11
+ # record.save!
12
+ #
13
+ # assert_equal [nil, 'foo'], record.previous_changes['name']
14
+ # assert !record.changed?
15
+ # end
16
+ #
17
+ # test 'reload clears dirty' do
18
+ # record = temp_object do
19
+ # string :name
20
+ # end.create! name: 'foo'
21
+ #
22
+ # record.name = 'bar'
23
+ # assert record.changed?
24
+ #
25
+ # record.reload
26
+ #
27
+ # assert !record.changed?
28
+ # end
29
+ #
30
+ # test 'typecast float before dirty check' do
31
+ # record = temp_object do
32
+ # float :price
33
+ # end.create(price: 5.01)
34
+ #
35
+ # record.price = '5.01'
36
+ # assert !record.changed?
37
+ #
38
+ # record.price = '7.12'
39
+ # assert record.changed?
40
+ # end
41
+ #
42
+ # test 'typecast boolean before dirty check' do
43
+ # record = temp_object do
44
+ # boolean :awesome
45
+ # end.create(awesome: false)
46
+ #
47
+ # record.awesome = false
48
+ # assert !record.changed?
49
+ #
50
+ # record.awesome = true
51
+ # assert record.changed?
52
+ # end
53
+ #
54
+ # test 'write_attribute' do
55
+ # object = temp_object do
56
+ # string :name
57
+ # end
58
+ #
59
+ # expected = {"name"=>[nil, "foo"]}
60
+ #
61
+ # object.new.tap do |record|
62
+ # record.name = 'foo'
63
+ # assert_equal expected, record.changes
64
+ # end
65
+ #
66
+ # object.new.tap do |record|
67
+ # record[:name] = 'foo'
68
+ # # record.write_attribute(:name, 'foo')
69
+ # assert_equal expected, record.changes
70
+ # end
71
+ # end
72
+ # end
@@ -0,0 +1,26 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::AttributeMethods::PrimaryKeyTest < CassandraObject::TestCase
4
+ test 'get id' do
5
+ model = temp_object do
6
+ key do
7
+ 'foo'
8
+ end
9
+ end
10
+ record = model.new
11
+
12
+ assert_equal 'foo', record.id
13
+ end
14
+
15
+ test 'set id' do
16
+ issue = Issue.new id: 'foo'
17
+
18
+ assert_equal 'foo', issue.id
19
+ end
20
+
21
+ test 'attributes' do
22
+ issue = Issue.new
23
+
24
+ assert_not_nil issue.attributes['id']
25
+ end
26
+ end
@@ -0,0 +1,119 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::AttributeMethods::TypecastingTest < CassandraObject::TestCase
4
+ class CustomType
5
+ end
6
+
7
+ class CustomCoder < CassandraObject::Types::BaseType
8
+ end
9
+
10
+ class TestIssue < CassandraObject::BaseSchemaless
11
+ self.column_family = 'Issues'
12
+
13
+ attribute :custom_column, type: CustomType, coder: CustomCoder
14
+ boolean :enabled
15
+ float :rating
16
+ integer :price
17
+ json :orders
18
+ string :name
19
+
20
+ end
21
+
22
+ class TestChildIssue < TestIssue
23
+ string :description
24
+ end
25
+
26
+ test 'attributes not shared' do
27
+ assert_nothing_raised { Issue.new.description }
28
+ assert_raise(NoMethodError) { TestIssue.new.description }
29
+ assert_nothing_raised { TestChildIssue.new.description }
30
+ end
31
+
32
+ test 'custom attribute definer' do
33
+ model_attribute = TestIssue.attribute_definitions['custom_column']
34
+
35
+ assert_kind_of CustomCoder, model_attribute.coder
36
+ assert_equal 'custom_column', model_attribute.name
37
+ end
38
+
39
+ test 'typecast_attribute' do
40
+ assert_equal 1, TestIssue.typecast_attribute(TestIssue.new, 'price', 1)
41
+ assert_equal 1, TestIssue.typecast_attribute(TestIssue.new, :price, 1)
42
+
43
+ assert_raise NoMethodError do
44
+ TestIssue.typecast_attribute(TestIssue.new, 'wtf', 1)
45
+ end
46
+ end
47
+
48
+ test 'boolean attribute' do
49
+ issue = TestIssue.create! enabled: '1'
50
+ assert_equal true, issue.enabled
51
+
52
+ issue = TestIssue.find issue.id
53
+ assert_equal true, issue.enabled
54
+ end
55
+
56
+ test 'float attribute' do
57
+ issue = TestIssue.create! rating: '4.5'
58
+ assert_equal 4.5, issue.rating
59
+
60
+ issue = TestIssue.find issue.id
61
+ assert_equal(4.5, issue.rating)
62
+ end
63
+
64
+ test 'integer attribute' do
65
+ issue = TestIssue.create! price: '101'
66
+ assert_equal 101, issue.price
67
+
68
+ issue = TestIssue.find issue.id
69
+ assert_equal(101, issue.price)
70
+
71
+ issue = TestIssue.new price: ''
72
+ assert_nil issue.price
73
+ end
74
+
75
+ test 'json attribute' do
76
+ issue = TestIssue.create! orders: {'a' => 'b'}
77
+ assert_equal({'a' => 'b'}, issue.orders)
78
+
79
+ issue = TestIssue.find issue.id
80
+ assert_equal({'a' => 'b'}, issue.orders)
81
+ end
82
+
83
+ test 'string attribute' do
84
+ issue = TestIssue.create! name: 'hola'
85
+ assert_equal('hola', issue.name)
86
+
87
+ issue = TestIssue.find issue.id
88
+ assert_equal('hola', issue.name)
89
+
90
+ issue = TestIssue.create! name: 42
91
+ assert_equal '42', issue.name
92
+ end
93
+
94
+ test 'multiple attributes definition' do
95
+ class MultipleAttributesIssue < CassandraObject::Base
96
+ self.column_family = 'Issues'
97
+ end
98
+
99
+ assert_nothing_raised {
100
+ MultipleAttributesIssue.string :hello, :greetings, :bye
101
+ }
102
+ issue = MultipleAttributesIssue.new :hello => 'hey', :greetings => 'how r u', :bye => 'see ya'
103
+
104
+ assert_equal 'how r u', issue.greetings
105
+ end
106
+
107
+ test 'multiple attributes with options' do
108
+ class MultipleAttributesIssue < CassandraObject::Base
109
+ self.column_family = 'Issues'
110
+ end
111
+
112
+ MultipleAttributesIssue.expects(:attribute).with(:hello, { :unique => :true, :type => :string })
113
+ MultipleAttributesIssue.expects(:attribute).with(:world, { :unique => :true, :type => :string })
114
+
115
+ class MultipleAttributesIssue < CassandraObject::Base
116
+ string :hello, :world, :unique => :true
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::AttributeMethodsTest < CassandraObject::TestCase
4
+ test 'read and write attributes' do
5
+ issue = Issue.new
6
+ assert_nil issue.read_attribute(:description)
7
+
8
+ issue.write_attribute(:description, nil)
9
+ assert_nil issue.read_attribute(:description)
10
+
11
+ issue.write_attribute(:description, 'foo')
12
+ assert_equal 'foo', issue.read_attribute(:description)
13
+ end
14
+
15
+ test 'hash accessor aliases' do
16
+ issue = Issue.new
17
+
18
+ issue[:description] = 'bar'
19
+
20
+ assert_equal 'bar', issue[:description]
21
+ end
22
+
23
+ test 'attributes setter' do
24
+ issue = Issue.new
25
+
26
+ issue.attributes = {
27
+ description: 'foo'
28
+ }
29
+
30
+ assert_equal 'foo', issue.description
31
+ end
32
+
33
+ class ChildIssue < Issue
34
+ def title=(val)
35
+ self[:title] = val + ' lol'
36
+ end
37
+ end
38
+
39
+ test 'override' do
40
+ issue = ChildIssue.new(title: 'hey')
41
+
42
+ assert_equal 'hey lol', issue.title
43
+ end
44
+
45
+ # test 'attribute_exists' do
46
+ # assert !Issue.new.attribute_exists?(:description)
47
+ # assert Issue.new(description: nil).attribute_exists?(:description)
48
+ # assert Issue.new(description: false).attribute_exists?(:description)
49
+ # assert Issue.new(description: 'hey').attribute_exists?(:description)
50
+ # end
51
+ end
@@ -0,0 +1,20 @@
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 CassandraObject::Base, CassandraObject::Base
12
+ assert_equal Son, Son.base_class
13
+ assert_equal Son, Grandson.base_class
14
+ end
15
+
16
+ test 'column family' do
17
+ assert_equal 'CassandraObject::BaseTest::Sons', Son.column_family
18
+ assert_equal 'CassandraObject::BaseTest::Sons', Grandson.column_family
19
+ end
20
+ end