cql_model 0.0.2 → 0.0.3

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.
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