quandl_cassandra 1.3.1 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|