extendi-cassandra_object 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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