cassandra_store 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,79 @@
1
+ require File.expand_path("../spec_helper", __dir__)
2
+
3
+ RSpec.describe CassandraStore::Migration do
4
+ let(:path) { File.expand_path("../fixtures", __dir__) }
5
+
6
+ describe ".up" do
7
+ let(:version) { "1589957812" }
8
+
9
+ before { CassandraStore::SchemaMigration.create_table(if_not_exists: true) }
10
+
11
+ it "calls the up migration" do
12
+ migration = double(up: true)
13
+
14
+ allow(described_class.migration_class(path, version)).to receive(:new).and_return(migration)
15
+
16
+ described_class.up(path, version)
17
+
18
+ expect(migration).to have_received(:up)
19
+ end
20
+ end
21
+
22
+ describe ".down" do
23
+ let(:version) { "1589957812" }
24
+
25
+ before { CassandraStore::SchemaMigration.create_table(if_not_exists: true) }
26
+
27
+ it "calls the down migration" do
28
+ migration = double(down: true)
29
+
30
+ allow(described_class.migration_class(path, version)).to receive(:new).and_return(migration)
31
+
32
+ described_class.down(path, version)
33
+
34
+ expect(migration).to have_received(:down)
35
+ end
36
+ end
37
+
38
+ describe ".execute" do
39
+ it "delegates to CassandraStore::Base.execute" do
40
+ allow(CassandraStore::Base).to receive(:execute)
41
+
42
+ described_class.new.execute("args")
43
+
44
+ expect(CassandraStore::Base).to have_received(:execute).with("args")
45
+ end
46
+ end
47
+
48
+ describe ".migrate" do
49
+ before { CassandraStore::SchemaMigration.create_table(if_not_exists: true) }
50
+
51
+ it "runs all pending migrations" do
52
+ migration1 = double(up: true)
53
+ migration2 = double(up: true)
54
+
55
+ allow(described_class.migration_class(path, "1589957812")).to receive(:new).and_return(migration1)
56
+ allow(described_class.migration_class(path, "1589957813")).to receive(:new).and_return(migration2)
57
+
58
+ described_class.migrate(path)
59
+
60
+ expect(migration1).to have_received(:up)
61
+ expect(migration2).to have_received(:up)
62
+ end
63
+
64
+ it "does not run already executed migrations" do
65
+ described_class.up(path, "1589957812")
66
+
67
+ migration1 = double(up: true)
68
+ migration2 = double(up: true)
69
+
70
+ allow(described_class.migration_class(path, "1589957812")).to receive(:new).and_return(migration1)
71
+ allow(described_class.migration_class(path, "1589957813")).to receive(:new).and_return(migration2)
72
+
73
+ described_class.migrate(path)
74
+
75
+ expect(migration1).not_to have_received(:up)
76
+ expect(migration2).to have_received(:up)
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,222 @@
1
+ require File.expand_path("../spec_helper", __dir__)
2
+
3
+ RSpec.describe CassandraStore::Relation do
4
+ describe "#all" do
5
+ it "returns all records" do
6
+ post1 = Post.create!(user: "user", domain: "domain", message: "message1")
7
+ post2 = Post.create!(user: "user", domain: "domain", message: "message2")
8
+
9
+ expect(Post.all.to_a.to_set).to eq([post1, post2].to_set)
10
+ end
11
+ end
12
+
13
+ describe "#update_all" do
14
+ it "allows to update records via a cql string" do
15
+ post1 = Post.create!(user: "user1", domain: "domain1", message: "message1")
16
+ post2 = Post.create!(user: "user2", domain: "domain2", message: "message2")
17
+
18
+ Post.where(user: "user1", domain: "domain1", id: post1.id).update_all("message = 'new message'")
19
+
20
+ post1 = Post.where(user: "user1", domain: "domain1", id: post1.id).first
21
+ post2 = Post.where(user: "user2", domain: "domain2", id: post2.id).first
22
+
23
+ expect(post1.message).to eq("new message")
24
+ expect(post2.message).to eq("message2")
25
+ end
26
+
27
+ it "allows to update records via a hash" do
28
+ post1 = Post.create!(user: "user1", domain: "domain1", message: "message1")
29
+ post2 = Post.create!(user: "user2", domain: "domain2", message: "message2")
30
+
31
+ Post.where(user: "user1", domain: "domain1", id: post1.id).update_all(message: "new message")
32
+
33
+ post1 = Post.where(user: "user1", domain: "domain1", id: post1.id).first
34
+ post2 = Post.where(user: "user2", domain: "domain2", id: post2.id).first
35
+
36
+ expect(post1.message).to eq("new message")
37
+ expect(post2.message).to eq("message2")
38
+ end
39
+ end
40
+
41
+ describe "#where" do
42
+ it "is chainable" do
43
+ post1 = Post.create!(user: "user", domain: "domain1", message: "message1")
44
+ post2 = Post.create!(user: "user", domain: "domain1", message: "message2")
45
+ _post3 = Post.create!(user: "user", domain: "domain2", message: "message1")
46
+
47
+ posts = Post.where(user: "user").where(domain: "domain1").to_a
48
+
49
+ expect(posts.to_a.to_set).to eq([post1, post2].to_set)
50
+ end
51
+
52
+ it "allows to pass multiple hash arguments" do
53
+ post1 = Post.create!(user: "user", domain: "domain1", message: "message1")
54
+ post2 = Post.create!(user: "user", domain: "domain1", message: "message2")
55
+ _post3 = Post.create!(user: "user", domain: "domain2", message: "message1")
56
+
57
+ posts = Post.where(user: "user", domain: "domain1").to_a
58
+
59
+ expect(posts.to_a.to_set).to eq([post1, post2].to_set)
60
+ end
61
+
62
+ it "allows to pass an array as constraint" do
63
+ post1 = Post.create!(user: "user", domain: "domain1")
64
+ post2 = Post.create!(user: "user", domain: "domain2")
65
+ _post3 = Post.create!(user: "user", domain: "domain3")
66
+
67
+ posts = Post.where(user: "user").where(domain: ["domain1", "domain2"]).to_a
68
+
69
+ expect(posts.to_a.to_set).to eq([post1, post2].to_set)
70
+ end
71
+
72
+ it "allows to pass a range as constraint" do
73
+ post1 = Post.create!(user: "user", domain: "domain1")
74
+ post2 = Post.create!(user: "user", domain: "domain2")
75
+ _post3 = Post.create!(user: "user", domain: "domain3")
76
+
77
+ expect(Post.where(user: "user").where(domain: "domain1".."domain2").to_a.to_set).to eq([post1, post2].to_set)
78
+ end
79
+
80
+ it "allows to pass an arbitrary cql string" do
81
+ post1 = Post.create!(user: "user", domain: "domain1", message: "message1")
82
+ post2 = Post.create!(user: "user", domain: "domain1", message: "message2")
83
+ _post3 = Post.create!(user: "user", domain: "domain2", message: "message1")
84
+
85
+ expect(Post.where_cql("user = 'user'").where_cql("domain = :domain", domain: "domain1").to_a.to_set).to eq([post1, post2].to_set)
86
+ end
87
+ end
88
+
89
+ describe "#order" do
90
+ it "sorts the records by the specified criteria" do
91
+ post1 = Post.create!(user: "user", domain: "domain", timestamp: Time.now)
92
+ post2 = Post.create!(user: "user", domain: "domain", timestamp: Time.now + 1.day)
93
+ post3 = Post.create!(user: "user", domain: "domain", timestamp: Time.now + 2.days)
94
+
95
+ expect(Post.where(user: "user", domain: "domain").order(id: :asc).to_a).to eq([post1, post2, post3])
96
+ expect(Post.where(user: "user", domain: "domain").order(id: :desc).to_a).to eq([post3, post2, post1])
97
+ end
98
+ end
99
+
100
+ describe "#limit" do
101
+ it "limits the records returned" do
102
+ Post.create!(user: "user", domain: "domain", timestamp: Time.now)
103
+ Post.create!(user: "user", domain: "domain", timestamp: Time.now)
104
+ Post.create!(user: "user", domain: "domain", timestamp: Time.now)
105
+ Post.create!(user: "user", domain: "domain", timestamp: Time.now)
106
+
107
+ expect(Post.limit(2).find_each.count).to eq(2)
108
+ expect(Post.where(user: "user", domain: "domain").limit(2).find_each.count).to eq(2)
109
+
110
+ expect(Post.limit(3).find_each.count).to eq(3)
111
+ expect(Post.where(user: "user", domain: "domain").limit(3).find_each.count).to eq(3)
112
+ end
113
+ end
114
+
115
+ describe "#first" do
116
+ it "returns the first record" do
117
+ post1 = Post.create!(user: "user", domain: "domain", timestamp: Time.now - 1.day)
118
+ post2 = Post.create!(user: "user", domain: "domain", timestamp: Time.now + 1.day)
119
+
120
+ expect(Post.where(user: "user", domain: "domain").order(id: :asc).first).to eq(post1)
121
+ expect(Post.where(user: "user", domain: "domain").order(id: :desc).first).to eq(post2)
122
+ end
123
+ end
124
+
125
+ describe "#distinct" do
126
+ it "returns distinct values for the specified columns" do
127
+ Post.create!(user: "user1", domain: "domain1", timestamp: Time.now)
128
+ Post.create!(user: "user1", domain: "domain1", timestamp: Time.now)
129
+ Post.create!(user: "user1", domain: "domain2", timestamp: Time.now)
130
+ Post.create!(user: "user1", domain: "domain2", timestamp: Time.now)
131
+ Post.create!(user: "user2", domain: "domain1", timestamp: Time.now)
132
+ Post.create!(user: "user2", domain: "domain1", timestamp: Time.now)
133
+
134
+ expect(Post.select(:user, :domain).distinct.find_each.to_a).to eq(
135
+ [
136
+ { "user" => "user1", "domain" => "domain1" },
137
+ { "user" => "user1", "domain" => "domain2" },
138
+ { "user" => "user2", "domain" => "domain1" }
139
+ ]
140
+ )
141
+ end
142
+ end
143
+
144
+ describe "#select" do
145
+ it "returns the specified columns only" do
146
+ Post.create!(user: "user1", domain: "domain1", timestamp: Time.now)
147
+ Post.create!(user: "user2", domain: "domain2", timestamp: Time.now)
148
+
149
+ expect(Post.select(:user, :domain).find_each.to_a).to eq(
150
+ [
151
+ { "user" => "user1", "domain" => "domain1" },
152
+ { "user" => "user2", "domain" => "domain2" }
153
+ ]
154
+ )
155
+ end
156
+ end
157
+
158
+ describe "#find_each" do
159
+ it "returns all records" do
160
+ Post.create!(user: "user", domain: "domain", message: "message1", timestamp: Time.now)
161
+ Post.create!(user: "user", domain: "domain", message: "message2", timestamp: Time.now + 1.day)
162
+ Post.create!(user: "user", domain: "domain", message: "message3", timestamp: Time.now + 2.days)
163
+
164
+ expect(Post.find_each(batch_size: 2).map(&:message)).to eq(["message1", "message2", "message3"])
165
+ end
166
+ end
167
+
168
+ describe "#find_in_batches" do
169
+ it "returns all records in batches" do
170
+ Post.create!(user: "user", domain: "domain", message: "message1", timestamp: Time.now)
171
+ Post.create!(user: "user", domain: "domain", message: "message2", timestamp: Time.now + 1.day)
172
+ Post.create!(user: "user", domain: "domain", message: "message3", timestamp: Time.now + 2.days)
173
+
174
+ expect(Post.find_in_batches(batch_size: 2).map { |batch| batch.map(&:message) }).to eq([["message1", "message2"], ["message3"]])
175
+ end
176
+ end
177
+
178
+ describe "#count" do
179
+ it "returns the number of records" do
180
+ Post.create!(user: "user1", domain: "domain", timestamp: Time.now)
181
+ Post.create!(user: "user1", domain: "domain", timestamp: Time.now)
182
+ Post.create!(user: "user2", domain: "domain", timestamp: Time.now)
183
+
184
+ expect(Post.count).to eq(3)
185
+ expect(Post.where(user: "user1", domain: "domain").count).to eq(2)
186
+ end
187
+ end
188
+
189
+ describe "#delete_all" do
190
+ it "deletes the specified records" do
191
+ _post1 = Post.create!(user: "user", domain: "domain1", timestamp: Time.now)
192
+ _post2 = Post.create!(user: "user", domain: "domain1", timestamp: Time.now)
193
+ post3 = Post.create!(user: "user", domain: "domain2", timestamp: Time.now)
194
+
195
+ Post.where(user: "user", domain: "domain1").delete_all
196
+
197
+ expect(Post.all.to_a).to eq([post3])
198
+ end
199
+ end
200
+
201
+ describe "#delete_in_batches" do
202
+ it "deletes the records in batches" do
203
+ _post1 = Post.create!(user: "user", domain: "domain1", timestamp: Time.now)
204
+ _post2 = Post.create!(user: "user", domain: "domain1", timestamp: Time.now)
205
+ post3 = Post.create!(user: "user", domain: "domain2", timestamp: Time.now)
206
+
207
+ Post.where(user: "user", domain: "domain1").delete_in_batches
208
+
209
+ expect(Post.all.to_a).to eq([post3])
210
+ end
211
+ end
212
+
213
+ describe "#to_a" do
214
+ it "converts the relation to an array" do
215
+ Post.create!(user: "user", domain: "domain1", message: "message1", timestamp: Time.now)
216
+ Post.create!(user: "user", domain: "domain1", message: "message2", timestamp: Time.now)
217
+ Post.create!(user: "user", domain: "domain2", message: "message3", timestamp: Time.now)
218
+
219
+ expect(Post.where(user: "user", domain: "domain1").to_a.map(&:message).to_set).to eq(["message1", "message2"].to_set)
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,19 @@
1
+ require File.expand_path("../spec_helper", __dir__)
2
+
3
+ RSpec.describe CassandraStore::SchemaMigration do
4
+ describe ".create_table" do
5
+ it "creates the schema migration table" do
6
+ expect { described_class.create(version: Time.now.to_i) }.to raise_error(Cassandra::Errors::InvalidError)
7
+
8
+ described_class.create_table
9
+
10
+ expect { described_class.create(version: Time.now.to_i) }.not_to raise_error
11
+ end
12
+
13
+ it "respects the if_not_exists option" do
14
+ described_class.create_table
15
+
16
+ expect { described_class.create_table(if_not_exists: true) }.not_to raise_error
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ class Migration1 < CassandraStore::Migration
2
+ def up; end
3
+
4
+ def down; end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Migration2 < CassandraStore::Migration
2
+ def up; end
3
+
4
+ def down; end
5
+ end
@@ -0,0 +1,87 @@
1
+ require "cassandra_store"
2
+
3
+ CassandraStore::Base.configure(
4
+ keyspace: "cassandra_store",
5
+ replication: { class: "SimpleStrategy", replication_factor: 1 }
6
+ )
7
+
8
+ CassandraStore::Base.drop_keyspace(if_exists: true)
9
+ CassandraStore::Base.create_keyspace
10
+
11
+ CassandraStore::Base.execute <<CQL
12
+ CREATE TABLE posts(
13
+ user TEXT,
14
+ domain TEXT,
15
+ id TIMEUUID,
16
+ message TEXT,
17
+ timestamp TIMESTAMP,
18
+ PRIMARY KEY((user, domain), id)
19
+ )
20
+ CQL
21
+
22
+ class Post < CassandraStore::Base
23
+ column :user, :text, partition_key: true
24
+ column :domain, :text, partition_key: true
25
+ column :id, :timeuuid, clustering_key: true
26
+ column :message, :text
27
+ column :timestamp, :timestamp
28
+
29
+ before_create do
30
+ self.timestamp ||= Time.now
31
+ self.id ||= generate_timeuuid(timestamp)
32
+ end
33
+ end
34
+
35
+ CassandraStore::Base.execute <<CQL
36
+ CREATE TABLE test_logs(
37
+ date DATE,
38
+ bucket INT,
39
+ id TIMEUUID,
40
+ query TEXT,
41
+ username TEXT,
42
+ timestamp TIMESTAMP,
43
+ PRIMARY KEY((date, bucket), id)
44
+ )
45
+ CQL
46
+
47
+ class TestLog < CassandraStore::Base
48
+ column :date, :date, partition_key: true
49
+ column :bucket, :int, partition_key: true
50
+ column :id, :timeuuid, clustering_key: true
51
+ column :query, :text
52
+ column :username, :text
53
+ column :timestamp, :timestamp
54
+
55
+ validates_presence_of :timestamp
56
+
57
+ def self.bucket_for(id)
58
+ Digest::SHA1.hexdigest(id.to_s)[0].to_i(16) % 8
59
+ end
60
+
61
+ before_create do
62
+ self.id = generate_timeuuid(timestamp)
63
+
64
+ self.date = id.to_date.strftime("%F")
65
+ self.bucket = self.class.bucket_for(id)
66
+ end
67
+ end
68
+
69
+ class TestLogWithContext < TestLog
70
+ def self.table_name
71
+ "test_logs"
72
+ end
73
+
74
+ validates_presence_of :username, on: :create
75
+ validates_presence_of :query, on: :update
76
+ end
77
+
78
+ RSpec.configure do |config|
79
+ config.before do
80
+ CassandraStore::Base.execute <<~CQL
81
+ DROP TABLE IF EXISTS schema_migrations
82
+ CQL
83
+
84
+ TestLog.delete_in_batches
85
+ Post.delete_in_batches
86
+ end
87
+ end
metadata ADDED
@@ -0,0 +1,214 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cassandra_store
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Benjamin Vetter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activemodel
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: activesupport
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '3.0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: cassandra-driver
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: connection_pool
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: hooks
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Powerful ORM for Cassandra
154
+ email:
155
+ - vetter@flakks.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - ".gitignore"
161
+ - ".rubocop.yml"
162
+ - ".travis.yml"
163
+ - Gemfile
164
+ - LICENSE.txt
165
+ - README.md
166
+ - Rakefile
167
+ - cassandra_store.gemspec
168
+ - docker-compose.yml
169
+ - lib/cassandra_store.rb
170
+ - lib/cassandra_store/base.rb
171
+ - lib/cassandra_store/migration.rb
172
+ - lib/cassandra_store/railtie.rb
173
+ - lib/cassandra_store/relation.rb
174
+ - lib/cassandra_store/schema_migration.rb
175
+ - lib/cassandra_store/tasks/cassandra.rake
176
+ - lib/cassandra_store/version.rb
177
+ - spec/cassandra_store/base_spec.rb
178
+ - spec/cassandra_store/migration_spec.rb
179
+ - spec/cassandra_store/relation_spec.rb
180
+ - spec/cassandra_store/schema_migration_spec.rb
181
+ - spec/fixtures/1589957812_migration1.rb
182
+ - spec/fixtures/1589957813_migration2.rb
183
+ - spec/spec_helper.rb
184
+ homepage: https://github.com/mrkamel/cassandra_store
185
+ licenses:
186
+ - MIT
187
+ metadata: {}
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubygems_version: 3.0.3
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: Easy to use ActiveRecord like ORM for Cassandra
207
+ test_files:
208
+ - spec/cassandra_store/base_spec.rb
209
+ - spec/cassandra_store/migration_spec.rb
210
+ - spec/cassandra_store/relation_spec.rb
211
+ - spec/cassandra_store/schema_migration_spec.rb
212
+ - spec/fixtures/1589957812_migration1.rb
213
+ - spec/fixtures/1589957813_migration2.rb
214
+ - spec/spec_helper.rb