quandl_cassandra 1.3.1 → 1.4.0
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/.gitignore +4 -1
- data/Berksfile +4 -0
- data/README.md +9 -3
- data/Rakefile +0 -8
- data/UPGRADE.md +6 -2
- data/Vagrantfile +43 -0
- data/examples/connect.rb +41 -3
- data/lib/quandl/cassandra.rb +2 -2
- data/lib/quandl/cassandra/base/attributes.rb +103 -102
- data/lib/quandl/cassandra/base/logging.rb +25 -29
- data/lib/quandl/cassandra/base/sanitization.rb +7 -11
- data/lib/quandl/cassandra/base/schema.rb +36 -31
- data/lib/quandl/cassandra/base/scoping.rb +41 -45
- data/lib/quandl/cassandra/batch/logging.rb +16 -16
- data/lib/quandl/cassandra/configuration.rb +30 -30
- data/lib/quandl/cassandra/logger.rb +10 -10
- data/lib/quandl/cassandra/version.rb +3 -3
- data/quandl_cassandra.gemspec +4 -6
- data/spec/config/cassandra.rb +3 -5
- data/spec/lib/quandl/cassandra/base/schema_spec.rb +47 -0
- metadata +57 -48
- checksums.yaml +0 -7
- data/VERSION +0 -1
data/.gitignore
CHANGED
data/Berksfile
ADDED
data/README.md
CHANGED
@@ -1,7 +1,13 @@
|
|
1
|
-
#
|
1
|
+
# NOTE
|
2
2
|
|
3
|
-
|
3
|
+
This project is deprecated. See: [Cequel](https://github.com/cequel/cequel) for an alternative.
|
4
|
+
|
5
|
+
## Installation
|
4
6
|
|
7
|
+
```ruby
|
5
8
|
gem 'quandl_cassandra'
|
9
|
+
```
|
10
|
+
|
11
|
+
## Development
|
6
12
|
|
7
|
-
|
13
|
+
Install cookbooks with 'berks vendor'. Run Vagrant with 'vagrant up'.
|
data/Rakefile
CHANGED
@@ -9,11 +9,3 @@ desc "Run all specs"
|
|
9
9
|
RSpec::Core::RakeTask.new(:spec) do |task|
|
10
10
|
task.pattern = "spec/**/*_spec.rb"
|
11
11
|
end
|
12
|
-
|
13
|
-
require 'quandl/utility/rake_tasks'
|
14
|
-
Quandl::Utility::Tasks.configure do |c|
|
15
|
-
c.name = 'quandl_cassandra'
|
16
|
-
c.version_path = 'VERSION'
|
17
|
-
c.changelog_path = 'UPGRADE.md'
|
18
|
-
c.changelog_matching = ['^QUGC','^WIKI','^CASS']
|
19
|
-
end
|
data/UPGRADE.md
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
## 1.
|
2
|
-
|
1
|
+
## 1.4.0
|
3
2
|
|
3
|
+
* Don't allow invalid values of columns, column_names and column_types. Always fetch or recalculate if invalid.
|
4
|
+
* Stop using Quandl Utility.
|
5
|
+
* Create self contained development environment.
|
6
|
+
* Add more verbose logging.
|
4
7
|
|
8
|
+
## 1.3.0
|
5
9
|
|
6
10
|
|
7
11
|
## 1.2.5
|
data/Vagrantfile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :"
|
3
|
+
|
4
|
+
Vagrant.configure('2') do |config|
|
5
|
+
# All Vagrant configuration is done here. The most common configuration
|
6
|
+
# options are documented and commented below. For a complete reference,
|
7
|
+
# please see the online documentation at vagrantup.com.
|
8
|
+
|
9
|
+
# Every Vagrant virtual environment requires a box to build off of.
|
10
|
+
config.vm.box = "ubuntu-precise64"
|
11
|
+
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
|
12
|
+
config.omnibus.chef_version = '11.8.0'
|
13
|
+
|
14
|
+
config.vm.provider :virtualbox do |v|
|
15
|
+
v.memory = '2048'
|
16
|
+
end
|
17
|
+
|
18
|
+
config.vm.network :private_network, ip: "192.168.50.4"
|
19
|
+
|
20
|
+
config.vm.provision "chef_solo" do |chef|
|
21
|
+
|
22
|
+
chef.cookbooks_path = 'berks-cookbooks'
|
23
|
+
|
24
|
+
chef.add_recipe 'apt'
|
25
|
+
chef.add_recipe 'cassandra::datastax'
|
26
|
+
|
27
|
+
chef.json = {
|
28
|
+
cassandra: {
|
29
|
+
version: '1.2.16',
|
30
|
+
listen_address: '192.168.50.4',
|
31
|
+
rpc_address: '0.0.0.0'
|
32
|
+
},
|
33
|
+
java: {
|
34
|
+
install_flavor: 'oracle',
|
35
|
+
jdk_version: '7',
|
36
|
+
oracle: {
|
37
|
+
accept_oracle_download_terms: true
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/examples/connect.rb
CHANGED
@@ -9,9 +9,47 @@ require "quandl/fabricate"
|
|
9
9
|
Quandl::Logger.use Quandl::Logger::Outputs
|
10
10
|
|
11
11
|
Quandl::Cassandra.configure do |c|
|
12
|
-
c.hosts = ['localhost','192.168.
|
12
|
+
c.hosts = ['localhost','192.168.50.4']
|
13
13
|
c.consistency = :one
|
14
|
-
c.keyspace = 'wikiposit'
|
15
14
|
end
|
16
15
|
|
17
|
-
|
16
|
+
# Create development keyspace if it does not already exists
|
17
|
+
keyspace_name = 'quandl_development'
|
18
|
+
columnfamily_name = 'posts'
|
19
|
+
|
20
|
+
if Quandl::Cassandra::Base.execute("SELECT * FROM system.schema_keyspaces WHERE keyspace_name = '#{keyspace_name}';", 'one').empty?
|
21
|
+
Quandl::Cassandra::Base.execute("CREATE KEYSPACE #{keyspace_name} WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor': 1};", 'one')
|
22
|
+
end
|
23
|
+
|
24
|
+
results = Quandl::Cassandra::Base.execute("SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = '#{keyspace_name}';")
|
25
|
+
|
26
|
+
# Create column family if it does not exist
|
27
|
+
if results.empty? or results.none? { |r| r['columnfamily_name'] == columnfamily_name }
|
28
|
+
Quandl::Cassandra.configuration.keyspace = keyspace_name
|
29
|
+
Quandl::Cassandra::Base.reset_connection
|
30
|
+
Quandl::Cassandra::Base.execute("CREATE TABLE #{columnfamily_name} (
|
31
|
+
id uuid PRIMARY KEY,
|
32
|
+
content text,
|
33
|
+
author varchar,
|
34
|
+
updated_at timestamp );", 'one')
|
35
|
+
else
|
36
|
+
puts "The column family #{columnfamily_name} already exists in keyspace #{keyspace_name}!"
|
37
|
+
end
|
38
|
+
|
39
|
+
Quandl::Cassandra.configuration.keyspace = keyspace_name
|
40
|
+
Quandl::Cassandra::Base.reset_connection
|
41
|
+
|
42
|
+
class Post < Quandl::Cassandra::Base
|
43
|
+
|
44
|
+
table_name :posts
|
45
|
+
|
46
|
+
after_initialize :default_attributes
|
47
|
+
|
48
|
+
def default_attributes
|
49
|
+
self.id = Cql::Uuid.new(SecureRandom.uuid) unless id.present?
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
binding.pry
|
55
|
+
|
data/lib/quandl/cassandra.rb
CHANGED
@@ -1,112 +1,113 @@
|
|
1
1
|
module Quandl
|
2
|
-
module Cassandra
|
3
|
-
class Base
|
4
|
-
|
5
|
-
module Attributes
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
end
|
13
|
-
|
14
|
-
module ClassMethods
|
15
|
-
|
16
|
-
def define_attributes(*names)
|
17
|
-
Array(names).each{|name| define_attribute(name) }
|
18
|
-
end
|
19
|
-
|
20
|
-
def define_attribute(name)
|
21
|
-
name = name.to_sym
|
22
|
-
self.class_eval do
|
23
|
-
define_attribute_methods [name.to_sym]
|
2
|
+
module Cassandra
|
3
|
+
class Base
|
4
|
+
|
5
|
+
module Attributes
|
6
|
+
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
include ActiveModel::AttributeMethods
|
11
|
+
include ActiveModel::Dirty
|
24
12
|
end
|
25
|
-
|
26
|
-
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
|
16
|
+
def define_attributes(*names)
|
17
|
+
Array(names).each{|name| define_attribute(name) }
|
18
|
+
Quandl::Logger.info("The attributes for #{self.to_s} are #{Array(names).join(', ')}")
|
19
|
+
end
|
20
|
+
|
21
|
+
def define_attribute(name)
|
22
|
+
name = name.to_sym
|
23
|
+
self.class_eval do
|
24
|
+
define_attribute_methods [name.to_sym]
|
25
|
+
end
|
26
|
+
define_method(name) do
|
27
|
+
read_attribute(name)
|
28
|
+
end
|
29
|
+
define_method("#{name}=") do |value|
|
30
|
+
write_attribute(name, value)
|
31
|
+
end
|
32
|
+
define_method("#{name}?") do
|
33
|
+
read_attribute(name).present?
|
34
|
+
end
|
35
|
+
# store an array of defined attriubte names
|
36
|
+
attribute_names << name unless attribute_names.include?(name)
|
37
|
+
end
|
38
|
+
|
39
|
+
def attribute_names
|
40
|
+
@attribute_names ||= []
|
41
|
+
end
|
42
|
+
|
27
43
|
end
|
28
|
-
|
29
|
-
|
44
|
+
|
45
|
+
def initialize(*args)
|
46
|
+
attrs = args.extract_options!
|
47
|
+
@attributes = {}
|
48
|
+
# result set attributes?
|
49
|
+
result_set = attrs.delete(:_result_set) if attrs.has_key?(:_result_set)
|
50
|
+
# assign
|
51
|
+
if result_set.present? && result_set.is_a?(Hash)
|
52
|
+
@attributes = result_set.symbolize_keys!
|
53
|
+
self.new_record = false
|
54
|
+
end
|
55
|
+
# assign attributes
|
56
|
+
self.assign_attributes(attrs)
|
30
57
|
end
|
31
|
-
|
32
|
-
|
58
|
+
|
59
|
+
def inspect
|
60
|
+
"#{self.class.name} " + attributes.inspect
|
33
61
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
62
|
+
|
63
|
+
def assign_attributes(hash)
|
64
|
+
hash.each do |k,v|
|
65
|
+
send("#{k}=", v) if self.class.attribute_names.include?(k) && respond_to?("#{k}=")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def attributes
|
70
|
+
@attributes ||= self.class.attribute_names.inject({}){|m,k| m[k] ||= nil; m }
|
71
|
+
end
|
72
|
+
|
73
|
+
def attributes=(value)
|
74
|
+
@attributes = value.symbolize_keys! if value.is_a?(Hash)
|
75
|
+
end
|
76
|
+
|
77
|
+
def reload
|
78
|
+
return false unless primary_key?
|
79
|
+
clear_changes!
|
80
|
+
reload_attributes
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
protected
|
85
|
+
|
86
|
+
def write_attribute(attribute, value)
|
87
|
+
self.send(:"#{attribute}_will_change!") if self.attributes[:"#{attribute}"] != value
|
88
|
+
@attributes[:"#{attribute}"] = value
|
89
|
+
end
|
90
|
+
|
91
|
+
def read_attribute(attribute)
|
92
|
+
@attributes[:"#{attribute}"]
|
93
|
+
end
|
94
|
+
|
95
|
+
def attribute_changed?(attribute)
|
96
|
+
!changes[attribute.to_s].nil?
|
97
|
+
end
|
98
|
+
|
99
|
+
def clear_changes!
|
100
|
+
@previously_changed = {}
|
101
|
+
@changed_attributes.clear
|
102
|
+
end
|
103
|
+
|
104
|
+
def cycle_changes!
|
105
|
+
@previously_changed = changes
|
106
|
+
@changed_attributes.clear
|
107
|
+
end
|
108
|
+
|
53
109
|
end
|
54
|
-
# assign attributes
|
55
|
-
self.assign_attributes(attrs)
|
56
|
-
end
|
57
110
|
|
58
|
-
def inspect
|
59
|
-
"#{self.class.name} " + attributes.inspect
|
60
|
-
end
|
61
|
-
|
62
|
-
def assign_attributes(hash)
|
63
|
-
hash.each do |k,v|
|
64
|
-
send("#{k}=", v) if self.class.attribute_names.include?(k) && respond_to?("#{k}=")
|
65
111
|
end
|
66
112
|
end
|
67
|
-
|
68
|
-
def attributes
|
69
|
-
@attributes ||= self.class.attribute_names.inject({}){|m,k| m[k] ||= nil; m }
|
70
|
-
end
|
71
|
-
|
72
|
-
def attributes=(value)
|
73
|
-
@attributes = value.symbolize_keys! if value.is_a?(Hash)
|
74
|
-
end
|
75
|
-
|
76
|
-
def reload
|
77
|
-
return false unless primary_key?
|
78
|
-
clear_changes!
|
79
|
-
reload_attributes
|
80
|
-
true
|
81
|
-
end
|
82
|
-
|
83
|
-
protected
|
84
|
-
|
85
|
-
def write_attribute(attribute, value)
|
86
|
-
self.send(:"#{attribute}_will_change!") if self.attributes[:"#{attribute}"] != value
|
87
|
-
@attributes[:"#{attribute}"] = value
|
88
|
-
end
|
89
|
-
|
90
|
-
def read_attribute(attribute)
|
91
|
-
@attributes[:"#{attribute}"]
|
92
|
-
end
|
93
|
-
|
94
|
-
def attribute_changed?(attribute)
|
95
|
-
!changes[attribute.to_s].nil?
|
96
|
-
end
|
97
|
-
|
98
|
-
def clear_changes!
|
99
|
-
@previously_changed = {}
|
100
|
-
@changed_attributes.clear
|
101
|
-
end
|
102
|
-
|
103
|
-
def cycle_changes!
|
104
|
-
@previously_changed = changes
|
105
|
-
@changed_attributes.clear
|
106
|
-
end
|
107
|
-
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
112
113
|
end
|
@@ -1,36 +1,32 @@
|
|
1
1
|
require 'colorize'
|
2
2
|
|
3
3
|
module Quandl
|
4
|
-
module Cassandra
|
5
|
-
class Base
|
6
|
-
module Logging
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
super if defined?(super)
|
17
|
-
end
|
4
|
+
module Cassandra
|
5
|
+
class Base
|
6
|
+
module Logging
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def prepare(*args, &block)
|
11
|
+
statement = args.first.to_s
|
12
|
+
statement = "#{statement[0..200]} ... #{statement.length} chars" if statement.length > 200
|
13
|
+
Logger.debug(statement)
|
14
|
+
super if defined?(super)
|
15
|
+
end
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
17
|
+
def execute(*args, &block)
|
18
|
+
statement = args.first.to_s
|
19
|
+
statement = "#{statement[0..200]} ... #{statement.length} chars" if statement.length > 200
|
20
|
+
t1 = Time.now
|
21
|
+
begin
|
22
|
+
r = super if defined?(super)
|
23
|
+
ensure
|
24
|
+
Logger.debug("(#{t1.elapsed_ms}) ".blue + " #{statement}")
|
25
|
+
end
|
26
|
+
r
|
27
|
+
end
|
28
|
+
end
|
27
29
|
end
|
28
|
-
r
|
29
30
|
end
|
30
|
-
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
31
|
+
end
|
36
32
|
end
|
@@ -1,15 +1,13 @@
|
|
1
1
|
module Quandl::Cassandra::Base::Sanitization
|
2
|
-
|
3
2
|
extend ActiveSupport::Concern
|
4
|
-
|
3
|
+
|
5
4
|
module ClassMethods
|
6
|
-
|
7
5
|
def bind_primary_key(*args)
|
8
6
|
attrs = {}
|
9
7
|
primary_key.each_with_index { |k, i| attrs[k] = args[i] if args[i].present? }
|
10
8
|
attrs
|
11
9
|
end
|
12
|
-
|
10
|
+
|
13
11
|
def sanitize_attributes(attrs)
|
14
12
|
values = {}
|
15
13
|
attrs.each do |attribute, value|
|
@@ -20,18 +18,16 @@ module Quandl::Cassandra::Base::Sanitization
|
|
20
18
|
end
|
21
19
|
values
|
22
20
|
end
|
23
|
-
|
21
|
+
|
24
22
|
def sanitize_attribute(attribute, value)
|
25
23
|
# process each value
|
26
|
-
return value.
|
24
|
+
return value.map { |val| column_type(attribute).sanitize_for_cql(val) } if value.is_a?(Array)
|
27
25
|
# process value
|
28
|
-
column_type(attribute).sanitize_for_cql(
|
26
|
+
column_type(attribute).sanitize_for_cql(value)
|
29
27
|
end
|
30
|
-
|
31
28
|
end
|
32
|
-
|
29
|
+
|
33
30
|
def sanitized_attribute(attribute)
|
34
31
|
self.class.sanitize_attribute(attribute, read_attribute(attribute))
|
35
32
|
end
|
36
|
-
|
37
|
-
end
|
33
|
+
end
|