cql_model 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -32,6 +32,33 @@ Or install it yourself as:
32
32
  column :dob, Date
33
33
  end
34
34
 
35
+ ### Schema Definition
36
+
37
+ While Cassandra doesn't get super picky about schemas you should understand how
38
+ you're storing your data. To help with this you should define the primary key
39
+ and the columns you care about within your model.
40
+
41
+ #### Primary Key
42
+
43
+ Defining the primary key determines which column the id-oriented finders will
44
+ work with. The default primary key is `id`.
45
+
46
+ primary_key :id
47
+ primary_key 'card_number'
48
+
49
+ #### Columns
50
+
51
+ You define columns by supplying the attribute name, Ruby class for type
52
+ conversion and an optional set of options.
53
+
54
+ column :first_name, String
55
+ column :birth_date, Date
56
+ column :birth_date, Date, column_name: :dob
57
+
58
+ The supported options for columns are as follows:
59
+
60
+ * `column_name`: actual column name for storing the attribute.
61
+
35
62
  ## Contributing
36
63
 
37
64
  1. Fork it
@@ -7,6 +7,7 @@ require 'cql/base'
7
7
  require 'cql/model/version'
8
8
  require 'cql/model/schema_methods'
9
9
  require 'cql/model/finder_methods'
10
+ require 'cql/model/persistence_methods'
10
11
  require 'cql/model/query_result'
11
12
 
12
13
  module Cql
@@ -24,6 +25,9 @@ module Cql
24
25
 
25
26
  include Cql::Model::SchemaMethods
26
27
  include Cql::Model::FinderMethods
28
+ include Cql::Model::PersistenceMethods
29
+
30
+ attr_reader :primary_value
27
31
 
28
32
  def initialize(attributes = {}, options = {})
29
33
  self.class.columns.each do |key, config|
@@ -34,6 +38,8 @@ module Cql
34
38
  end
35
39
 
36
40
  @metadata = options[:metadata]
41
+ @primary_value = attributes[self.class.primary_key.to_sym]
42
+ @persisted = false
37
43
 
38
44
  attributes.each do |key, value|
39
45
  attr_name = "@#{key.to_s}".to_sym
@@ -42,5 +48,18 @@ module Cql
42
48
 
43
49
  self
44
50
  end
51
+
52
+ def quoted_primary_value
53
+ primary_value.is_a?(Fixnum) ? primary_value : "'#{primary_value}'"
54
+ end
55
+
56
+ def persisted?
57
+ @persisted
58
+ end
59
+
60
+ def self.execute(query)
61
+ cql_results = Cql::Base.connection.execute(query)
62
+ Cql::Model::QueryResult.new(cql_results, self)
63
+ end
45
64
  end
46
65
  end
@@ -4,14 +4,33 @@ module Cql::Model::FinderMethods
4
4
  module ClassMethods
5
5
  def all
6
6
  query = "SELECT * FROM #{self.model_name.plural}"
7
- cql_results = Cql::Base.connection.execute(query)
8
- Cql::Model::QueryResult.new(cql_results, self)
7
+ execute(query)
9
8
  end
10
9
 
11
- def find(primary_key_value)
12
- query = "SELECT * FROM #{self.model_name.plural} WHERE #{self.primary_key} = #{primary_key_value}"
13
- cql_results = Cql::Base.connection.execute(query)
14
- Cql::Model::QueryResult.new(cql_results, self).first
10
+ def find(*args)
11
+ value = args.to_a.flatten.join(',')
12
+ key = self.primary_key
13
+ table = self.model_name.plural
14
+
15
+ query = "SELECT * FROM #{table} WHERE #{key} IN (#{value})"
16
+
17
+ if args[0].is_a?(Array) || args.size > 1
18
+ execute(query).to_a
19
+ else
20
+ execute(query).first
21
+ end
22
+ end
23
+
24
+ def find_by(hash)
25
+ table = self.model_name.plural
26
+
27
+ clause = "WHERE "
28
+ clause_pieces = hash.collect {|key,value| "#{key.to_s} = '#{value}'"}
29
+ clause << clause_pieces.join(' AND ')
30
+
31
+ query = "SELECT * FROM #{table} #{clause} ALLOW FILTERING"
32
+
33
+ execute(query).to_a
15
34
  end
16
35
  end
17
36
  end
@@ -0,0 +1,28 @@
1
+ module Cql::Model::PersistenceMethods
2
+ extend ::ActiveSupport::Concern
3
+
4
+ def save
5
+ updates = []
6
+
7
+ self.class.columns.each do |key, config|
8
+ value = instance_variable_get("@#{config[:attribute_name].to_s}".to_sym)
9
+ value = "'#{value}'" unless value.is_a?(Fixnum)
10
+ updates << "#{key.to_s} = #{value}" unless value.nil?
11
+ end
12
+
13
+ updates = updates.join(', ')
14
+
15
+ table = self.class.model_name.plural
16
+ primary_key = self.class.primary_key.to_s
17
+
18
+ query = "UPDATE #{table} SET #{updates} WHERE #{primary_key} = #{quoted_primary_value}"
19
+ Cql::Base.connection.execute(query)
20
+
21
+ @persisted = true
22
+ self
23
+ end
24
+
25
+ module ClassMethods
26
+
27
+ end
28
+ end
@@ -3,17 +3,18 @@ module Cql::Model::SchemaMethods
3
3
 
4
4
  module ClassMethods
5
5
  def columns
6
- @@columns ||= {}
6
+ @columns ||= {}
7
7
  end
8
8
 
9
9
  def primary_key(key_name = nil)
10
- @@primary_key ||= key_name.nil? ? 'id' : key_name.to_s
10
+ @primary_key ||= key_name.nil? ? 'id' : key_name.to_s
11
11
  end
12
12
 
13
13
  def column(attribute_name, ruby_class, options = {})
14
14
  column_name = options[:column_name] || attribute_name
15
15
 
