cassandra_record 0.0.2

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 15e9b62adf2878cd1519843016be084e20ae05c2
4
+ data.tar.gz: e0f60d8679f48770283c0d9d2af5e9865a9361c0
5
+ SHA512:
6
+ metadata.gz: f71feade39ab085b9ba0cfd24c1b5e4dae26e03299c31e5496445900edecbda81777932438ce1921c97423853d7c8910f7a731b163a9f362350364c3e286e423
7
+ data.tar.gz: b1a53502f6027829f06361841d72b91e8d7297e0fed04c0229d997fda862beb7e2faec39f6d71fd62084b545168bd6fa5e777a8e92709f42a9c260ea02893c37
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group 'test' do
6
+ gem 'rspec'
7
+ gem 'rspec-mocks-extensions'
8
+ end
9
+
10
+ group :development, :test do
11
+ gem 'pry'
12
+ gem 'pry-byebug'
13
+ gem 'pry-doc'
14
+ end
15
+
16
+
17
+ gem 'activesupport'
18
+ gem 'cassandra-driver'
data/Gemfile.lock ADDED
@@ -0,0 +1,73 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cassandra_record (0.0.1)
5
+ activesupport
6
+ cassandra-driver
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (4.0.2)
12
+ i18n (~> 0.6, >= 0.6.4)
13
+ minitest (~> 4.2)
14
+ multi_json (~> 1.3)
15
+ thread_safe (~> 0.1)
16
+ tzinfo (~> 0.3.37)
17
+ byebug (2.7.0)
18
+ columnize (~> 0.3)
19
+ debugger-linecache (~> 1.2)
20
+ cassandra-driver (1.0.0.rc.1)
21
+ ione (~> 1.2.0.pre9)
22
+ coderay (1.1.0)
23
+ columnize (0.8.9)
24
+ debugger-linecache (1.2.0)
25
+ diff-lcs (1.2.5)
26
+ i18n (0.6.9)
27
+ ione (1.2.0)
28
+ method_source (0.8.2)
29
+ minitest (4.7.5)
30
+ multi_json (1.10.1)
31
+ pry (0.9.12.6)
32
+ coderay (~> 1.0)
33
+ method_source (~> 0.8)
34
+ slop (~> 3.4)
35
+ pry-byebug (1.3.2)
36
+ byebug (~> 2.7)
37
+ pry (~> 0.9.12)
38
+ pry-doc (0.6.0)
39
+ pry (~> 0.9)
40
+ yard (~> 0.8)
41
+ rake (10.3.2)
42
+ rspec (3.1.0)
43
+ rspec-core (~> 3.1.0)
44
+ rspec-expectations (~> 3.1.0)
45
+ rspec-mocks (~> 3.1.0)
46
+ rspec-core (3.1.7)
47
+ rspec-support (~> 3.1.0)
48
+ rspec-expectations (3.1.2)
49
+ diff-lcs (>= 1.2.0, < 2.0)
50
+ rspec-support (~> 3.1.0)
51
+ rspec-mocks (3.1.3)
52
+ rspec-support (~> 3.1.0)
53
+ rspec-mocks-extensions (0.0.1)
54
+ rspec-support (3.1.2)
55
+ slop (3.5.0)
56
+ thread_safe (0.3.3)
57
+ tzinfo (0.3.39)
58
+ yard (0.8.7.6)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ activesupport
65
+ bundler (~> 1.7)
66
+ cassandra-driver
67
+ cassandra_record!
68
+ pry
69
+ pry-byebug
70
+ pry-doc
71
+ rake (~> 10.0)
72
+ rspec
73
+ rspec-mocks-extensions
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Gust
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Cassandra Record
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ ```ruby
8
+ gem 'cassandra_record'
9
+ ```
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install cassandra_record
18
+
19
+ ## Usage
20
+
21
+ ## Contributing
22
+
23
+ 1. Fork it ( https://github.com/zephyr-dev/cassandra_record/fork )
24
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
25
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
26
+ 4. Push to the branch (`git push origin my-new-feature`)
27
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require 'cassandra_record'
3
+
4
+ task :environment do
5
+ end
6
+
7
+ namespace :cassandra_record do
8
+ namespace :structure do
9
+ desc "Loads your structures"
10
+ task :load => :environment do
11
+ filepath = File.dirname(__FILE__) + "/db/cassandra_structure.cql"
12
+ `cqlsh -f #{filepath}`
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cassandra_record/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "cassandra_record"
8
+ spec.version = CassandraRecord::VERSION
9
+ spec.authors = ["Gust"]
10
+ spec.email = ["zephyr-dev@googlegroups.com"]
11
+ spec.summary = %q{A familiar interface to Cassandra-backed models}
12
+ spec.description = %q{A familiar interface to Cassandra-backed models}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+
24
+ spec.add_runtime_dependency "activesupport"
25
+ spec.add_runtime_dependency "cassandra-driver"
26
+ end
@@ -0,0 +1,57 @@
1
+ require 'active_support/hash_with_indifferent_access'
2
+ require 'active_support/core_ext/hash'
3
+ require 'active_support/inflector'
4
+
5
+ module CassandraRecord
6
+ class Base
7
+ class << self
8
+ def create(attributes)
9
+ new(attributes).create
10
+ end
11
+
12
+ def where(attributes={})
13
+ new.where(attributes)
14
+ end
15
+ end
16
+
17
+ attr_accessor :attributes
18
+
19
+ def initialize(attributes={})
20
+ @attributes = HashWithIndifferentAccess.new(attributes)
21
+ end
22
+
23
+ def where(options={})
24
+ results = Statement.where(table_name, options).map do |attributes|
25
+ self.class.new(attributes)
26
+ end
27
+ end
28
+
29
+ def create
30
+ Statement.create(table_name, columns, values)
31
+ self
32
+ end
33
+
34
+ private
35
+
36
+ def table_name
37
+ ActiveSupport::Inflector.tableize(self.class.name).gsub(/\//, '_')
38
+ end
39
+
40
+ def columns
41
+ attributes.keys
42
+ end
43
+
44
+ def values
45
+ attributes.values
46
+ end
47
+
48
+ def method_missing(method, *args, &block)
49
+ if attributes.has_key?(method)
50
+ attributes[method]
51
+ else
52
+ super(method, *args, &block)
53
+ end
54
+ end
55
+
56
+ end
57
+ end
@@ -0,0 +1,40 @@
1
+ require 'cassandra'
2
+ require 'singleton'
3
+
4
+ module CassandraRecord
5
+ module Database
6
+ module Adapters
7
+ class Cassandra
8
+ include Singleton
9
+
10
+ attr_reader :keyspace
11
+
12
+ def session
13
+ @session ||= ::Cassandra.cluster.connect(@keyspace)
14
+ end
15
+
16
+ def use(keyspace_name)
17
+ @session = nil
18
+ @keyspace = keyspace_name
19
+ end
20
+
21
+ def prepare(cql)
22
+ session.prepare(cql)
23
+ end
24
+
25
+ def execute(cql, *args)
26
+ session.execute(cql, *args)
27
+ end
28
+
29
+ def cluster
30
+ ::Cassandra.cluster.connect
31
+ end
32
+
33
+ def session
34
+ @session ||= ::Cassandra.cluster.connect(@keyspace)
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ module CassandraRecord
2
+ class Statement
3
+ class << self
4
+ def where(table_name, options={})
5
+ cql = base_where_query(table_name)
6
+
7
+ if options.present?
8
+ cql << 'WHERE'
9
+ cql << parse_where_clause_options(options)
10
+ end
11
+
12
+ cql << ';'
13
+ db.execute(cql)
14
+ end
15
+
16
+ def create(table_name, columns, values)
17
+ cql = <<-CQL
18
+ INSERT INTO #{table_name} (#{columns.join(", ")})
19
+ VALUES (#{value_placeholders(values).join(", ")})
20
+ CQL
21
+
22
+ insert_statement = db.prepare(cql)
23
+ db.execute(insert_statement, *values)
24
+ end
25
+
26
+ private
27
+
28
+ def db
29
+ Database::Adapters::Cassandra.instance
30
+ end
31
+
32
+ def value_placeholders(values)
33
+ [].tap do |arr|
34
+ values.count.times do
35
+ arr << "?"
36
+ end
37
+ end
38
+ end
39
+
40
+ def base_where_query(table_name)
41
+ cql = <<-CQL
42
+ SELECT *
43
+ FROM #{table_name}
44
+ CQL
45
+ end
46
+
47
+ def parse_where_clause_options(options)
48
+ return options if options.is_a?(String)
49
+
50
+ clause_count = 0
51
+ "".tap do |cql|
52
+ options.each do |column, value|
53
+ cql << ' AND' if clause_count > 0
54
+ cql << " #{column.to_s} = #{Cassandra::Util.encode_object(value)}"
55
+ clause_count += 1
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,3 @@
1
+ module CassandraRecord
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'pry'
3
+
4
+ require 'cassandra_record/base'
5
+ require 'cassandra_record/statement'
6
+ require 'cassandra_record/database/adapters/cassandra'
7
+
8
+ module CassandraRecord
9
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe CassandraRecord::Base do
4
+ let(:db) { RSpec.configuration.db }
5
+ let(:keyspace) { RSpec.configuration.keyspace }
6
+
7
+ class TestRecord < CassandraRecord::Base; end
8
+
9
+ describe ".create" do
10
+ it "returns a hydrated record" do
11
+ record = TestRecord.create(id: 99, name: 'turkey')
12
+
13
+ expect(record.id).to eq(99)
14
+ expect(record.name).to eq('turkey')
15
+ end
16
+
17
+ it "persists a record" do
18
+ record = TestRecord.create(id: 99, name: 'turkey')
19
+
20
+ select = <<-CQL
21
+ SELECT * from #{keyspace}.test_records
22
+ WHERE id = 99;
23
+ CQL
24
+
25
+ results = db.execute(select)
26
+ expect(results.count).to eq(1)
27
+
28
+ result = results.first
29
+ expect(result['id']).to eq(99)
30
+ expect(result['name']).to eq('turkey')
31
+ end
32
+ end
33
+
34
+ describe ".where" do
35
+ context "with results" do
36
+ before do
37
+ insert_1 = <<-CQL
38
+ INSERT INTO #{keyspace}.test_records (id, name)
39
+ VALUES (9090, 'burgers');
40
+ CQL
41
+ insert_2 = <<-CQL
42
+ INSERT INTO #{keyspace}.test_records (id, name)
43
+ VALUES (8080, 'nachos');
44
+ CQL
45
+ insert_3 = <<-CQL
46
+ INSERT INTO #{keyspace}.test_records (id, name)
47
+ VALUES (7070, 'nachos');
48
+ CQL
49
+
50
+ db.execute(insert_1)
51
+ db.execute(insert_2)
52
+ db.execute(insert_3)
53
+ end
54
+
55
+ it "returns an array of hydrated results" do
56
+ nacho_results = TestRecord.where(name: 'nachos')
57
+ expect(nacho_results.count).to eq(2)
58
+
59
+ expect(nacho_results[0].id).to eq(8080)
60
+ expect(nacho_results[0].name).to eq('nachos')
61
+
62
+ expect(nacho_results[1].id).to eq(7070)
63
+ expect(nacho_results[1].name).to eq('nachos')
64
+ end
65
+ end
66
+
67
+ context "without results" do
68
+ it "returns an empty array" do
69
+ results = TestRecord.where(name: 'pizza')
70
+ expect(results).to eq([])
71
+ end
72
+ end
73
+ end
74
+
75
+ end
@@ -0,0 +1,67 @@
1
+ ENV['environment'] = 'test'
2
+
3
+ require 'cassandra_record'
4
+
5
+ RSpec.configure do |config|
6
+ config.run_all_when_everything_filtered = true
7
+ config.filter_run :focus
8
+
9
+ # Run specs in random order to surface order dependencies. If you find an
10
+ # order dependency and want to debug it, you can fix the order by providing
11
+ # the seed, which is printed after each run.
12
+ # --seed 1234
13
+ config.order = 'random'
14
+
15
+ # create test keyspace and table
16
+ db = CassandraRecord::Database::Adapters::Cassandra.instance
17
+
18
+ config.add_setting :db
19
+ config.db = db
20
+ config.add_setting :keyspace
21
+ config.keyspace = 'test_space' # CassandraRecord::Database::Adapters::Cassandra.instance.keyspace
22
+
23
+ create_keyspace = <<-CQL
24
+ CREATE KEYSPACE IF NOT EXISTS #{config.keyspace} WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '1'};
25
+ CQL
26
+
27
+ create_test_table_1 = <<-CQL
28
+ CREATE TABLE IF NOT EXISTS test_records (
29
+ id int,
30
+ name text,
31
+ PRIMARY KEY (id)
32
+ );
33
+ CQL
34
+
35
+ create_test_table_2 = <<-CQL
36
+ CREATE TABLE IF NOT EXISTS matching_log_items (
37
+ blah int,
38
+ whatever text,
39
+ PRIMARY KEY (blah)
40
+ );
41
+ CQL
42
+
43
+ create_test_table_3 = <<-CQL
44
+ CREATE TABLE IF NOT EXISTS non_matching_log_items (
45
+ blah int,
46
+ whatever text,
47
+ PRIMARY KEY (blah)
48
+ );
49
+ CQL
50
+
51
+ create_table_index = <<-CQL
52
+ CREATE INDEX IF NOT EXISTS test_records_name_index ON test_records (name);
53
+ CQL
54
+
55
+ db.cluster.execute(create_keyspace)
56
+ db.use(config.keyspace)
57
+ db.execute(create_test_table_1)
58
+ db.execute(create_test_table_2)
59
+ db.execute(create_test_table_3)
60
+ db.execute(create_table_index)
61
+
62
+ config.before(:each) do
63
+ ['test_records', 'matching_log_items'].each do |table_name|
64
+ db.execute("TRUNCATE #{table_name}")
65
+ end
66
+ end
67
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cassandra_record
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Gust
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-12 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: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: activesupport
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
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: cassandra-driver
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: A familiar interface to Cassandra-backed models
70
+ email:
71
+ - zephyr-dev@googlegroups.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .rspec
77
+ - Gemfile
78
+ - Gemfile.lock
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - cassandra_record.gemspec
83
+ - lib/cassandra_record.rb
84
+ - lib/cassandra_record/base.rb
85
+ - lib/cassandra_record/database/adapters/cassandra.rb
86
+ - lib/cassandra_record/statement.rb
87
+ - lib/cassandra_record/version.rb
88
+ - spec/integration/cassandra_record/base_spec.rb
89
+ - spec/spec_helper.rb
90
+ homepage: ''
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.2.0
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: A familiar interface to Cassandra-backed models
114
+ test_files:
115
+ - spec/integration/cassandra_record/base_spec.rb
116
+ - spec/spec_helper.rb
117
+ has_rdoc: