datastax_rails 1.0.5
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/MIT-LICENSE +20 -0
- data/README.rdoc +62 -0
- data/Rakefile +34 -0
- data/config/schema.xml +266 -0
- data/config/schema.xml.erb +70 -0
- data/config/solrconfig.xml +1564 -0
- data/config/stopwords.txt +58 -0
- data/lib/datastax_rails/associations/association.rb +224 -0
- data/lib/datastax_rails/associations/association_scope.rb +25 -0
- data/lib/datastax_rails/associations/belongs_to_association.rb +64 -0
- data/lib/datastax_rails/associations/builder/association.rb +56 -0
- data/lib/datastax_rails/associations/builder/belongs_to.rb +30 -0
- data/lib/datastax_rails/associations/builder/collection_association.rb +48 -0
- data/lib/datastax_rails/associations/builder/has_and_belongs_to_many.rb +36 -0
- data/lib/datastax_rails/associations/builder/has_many.rb +54 -0
- data/lib/datastax_rails/associations/builder/has_one.rb +52 -0
- data/lib/datastax_rails/associations/builder/singular_association.rb +56 -0
- data/lib/datastax_rails/associations/collection_association.rb +274 -0
- data/lib/datastax_rails/associations/collection_proxy.rb +118 -0
- data/lib/datastax_rails/associations/has_and_belongs_to_many_association.rb +44 -0
- data/lib/datastax_rails/associations/has_many_association.rb +58 -0
- data/lib/datastax_rails/associations/has_one_association.rb +68 -0
- data/lib/datastax_rails/associations/singular_association.rb +58 -0
- data/lib/datastax_rails/associations.rb +86 -0
- data/lib/datastax_rails/attribute_methods/definition.rb +20 -0
- data/lib/datastax_rails/attribute_methods/dirty.rb +43 -0
- data/lib/datastax_rails/attribute_methods/typecasting.rb +50 -0
- data/lib/datastax_rails/attribute_methods.rb +104 -0
- data/lib/datastax_rails/base.rb +587 -0
- data/lib/datastax_rails/batches.rb +35 -0
- data/lib/datastax_rails/callbacks.rb +37 -0
- data/lib/datastax_rails/collection.rb +9 -0
- data/lib/datastax_rails/connection.rb +21 -0
- data/lib/datastax_rails/consistency.rb +33 -0
- data/lib/datastax_rails/cql/base.rb +15 -0
- data/lib/datastax_rails/cql/column_family.rb +38 -0
- data/lib/datastax_rails/cql/consistency.rb +13 -0
- data/lib/datastax_rails/cql/create_column_family.rb +63 -0
- data/lib/datastax_rails/cql/create_keyspace.rb +30 -0
- data/lib/datastax_rails/cql/delete.rb +41 -0
- data/lib/datastax_rails/cql/drop_column_family.rb +13 -0
- data/lib/datastax_rails/cql/drop_keyspace.rb +13 -0
- data/lib/datastax_rails/cql/insert.rb +53 -0
- data/lib/datastax_rails/cql/select.rb +51 -0
- data/lib/datastax_rails/cql/truncate.rb +13 -0
- data/lib/datastax_rails/cql/update.rb +68 -0
- data/lib/datastax_rails/cql/use_keyspace.rb +13 -0
- data/lib/datastax_rails/cql.rb +25 -0
- data/lib/datastax_rails/cursor.rb +90 -0
- data/lib/datastax_rails/errors.rb +16 -0
- data/lib/datastax_rails/identity/abstract_key_factory.rb +26 -0
- data/lib/datastax_rails/identity/custom_key_factory.rb +36 -0
- data/lib/datastax_rails/identity/hashed_natural_key_factory.rb +10 -0
- data/lib/datastax_rails/identity/natural_key_factory.rb +37 -0
- data/lib/datastax_rails/identity/uuid_key_factory.rb +23 -0
- data/lib/datastax_rails/identity.rb +53 -0
- data/lib/datastax_rails/log_subscriber.rb +37 -0
- data/lib/datastax_rails/migrations/migration.rb +15 -0
- data/lib/datastax_rails/migrations.rb +36 -0
- data/lib/datastax_rails/mocking.rb +15 -0
- data/lib/datastax_rails/persistence.rb +133 -0
- data/lib/datastax_rails/railtie.rb +20 -0
- data/lib/datastax_rails/reflection.rb +472 -0
- data/lib/datastax_rails/relation/finder_methods.rb +184 -0
- data/lib/datastax_rails/relation/modification_methods.rb +80 -0
- data/lib/datastax_rails/relation/search_methods.rb +349 -0
- data/lib/datastax_rails/relation/spawn_methods.rb +107 -0
- data/lib/datastax_rails/relation.rb +393 -0
- data/lib/datastax_rails/schema/migration.rb +106 -0
- data/lib/datastax_rails/schema/migration_proxy.rb +25 -0
- data/lib/datastax_rails/schema/migrator.rb +212 -0
- data/lib/datastax_rails/schema.rb +37 -0
- data/lib/datastax_rails/scoping.rb +394 -0
- data/lib/datastax_rails/serialization.rb +6 -0
- data/lib/datastax_rails/tasks/column_family.rb +162 -0
- data/lib/datastax_rails/tasks/ds.rake +63 -0
- data/lib/datastax_rails/tasks/keyspace.rb +57 -0
- data/lib/datastax_rails/timestamps.rb +19 -0
- data/lib/datastax_rails/type.rb +16 -0
- data/lib/datastax_rails/types/array_type.rb +77 -0
- data/lib/datastax_rails/types/base_type.rb +26 -0
- data/lib/datastax_rails/types/binary_type.rb +15 -0
- data/lib/datastax_rails/types/boolean_type.rb +22 -0
- data/lib/datastax_rails/types/date_type.rb +17 -0
- data/lib/datastax_rails/types/float_type.rb +18 -0
- data/lib/datastax_rails/types/integer_type.rb +18 -0
- data/lib/datastax_rails/types/string_type.rb +16 -0
- data/lib/datastax_rails/types/text_type.rb +16 -0
- data/lib/datastax_rails/types/time_type.rb +17 -0
- data/lib/datastax_rails/types.rb +9 -0
- data/lib/datastax_rails/validations/uniqueness.rb +119 -0
- data/lib/datastax_rails/validations.rb +48 -0
- data/lib/datastax_rails/version.rb +3 -0
- data/lib/datastax_rails.rb +87 -0
- data/lib/solr_no_escape.rb +28 -0
- data/spec/datastax_rails/associations/belongs_to_association_spec.rb +7 -0
- data/spec/datastax_rails/associations/has_many_association_spec.rb +37 -0
- data/spec/datastax_rails/associations_spec.rb +22 -0
- data/spec/datastax_rails/attribute_methods_spec.rb +23 -0
- data/spec/datastax_rails/base_spec.rb +15 -0
- data/spec/datastax_rails/cql/select_spec.rb +12 -0
- data/spec/datastax_rails/cql/update_spec.rb +0 -0
- data/spec/datastax_rails/relation/finder_methods_spec.rb +54 -0
- data/spec/datastax_rails/relation/modification_methods_spec.rb +41 -0
- data/spec/datastax_rails/relation/search_methods_spec.rb +117 -0
- data/spec/datastax_rails/relation/spawn_methods_spec.rb +28 -0
- data/spec/datastax_rails/relation_spec.rb +130 -0
- data/spec/datastax_rails/validations/uniqueness_spec.rb +41 -0
- data/spec/datastax_rails_spec.rb +5 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/javascripts/application.js +9 -0
- data/spec/dummy/app/assets/stylesheets/application.css +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +47 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/datastax.yml +18 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +30 -0
- data/spec/dummy/config/environments/production.rb +60 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/config/sunspot.yml +17 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/ks/migrate/20111117224534_models.rb +20 -0
- data/spec/dummy/ks/schema.json +180 -0
- data/spec/dummy/log/development.log +298 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/test.log +20307 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/datastax_test_hook.rb +14 -0
- data/spec/support/models.rb +72 -0
- metadata +353 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Consistency
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
cattr_accessor :consistency_levels
|
|
7
|
+
self.consistency_levels = [:one, :quorum, :all]
|
|
8
|
+
|
|
9
|
+
class_attribute :write_consistency
|
|
10
|
+
class_attribute :read_consistency
|
|
11
|
+
self.write_consistency = :quorum
|
|
12
|
+
self.read_consistency = :quorum
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
module ClassMethods
|
|
16
|
+
THRIFT_LEVELS = {
|
|
17
|
+
:one => 'ONE',
|
|
18
|
+
:quorum => 'QUORUM',
|
|
19
|
+
:local_quorum => 'LOCAL_QUORUM',
|
|
20
|
+
:each_quorum => 'EACH_QUORUM',
|
|
21
|
+
:all => 'ALL'
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
def thrift_read_consistency
|
|
25
|
+
THRIFT_LEVELS[read_consistency] || (raise "Invalid consistency level #{read_consistency}")
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def thrift_write_consistency
|
|
29
|
+
THRIFT_LEVELS[write_consistency] || (raise "Invalid consistency level #{write_consistency}")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Cql
|
|
3
|
+
class ColumnFamily
|
|
4
|
+
def initialize(klass)
|
|
5
|
+
@klass = klass
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def create_column_family
|
|
9
|
+
DatastaxRails::Cql::CreateColumnFamily.new(@klass.column_family)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def delete(*keys)
|
|
13
|
+
DatastaxRails::Cql::Delete.new(@klass, keys.flatten)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def insert
|
|
17
|
+
DatastaxRails::Cql::Insert.new(@klass)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def drop_column_family
|
|
21
|
+
DatastaxRails::Cql::DropColumnFamily.new(@klass.column_family)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def select(*columns)
|
|
25
|
+
columns << "*" if columns.empty?
|
|
26
|
+
DatastaxRails::Cql::Select.new(@klass, columns.flatten)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def truncate
|
|
30
|
+
DatastaxRails::Cql::Truncate.new(@klass)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def update(*keys)
|
|
34
|
+
DatastaxRails::Cql::Update.new(@klass, keys.flatten)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Cql
|
|
3
|
+
module Consistency
|
|
4
|
+
ONE = 'ONE'
|
|
5
|
+
QUORUM = 'QUORUM'
|
|
6
|
+
LOCAL_QUORUM = 'LOCAL_QUORUM'
|
|
7
|
+
EACH_QUORUM = 'EACH_QUORUM'
|
|
8
|
+
ALL = 'ALL'
|
|
9
|
+
|
|
10
|
+
VALID_CONSISTENCY_LEVELS = [ONE, QUORUM, LOCAL_QUORUM, EACH_QUORUM, ALL]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
module DatastaxRails#:nodoc:
|
|
2
|
+
module Cql #:nodoc:
|
|
3
|
+
class CreateColumnFamily < Base #:nodoc:
|
|
4
|
+
def initialize(cf_name)
|
|
5
|
+
@cf_name = cf_name
|
|
6
|
+
@columns = {}
|
|
7
|
+
@storage_parameters = {}
|
|
8
|
+
@key_type = 'uuid'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def key_type(key_type)
|
|
12
|
+
@key_type = key_type
|
|
13
|
+
self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def with(with)
|
|
17
|
+
@storage_parameters.merge!(with)
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def columns(columns)
|
|
22
|
+
@columns.merge! columns
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Migration helpers
|
|
27
|
+
def comment=(comment)
|
|
28
|
+
with("comment" => comment)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def comparator=(comp)
|
|
32
|
+
with("comparator" => comp)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def default_validation=(val)
|
|
36
|
+
with("default_validation" => val)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def column_type=(type)
|
|
40
|
+
# TODO: Ignored till CQL supports super-columns
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def to_cql
|
|
44
|
+
stmt = "CREATE COLUMNFAMILY #{@cf_name} (key #{@key_type} PRIMARY KEY"
|
|
45
|
+
@columns.each do |name,type|
|
|
46
|
+
stmt << ", #{name} #{type}"
|
|
47
|
+
end
|
|
48
|
+
stmt << ")"
|
|
49
|
+
unless @storage_parameters.empty?
|
|
50
|
+
stmt << " WITH "
|
|
51
|
+
first_parm = @storage_parameter.shift
|
|
52
|
+
stmt << "#{first_parm.first.to_s} = '#{first_parm.last.to_s}'"
|
|
53
|
+
|
|
54
|
+
@storage_parameters.each do |key, value|
|
|
55
|
+
stmt << " AND #{key.to_s} = '#{value.to_s}'"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
stmt
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module DatastaxRails#:nodoc:
|
|
2
|
+
module Cql #:nodoc:
|
|
3
|
+
class CreateKeyspace < Base #:nodoc:
|
|
4
|
+
def initialize(ks_name)
|
|
5
|
+
@ks_name = ks_name
|
|
6
|
+
@strategy_options = {}
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def strategy_class(sc)
|
|
10
|
+
@strategy_class = sc
|
|
11
|
+
self
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def strategy_options(so)
|
|
15
|
+
@strategy_options.merge!(so)
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def to_cql
|
|
20
|
+
stmt = "CREATE KEYSPACE #{@ks_name} WITH strategy_class = '#{@strategy_class}'"
|
|
21
|
+
|
|
22
|
+
@strategy_options.each do |key, value|
|
|
23
|
+
stmt << " AND strategy_options:#{key.to_s} = '#{value.to_s}'"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
stmt
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Cql
|
|
3
|
+
class Delete < Base
|
|
4
|
+
def initialize(klass, keys)
|
|
5
|
+
@klass = klass
|
|
6
|
+
@keys = keys
|
|
7
|
+
@consistency = DatastaxRails::Cql::Consistency::QUORUM
|
|
8
|
+
@timestamp = nil
|
|
9
|
+
@columns = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def using(consistency)
|
|
13
|
+
@consistency = consistency
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def columns(columns)
|
|
18
|
+
@columns = columns
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def timestamp(timestamp)
|
|
23
|
+
@timestamp = timestamp
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_cql
|
|
28
|
+
values = []
|
|
29
|
+
stmt = "DELETE #{@columns.join(',')} FROM #{@klass.column_family} USING CONSISTENCY #{@consistency} "
|
|
30
|
+
|
|
31
|
+
if(@timestamp)
|
|
32
|
+
stmt << "AND TIMESTAMP #{@timestamp} "
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
stmt << "WHERE KEY IN (?)"
|
|
36
|
+
|
|
37
|
+
CassandraCQL::Statement.sanitize(stmt, @keys)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Cql
|
|
3
|
+
class Insert < Base
|
|
4
|
+
def initialize(klass)
|
|
5
|
+
@klass = klass
|
|
6
|
+
@consistency = DatastaxRails::Cql::Consistency::QUORUM
|
|
7
|
+
@ttl = nil
|
|
8
|
+
@timestamp = nil
|
|
9
|
+
@columns = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def using(consistency)
|
|
13
|
+
@consistency = consistency
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def columns(columns)
|
|
18
|
+
@columns.merge!(columns)
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def ttl(ttl)
|
|
23
|
+
@ttl = ttl
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def timestamp(timestamp)
|
|
28
|
+
@timestamp = timestamp
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_cql
|
|
33
|
+
values = []
|
|
34
|
+
keys = []
|
|
35
|
+
@columns.each do |k,v|
|
|
36
|
+
keys << k.to_s
|
|
37
|
+
values << v
|
|
38
|
+
end
|
|
39
|
+
stmt = "INSERT INTO #{@klass.column_family} (#{keys.join(',')}) VALUES (#{('?'*keys.size).split(//).join(',')}) USING CONSISTENCY #{@consistency} "
|
|
40
|
+
|
|
41
|
+
if(@ttl)
|
|
42
|
+
stmt << "AND TTL #{@ttl} "
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if(@timestamp)
|
|
46
|
+
stmt << "AND TIMESTAMP #{@timestamp}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
CassandraCQL::Statement.sanitize(stmt, values)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module DatastaxRails#:nodoc:
|
|
2
|
+
module Cql #:nodoc:
|
|
3
|
+
class Select < Base #:nodoc:
|
|
4
|
+
def initialize(klass, select)
|
|
5
|
+
@klass = klass
|
|
6
|
+
@select = select.join(",")
|
|
7
|
+
@consistency = DatastaxRails::Cql::Consistency::QUORUM
|
|
8
|
+
@limit = nil
|
|
9
|
+
@conditions = {}
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def using(consistency)
|
|
13
|
+
@consistency = consistency
|
|
14
|
+
self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def conditions(conditions)
|
|
18
|
+
@conditions.merge!(conditions)
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def limit(limit)
|
|
23
|
+
@limit = limit
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def to_cql
|
|
28
|
+
conditions = []
|
|
29
|
+
values = []
|
|
30
|
+
stmt = "SELECT #{@select} FROM #{@klass.column_family} USING CONSISTENCY #{@consistency} "
|
|
31
|
+
@conditions.each do |k,v|
|
|
32
|
+
values << v
|
|
33
|
+
if v.kind_of?(Array)
|
|
34
|
+
conditions << "#{k.to_s} IN (?)"
|
|
35
|
+
else
|
|
36
|
+
conditions << "#{k.to_s} = ?"
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
unless conditions.empty?
|
|
41
|
+
stmt << "WHERE #{conditions.join(" AND ")} "
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if @limit
|
|
45
|
+
stmt << "LIMIT #{@limit}"
|
|
46
|
+
end
|
|
47
|
+
CassandraCQL::Statement.sanitize(stmt, values)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Cql
|
|
3
|
+
class Update < Base
|
|
4
|
+
def initialize(klass, key)
|
|
5
|
+
@klass = klass
|
|
6
|
+
@key = key
|
|
7
|
+
@consistency = DatastaxRails::Cql::Consistency::QUORUM
|
|
8
|
+
@columns = {}
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def using(consistency)
|
|
12
|
+
@consistency = consistency
|
|
13
|
+
self
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def columns(columns)
|
|
17
|
+
@columns.merge!(columns)
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def limit(limit)
|
|
22
|
+
@limit = limit
|
|
23
|
+
self
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def ttl(ttl)
|
|
27
|
+
@ttl = ttl
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def timestamp(timestamp)
|
|
32
|
+
@timestamp = timestamp
|
|
33
|
+
self
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def to_cql
|
|
37
|
+
values = []
|
|
38
|
+
|
|
39
|
+
stmt = "update #{@klass.column_family} using consistency #{@consistency} "
|
|
40
|
+
|
|
41
|
+
if(@ttl)
|
|
42
|
+
stmt << "AND TTL #{@ttl} "
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if(@timestamp)
|
|
46
|
+
stmt << "AND TIMESTAMP #{@timestamp}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
stmt << "SET "
|
|
50
|
+
|
|
51
|
+
first_entry = @columns.shift
|
|
52
|
+
|
|
53
|
+
stmt << "#{first_entry.first.to_s} = ? "
|
|
54
|
+
values << first_entry.last
|
|
55
|
+
|
|
56
|
+
@columns.each do |k,v|
|
|
57
|
+
stmt << ", #{k.to_s} = ? "
|
|
58
|
+
values << v
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
stmt << "WHERE KEY IN (?)"
|
|
62
|
+
values << @key
|
|
63
|
+
|
|
64
|
+
CassandraCQL::Statement.sanitize(stmt, values)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Cql
|
|
3
|
+
extend ActiveSupport::Autoload
|
|
4
|
+
class << self
|
|
5
|
+
def for_class(klass)
|
|
6
|
+
@cql ||= {}
|
|
7
|
+
@cql[klass] ||= DatastaxRails::Cql::ColumnFamily.new(klass)
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
autoload :Base
|
|
12
|
+
autoload :ColumnFamily
|
|
13
|
+
autoload :Consistency
|
|
14
|
+
autoload :CreateColumnFamily
|
|
15
|
+
autoload :CreateKeyspace
|
|
16
|
+
autoload :Delete
|
|
17
|
+
autoload :DropColumnFamily
|
|
18
|
+
autoload :DropKeyspace
|
|
19
|
+
autoload :Insert
|
|
20
|
+
autoload :Select
|
|
21
|
+
autoload :Truncate
|
|
22
|
+
autoload :Update
|
|
23
|
+
autoload :UseKeyspace
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
class Cursor
|
|
3
|
+
include Consistency
|
|
4
|
+
|
|
5
|
+
def initialize(target_class, column_family, key, super_column, options={})
|
|
6
|
+
@target_class = target_class
|
|
7
|
+
@column_family = column_family
|
|
8
|
+
@key = key.to_s
|
|
9
|
+
@super_column = super_column
|
|
10
|
+
@options = options
|
|
11
|
+
@validators = []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def find(number_to_find)
|
|
15
|
+
limit = number_to_find
|
|
16
|
+
objects = DatastaxRails::Collection.new
|
|
17
|
+
out_of_keys = false
|
|
18
|
+
|
|
19
|
+
if start_with = @options[:start_after]
|
|
20
|
+
limit += 1
|
|
21
|
+
else
|
|
22
|
+
start_with = nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
while objects.size < number_to_find && !out_of_keys
|
|
26
|
+
index_results = connection.get(@column_family, @key, @super_column,
|
|
27
|
+
:count => limit,
|
|
28
|
+
:start => start_with,
|
|
29
|
+
:reversed => @options[:reversed],
|
|
30
|
+
:consistency => @target_class.thrift_read_consistency)
|
|
31
|
+
|
|
32
|
+
out_of_keys = index_results.size < limit
|
|
33
|
+
|
|
34
|
+
if !start_with.blank?
|
|
35
|
+
index_results.delete(start_with)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
keys = index_results.keys
|
|
39
|
+
values = index_results.values
|
|
40
|
+
|
|
41
|
+
missing_keys = []
|
|
42
|
+
|
|
43
|
+
results = values.empty? ? {} : @target_class.multi_get(values)
|
|
44
|
+
results.each do |(key, result)|
|
|
45
|
+
if result.nil?
|
|
46
|
+
missing_keys << key
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
unless missing_keys.empty?
|
|
51
|
+
@target_class.multi_get(missing_keys, :quorum=>true).each do |(key, result)|
|
|
52
|
+
index_key = index_results.key(key)
|
|
53
|
+
if result.nil?
|
|
54
|
+
remove(index_key)
|
|
55
|
+
results.delete(key)
|
|
56
|
+
else
|
|
57
|
+
results[key] = result
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
results.values.each do |o|
|
|
63
|
+
if @validators.all? {|v| v.call(o) }
|
|
64
|
+
objects << o
|
|
65
|
+
else
|
|
66
|
+
remove(index_results.index(o.key))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
start_with = objects.last_column_name = keys.last
|
|
71
|
+
limit = (number_to_find - results.size) + 1
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
return objects
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def connection
|
|
79
|
+
@target_class.connection
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def remove(index_key)
|
|
83
|
+
connection.remove(@column_family, @key, @super_column, index_key, :consistency => @target_class.thrift_write_consistency)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def validator(&validator)
|
|
87
|
+
@validators << validator
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
class DatastaxRailsError < StandardError
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class AssociationTypeMismatch < DatastaxRailsError
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
class RecordNotSaved < DatastaxRailsError
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class DeleteRestrictionError < DatastaxRailsError
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class RecordNotFound < DatastaxRailsError
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Identity
|
|
3
|
+
# Key factories need to support 3 operations
|
|
4
|
+
class AbstractKeyFactory
|
|
5
|
+
# Next key takes an object and returns the key object it should use.
|
|
6
|
+
# object will be ignored with synthetic keys but could be useful with natural ones
|
|
7
|
+
#
|
|
8
|
+
# @param [CassandraObject::Base] the object that needs a new key
|
|
9
|
+
# @return [CassandraObject::Identity::Key] the key
|
|
10
|
+
#
|
|
11
|
+
def next_key(object)
|
|
12
|
+
raise NotImplementedError, "#{self.class.name}#next_key isn't implemented."
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Parse should create a new key object from the 'to_param' format
|
|
16
|
+
#
|
|
17
|
+
# @param [String] the result of calling key.to_param
|
|
18
|
+
# @return [CassandraObject::Identity::Key] the parsed key
|
|
19
|
+
#
|
|
20
|
+
def parse(string)
|
|
21
|
+
raise NotImplementedError, "#{self.class.name}#parse isn't implemented."
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module DatastaxRails
|
|
2
|
+
module Identity
|
|
3
|
+
class CustomKeyFactory < AbstractKeyFactory
|
|
4
|
+
class CustomKey
|
|
5
|
+
attr_reader :value
|
|
6
|
+
|
|
7
|
+
def initialize(value)
|
|
8
|
+
@value = value
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def to_s
|
|
12
|
+
value
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ==(other)
|
|
16
|
+
other.to_s == value
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
attr_reader :method
|
|
21
|
+
|
|
22
|
+
def initialize(options)
|
|
23
|
+
@method = options[:method]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def next_key(object)
|
|
27
|
+
CustomKey.new(object.send(@method))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def parse(value)
|
|
31
|
+
value
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
module DatastaxRails
|
|
3
|
+
module Identity
|
|
4
|
+
class HashedNaturalKeyFactory < NaturalKeyFactory
|
|
5
|
+
def next_key(object)
|
|
6
|
+
NaturalKey.new(Digest::SHA1.hexdigest(attributes.map { |a| object.attributes[a.to_s] }.join(separator)))
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|