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,266 @@
1
+ #!/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'test_helper'
5
+
6
+ class CassandraObject::PersistenceTest < CassandraObject::TestCase
7
+ test 'instantiate removes unknowns' do
8
+ assert_nil Issue.instantiate('theid', 'z' => 'nooo').attributes['z']
9
+ end
10
+
11
+ test 'encode_attributes' do
12
+ assert_equal(
13
+ {},
14
+ Issue.encode_attributes({})
15
+ )
16
+
17
+ assert_equal(
18
+ {'description' => nil},
19
+ Issue.encode_attributes({'description' => nil})
20
+ )
21
+
22
+ assert_equal(
23
+ {'description' => 'lol'},
24
+ Issue.encode_attributes({'description' => 'lol'})
25
+ )
26
+ end
27
+
28
+ test 'batch' do
29
+ first_issue = second_issue = nil
30
+
31
+ Issue.batch do
32
+ assert Issue.batching?
33
+
34
+ first_issue = Issue.create
35
+ second_issue = Issue.create
36
+ assert_raise(CassandraObject::RecordNotFound) { Issue.find(first_issue.id) }
37
+ assert_raise(CassandraObject::RecordNotFound) { Issue.find(second_issue.id) }
38
+ end
39
+
40
+ assert !Issue.batching?
41
+ assert_nothing_raised do
42
+ Issue.find(first_issue.id)
43
+ end
44
+ assert_nothing_raised do
45
+ Issue.find(second_issue.id)
46
+ end
47
+ end
48
+
49
+ test 'persistance inquiries' do
50
+ issue = Issue.new
51
+ assert issue.new_record?
52
+ assert !issue.persisted?
53
+
54
+ issue.save
55
+ assert issue.persisted?
56
+ assert !issue.new_record?
57
+ end
58
+
59
+ test 'create' do
60
+ issue = Issue.create { |i| i.description = 'foo' }
61
+ assert_equal 'foo', issue.description
62
+ assert_equal 'foo', Issue.find(issue.id).description
63
+ end
64
+
65
+ test 'read and write UTF' do
66
+ utf = "\ucba1\ucba2\ucba3 ƒ´∑ƒ©√åµ≈√ˆअनुच्छेद´µøµø¬≤ 汉语漢語".force_encoding(Encoding::UTF_8)
67
+
68
+ issue = Issue.create { |i| i.description = utf }
69
+ assert_equal utf, issue.description
70
+ reloaded = Issue.find(issue.id).description
71
+ assert_equal utf, reloaded
72
+ end
73
+
74
+ test 'save' do
75
+ issue = Issue.new
76
+ issue.save
77
+
78
+ assert_equal issue, Issue.find(issue.id)
79
+ end
80
+
81
+ test 'save!' do
82
+ begin
83
+ Issue.validates(:description, presence: true)
84
+
85
+ record = Issue.new(description: 'bad')
86
+ record.save!
87
+
88
+ assert_raise CassandraObject::RecordInvalid do
89
+ record = Issue.new
90
+ record.save!
91
+ end
92
+ ensure
93
+ Issue.reset_callbacks(:validate)
94
+ end
95
+
96
+ end
97
+
98
+ test 'destroy' do
99
+ issue = Issue.create
100
+ issue.destroy
101
+
102
+ assert issue.destroyed?
103
+ assert !issue.persisted?
104
+ assert !issue.new_record?
105
+ end
106
+
107
+ test 'update_attribute' do
108
+ issue = Issue.create
109
+ issue.update_attribute(:description, 'lol')
110
+
111
+ assert !issue.changed?
112
+ assert_equal 'lol', issue.description
113
+ end
114
+
115
+ test 'update_attributes' do
116
+ issue = Issue.create
117
+ issue.update_attributes(description: 'lol')
118
+
119
+ assert !issue.changed?
120
+ assert_equal 'lol', issue.description
121
+ end
122
+
123
+ test 'update_attributes!' do
124
+ begin
125
+ Issue.validates(:description, presence: true)
126
+
127
+ issue = Issue.new(description: 'bad')
128
+ issue.save!
129
+
130
+ assert_raise CassandraObject::RecordInvalid do
131
+ issue.update_attributes! description: ''
132
+ end
133
+ ensure
134
+ Issue.reset_callbacks(:validate)
135
+ end
136
+ end
137
+
138
+ test 'update nil attributes' do
139
+ issue = Issue.create(title: 'I rule', description: 'lololol')
140
+
141
+ issue.update_attributes title: nil
142
+
143
+ issue = Issue.find issue.id
144
+ assert_nil issue.title
145
+ end
146
+
147
+ test 'becomes' do
148
+ klass = temp_object do
149
+ end
150
+
151
+ assert_kind_of klass, Issue.new.becomes(klass)
152
+ end
153
+
154
+ test 'reload' do
155
+ persisted_issue = Issue.create
156
+ fresh_issue = Issue.find(persisted_issue.id)
157
+ fresh_issue.update_attribute(:description, 'say what')
158
+
159
+ reloaded_issue = persisted_issue.reload
160
+ assert_equal 'say what', persisted_issue.description
161
+ assert_equal persisted_issue, reloaded_issue
162
+ end
163
+
164
+ test 'allow CQL keyword in column name' do
165
+ assert_nothing_raised do
166
+ Issue.string :text
167
+ issue = Issue.create :text => 'hello'
168
+ issue.text = 'world'
169
+ issue.save!
170
+ issue.text = nil
171
+ issue.save!
172
+ end
173
+ end
174
+
175
+ test 'remove' do
176
+ record = Issue.new(title: 'cool')
177
+ record.save!
178
+
179
+ id = record.id
180
+ assert_equal id, Issue.find(id).id
181
+
182
+ Issue.remove(id)
183
+
184
+ assert_raise CassandraObject::RecordNotFound do
185
+ Issue.find(id)
186
+ end
187
+ end
188
+
189
+ test 'remove multiple' do
190
+ ids = []
191
+ (1..10).each do
192
+ record = Issue.create!(title: 'cool')
193
+ ids << record.id
194
+ end
195
+
196
+ Issue.remove(ids)
197
+
198
+ assert_equal [], Issue.find(ids)
199
+ end
200
+
201
+ test 'ttl' do
202
+ record = Issue.create({title: 'name', ttl: 1})
203
+ assert_nothing_raised do
204
+ Issue.find(record.id)
205
+ end
206
+
207
+ sleep 2
208
+
209
+ assert_raise CassandraObject::RecordNotFound do
210
+ Issue.find(record.id)
211
+ end
212
+ end
213
+
214
+ test 'dynamic create' do
215
+
216
+ id1 = "1"
217
+ IssueDynamic.create(key: id1, title: 'tit', dynamic_field1: 'one', dynamic_field2: 'two')
218
+ id2 = "2"
219
+ IssueDynamic.create(key: id2, title: 'tit2', dynamic_field1: '1', dynamic_field2: '2')
220
+ # number of dynamic fields
221
+
222
+ assert_equal 3, IssueDynamic.find(id1)[id1].size
223
+ end
224
+
225
+ test 'dynamic update' do
226
+
227
+ id = "123"
228
+ IssueDynamic.create(key: id, title: 'tit', dynamic_field1: 'one', dynamic_field2: 'two')
229
+ assert_equal 3, IssueDynamic.find(id)[id].size
230
+
231
+ IssueDynamic.update(id, {title: 'tit_new', dynamic_field1: 'new_one', dynamic_field2: nil})
232
+ assert_equal 2, IssueDynamic.find(id)[id].size
233
+
234
+ end
235
+
236
+ test 'dynamic delete' do
237
+ id = "123"
238
+ IssueDynamic.create(key: id, title: 'tit', dynamic_field1: 'one', dynamic_field2: 'two')
239
+ IssueDynamic.delete(id)
240
+ assert_raise CassandraObject::RecordNotFound do
241
+ IssueDynamic.find(id)
242
+ end
243
+ end
244
+
245
+ test 'dynamic delete attributes' do
246
+ id = "123"
247
+ IssueDynamic.create(key: id, title: 'tit', dynamic_field1: 'one', dynamic_field2: 'two')
248
+ IssueDynamic.delete(id, [:dynamic_field1])
249
+ assert_equal 2, IssueDynamic.find(id)[id].size
250
+ end
251
+
252
+ test 'paged_request_dynamic' do
253
+
254
+ NUMTEST = 21000
255
+ KEY = '987987'
256
+
257
+ NUMTEST.times.each do |i|
258
+ rand = rand()
259
+ IssueDynamic.create(key: KEY, rand => rand)
260
+ end
261
+ found = IssueDynamic.find_by_id(KEY)
262
+
263
+ assert_equal NUMTEST, found[KEY].size
264
+ end
265
+
266
+ end
@@ -0,0 +1,48 @@
1
+ require 'test_helper'
2
+ require 'cassandra_object/railties/controller_runtime'
3
+
4
+ class CassandraObject::Railties::ControllerRuntimeTest < MiniTest::Test
5
+ class TestRuntime
6
+ def self.log_process_action(payload)
7
+ ['sweet']
8
+ end
9
+
10
+ def cleanup_view_runtime
11
+ 12
12
+ end
13
+
14
+ def append_info_to_payload(payload)
15
+ payload[:foo] = 42
16
+ end
17
+ end
18
+
19
+ class CassandraRuntime < TestRuntime
20
+ include CassandraObject::Railties::ControllerRuntime
21
+ end
22
+
23
+ def test_cleanup_view_runtime
24
+ runtime = CassandraRuntime.new
25
+ CassandraObject::LogSubscriber.runtime = 10
26
+
27
+ runtime.cleanup_view_runtime
28
+
29
+ assert_equal 0, CassandraObject::LogSubscriber.runtime
30
+ end
31
+
32
+ def test_append_info_to_payload
33
+ runtime = CassandraRuntime.new
34
+ payload = {}
35
+ runtime.append_info_to_payload(payload)
36
+
37
+ assert_equal 42, payload[:foo]
38
+ assert payload.key?(:cassandra_object_runtime)
39
+ end
40
+
41
+ def test_log_process_action
42
+ payload = {cassandra_object_runtime: 12.3}
43
+ messages = CassandraRuntime.log_process_action(payload)
44
+
45
+ assert_equal 2, messages.size
46
+ assert_equal 'CassandraObject: 12.3ms', messages.last
47
+ end
48
+ end
@@ -0,0 +1,32 @@
1
+ =begin
2
+ require 'test_helper'
3
+
4
+ class CassandraObject::Schema::TasksTest < CassandraObject::TestCase
5
+ test "table_names" do
6
+ assert_equal ['Issues'], CassandraObject::Schema.table_names
7
+ end
8
+
9
+ test "dump" do
10
+ io = StringIO.new
11
+
12
+ CassandraObject::Schema.dump(io)
13
+ raise CassandraObject::Schema.dump(io).inspect
14
+ io.rewind
15
+
16
+ assert_match /Issues/, io.read
17
+ end
18
+
19
+ test "load" do
20
+ CassandraObject::Schema.expects(:keyspace_execute).with("DO STUFF;")
21
+ CassandraObject::Schema.expects(:keyspace_execute).with("AND MORE;")
22
+
23
+ CassandraObject::Schema.load StringIO.new(
24
+ "DO\n" +
25
+ " STUFF;\n" +
26
+ "\n" +
27
+ "AND\n" +
28
+ " MORE;\n"
29
+ )
30
+ end
31
+ end
32
+ =end
@@ -0,0 +1,115 @@
1
+ require 'test_helper'
2
+
3
+ class CassandraObject::SchemaTest < CassandraObject::TestCase
4
+
5
+ SCHEMA = {attributes: 'key text, text_field text, integer_field int ,float_field float, created_at timestamp, updated_at timestamp, PRIMARY KEY (key)'}
6
+
7
+ test 'create_keyspace' do
8
+ CassandraObject::Schema.create_keyspace 'Blah'
9
+ begin
10
+ existing_keyspace = false
11
+ CassandraObject::Schema.create_keyspace 'Blah'
12
+ rescue Exception => e
13
+ assert_equal e.message, 'Cannot add existing keyspace "blah"'
14
+ existing_keyspace = true
15
+ ensure
16
+ CassandraObject::Schema.drop_keyspace 'Blah'
17
+ end
18
+
19
+ assert existing_keyspace
20
+ end
21
+
22
+ test 'drop undroppable' do
23
+ begin
24
+ CassandraObject::Schema.drop_keyspace 'cassandra_object_test'
25
+ rescue Exception => e
26
+ assert_equal e.message, 'Cannot drop keyspace cassandra_object_test. You must delete all tables before'
27
+ ensure
28
+ end
29
+ end
30
+
31
+ test 'create_table' do
32
+ CassandraObject::Schema.create_table 'TestSchemaRecords', SCHEMA
33
+
34
+ begin
35
+ CassandraObject::Schema.create_table 'TestSchemaRecords', SCHEMA
36
+ assert false, 'TestSchemaRecords should already exist'
37
+ rescue Exception => e
38
+ assert_equal e.message.gsub('column family', 'table'), 'Cannot add already existing table "testschemarecords" to keyspace "cassandra_object_test"'
39
+ end
40
+ end
41
+
42
+ test 'drop_table' do
43
+ CassandraObject::Schema.create_table 'TestSchemaCFToDrop1', SCHEMA
44
+
45
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop1'
46
+
47
+ begin
48
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop1'
49
+ assert false, 'TestSchemaCFToDrop1 should not exist'
50
+ rescue Exception => e
51
+ assert_equal e.message.gsub('columnfamily', 'table'), 'unconfigured table testschemacftodrop1'
52
+ end
53
+ end
54
+
55
+ test 'test drop with record' do
56
+ class TestDrop < CassandraObject::BaseSchema
57
+ self.column_family = 'TestSchemaCFToDrop2'
58
+ end
59
+
60
+ CassandraObject::Schema.create_table 'TestSchemaCFToDrop2', SCHEMA
61
+ TestDrop.create
62
+
63
+ begin
64
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop2'
65
+ rescue Exception => e
66
+ assert_equal e.message, 'The table TestSchemaCFToDrop2 is not empty! If you want to drop it add the option confirm = true'
67
+ end
68
+ end
69
+
70
+ test 'test drop with confirm' do
71
+ CassandraObject::Schema.create_table 'TestSchemaCFToDrop3', SCHEMA
72
+
73
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop3', true
74
+ begin
75
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop3'
76
+ assert false, 'TestSchemaCFToDrop should not exist'
77
+ rescue Exception => e
78
+ assert_equal e.message.gsub('columnfamily', 'table'), 'unconfigured table testschemacftodrop3'
79
+ end
80
+ end
81
+
82
+ test 'test drop empty' do
83
+ CassandraObject::Schema.create_table 'TestSchemaCFToDrop4', SCHEMA
84
+ # drop empty
85
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop4'
86
+ begin
87
+ CassandraObject::Schema.drop_table 'TestSchemaCFToDrop4'
88
+ assert false, 'TestSchemaCFToDrop4 should not exist'
89
+ rescue Exception => e
90
+ assert_equal e.message.gsub('columnfamily', 'table'), 'unconfigured table testschemacftodrop4'
91
+ end
92
+ end
93
+
94
+ test 'create_index' do
95
+ CassandraObject::Schema.create_column_family 'TestSchemaIndexed', SCHEMA
96
+
97
+ CassandraObject::Schema.alter_column_family 'TestSchemaIndexed', 'ADD id_value varchar'
98
+
99
+ CassandraObject::Schema.add_index 'TestSchemaIndexed', 'id_value'
100
+ end
101
+
102
+ test 'drop_index' do
103
+ CassandraObject::Schema.create_column_family 'TestSchemaDropIndexes', SCHEMA
104
+
105
+ CassandraObject::Schema.alter_column_family 'TestSchemaDropIndexes', 'ADD id_value1 varchar'
106
+ CassandraObject::Schema.alter_column_family 'TestSchemaDropIndexes', 'ADD id_value2 varchar'
107
+
108
+ CassandraObject::Schema.add_index 'TestSchemaDropIndexes', 'id_value1'
109
+ CassandraObject::Schema.add_index 'TestSchemaDropIndexes', 'id_value2', 'special_name'
110
+
111
+ CassandraObject::Schema.drop_index 'TestSchemaDropIndexes_id_value1_idx'
112
+ CassandraObject::Schema.drop_index 'special_name'
113
+ end
114
+
115
+ end