16
- columns[column_name.to_sym] = {
16
+ @columns ||= {}
17
+ @columns[column_name.to_sym] = {
17
18
  attribute_name: attribute_name.to_sym,
18
19
  klass: ruby_class.to_s.constantize
19
20
  }.merge(options)
@@ -1,5 +1,5 @@
1
1
  module Cql
2
2
  class Model
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.3'
4
4
  end
5
5
  end
@@ -1,19 +1,39 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Cql::Model do
3
+ describe 'Cql::Model Finders' do
4
4
  before :all do
5
5
  Cql::Base.establish_connection(host: '127.0.0.1')
6
6
  Cql::Base.connection.use('cql_model_test')
7
7
  end
8
8
 
9
- describe 'Finders' do
10
- describe '#all' do
11
- it { Person.all.must_be_instance_of Cql::Model::QueryResult }
12
- it { Person.all.first.must_be_instance_of Person }
13
- end
9
+ describe '#all' do
10
+ it { Person.all.must_be_instance_of Cql::Model::QueryResult }
11
+ it { Person.all.first.must_be_instance_of Person }
12
+ end
14
13
 
15
- describe '#find' do
14
+ describe '#find' do
15
+ describe 'single records' do
16
16
  it { Person.find(1).must_be_instance_of Person }
17
+ it { Person.find('1').must_be_instance_of Person }
17
18
  end
19
+
20
+ describe 'multiple/array records' do
21
+ it { Person.find(1,2).must_be_instance_of Array }
22
+ it { Person.find(1,2).size.must_equal 2 }
23
+
24
+ it { Person.find([1]).must_be_instance_of Array }
25
+ it { Person.find([1]).size.must_equal 1 }
26
+
27
+ it { Person.find([1,2]).must_be_instance_of Array }
28
+ it { Person.find([1,2]).size.must_equal 2 }
29
+ end
30
+ end
31
+
32
+ describe '#find_by' do
33
+ it { Person.find_by(first_name: 'John').must_be_instance_of Array }
34
+ it { Person.find_by(first_name: 'John').size.must_equal 1 }
35
+
36
+ it { Person.find_by(first_name: 'John', last_name: 'Doe').must_be_instance_of Array }
37
+ it { Person.find_by(first_name: 'John', last_name: 'Doe').size.must_equal 1 }
18
38
  end
19
39
  end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Cql::Model Finders' do
4
+ before :all do
5
+ Cql::Base.establish_connection(host: '127.0.0.1')
6
+ Cql::Base.connection.use('cql_model_test')
7
+ end
8
+
9
+ before :each do
10
+ @person = Person.new(id: 123, first_name: 'Alex', last_name: 'Jones')
11
+ end
12
+
13
+ after :each do
14
+ Cql::Base.connection.execute('DELETE FROM people WHERE id = 123')
15
+ end
16
+
17
+ describe '#save' do
18
+ it { @person.save.must_be_instance_of Person }
19
+ it do
20
+ @person.persisted?.must_equal false
21
+ @person.save
22
+ @person.persisted?.must_equal true
23
+ end
24
+ end
25
+
26
+ describe '#update_attribute' do
27
+
28
+ end
29
+
30
+ describe '#update_attributes' do
31
+
32
+ end
33
+ end
@@ -10,7 +10,6 @@ unless ENV['COVERAGE'] == 'no'
10
10
  require 'simplecov'
11
11
  SimpleCov.start do
12
12
  add_filter "/spec/"
13
- add_group 'Source', 'lib'
14
13
  end
15
14
  end
16
15
 
@@ -50,4 +50,7 @@ def setup_cql_test
50
50
  cql_client.execute(table_definition)
51
51
  rescue Exception
52
52
  end
53
+
54
+ begin; cql_client.execute("CREATE INDEX ON people (first_name);") rescue Exception end
55
+ begin; cql_client.execute("CREATE INDEX ON people (last_name);") rescue Exception end
53
56
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cql_model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -139,6 +139,7 @@ files:
139
139
  - lib/cql/base.rb
140
140
  - lib/cql/model.rb
141
141
  - lib/cql/model/finder_methods.rb
142
+ - lib/cql/model/persistence_methods.rb
142
143
  - lib/cql/model/query_result.rb
143
144
  - lib/cql/model/schema_methods.rb
144
145
  - lib/cql/model/version.rb
@@ -146,6 +147,7 @@ files:
146
147
  - spec/active_model_lint_spec.rb
147
148
  - spec/cql/base_spec.rb
148
149
  - spec/cql/model/finders_spec.rb
150
+ - spec/cql/model/persistence_spec.rb
149
151
  - spec/cql/model/query_result_spec.rb
150
152
  - spec/spec_helper.rb
151
153
  - spec/support/setup_test_keyspace.rb
@@ -164,7 +166,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
166
  version: '0'
165
167
  segments:
166
168
  - 0
167
- hash: 2224793988251735129
169
+ hash: 3909175812129280825
168
170
  required_rubygems_version: !ruby/object:Gem::Requirement
169
171
  none: false
170
172
  requirements:
@@ -173,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
175
  version: '0'
174
176
  segments:
175
177
  - 0
176
- hash: 2224793988251735129
178
+ hash: 3909175812129280825
177
179
  requirements: []
178
180
  rubyforge_project:
179
181
  rubygems_version: 1.8.23
@@ -184,6 +186,7 @@ test_files:
184
186
  - spec/active_model_lint_spec.rb
185
187
  - spec/cql/base_spec.rb
186
188
  - spec/cql/model/finders_spec.rb
189
+ - spec/cql/model/persistence_spec.rb
187
190
  - spec/cql/model/query_result_spec.rb
188
191
  - spec/spec_helper.rb
189
192
  - spec/support/setup_test_keyspace.rb