extendi-cassandra_object 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/.travis.yml +23 -0
- data/CHANGELOG +0 -0
- data/Gemfile +17 -0
- data/LICENSE +13 -0
- data/MIT-LICENSE +20 -0
- data/README.md +177 -0
- data/Rakefile +12 -0
- data/extendi-cassandra_object.gemspec +26 -0
- data/lib/cassandra_object.rb +73 -0
- data/lib/cassandra_object/adapters/abstract_adapter.rb +61 -0
- data/lib/cassandra_object/adapters/cassandra_adapter.rb +269 -0
- data/lib/cassandra_object/adapters/cassandra_schemaless_adapter.rb +306 -0
- data/lib/cassandra_object/attribute_methods.rb +96 -0
- data/lib/cassandra_object/attribute_methods/definition.rb +22 -0
- data/lib/cassandra_object/attribute_methods/dirty.rb +36 -0
- data/lib/cassandra_object/attribute_methods/primary_key.rb +25 -0
- data/lib/cassandra_object/attribute_methods/typecasting.rb +59 -0
- data/lib/cassandra_object/base.rb +33 -0
- data/lib/cassandra_object/base_schema.rb +11 -0
- data/lib/cassandra_object/base_schemaless.rb +11 -0
- data/lib/cassandra_object/base_schemaless_dynamic.rb +11 -0
- data/lib/cassandra_object/belongs_to.rb +63 -0
- data/lib/cassandra_object/belongs_to/association.rb +49 -0
- data/lib/cassandra_object/belongs_to/builder.rb +40 -0
- data/lib/cassandra_object/belongs_to/reflection.rb +30 -0
- data/lib/cassandra_object/callbacks.rb +29 -0
- data/lib/cassandra_object/core.rb +63 -0
- data/lib/cassandra_object/errors.rb +10 -0
- data/lib/cassandra_object/identity.rb +26 -0
- data/lib/cassandra_object/inspect.rb +25 -0
- data/lib/cassandra_object/log_subscriber.rb +44 -0
- data/lib/cassandra_object/model.rb +60 -0
- data/lib/cassandra_object/persistence.rb +203 -0
- data/lib/cassandra_object/railtie.rb +33 -0
- data/lib/cassandra_object/railties/controller_runtime.rb +45 -0
- data/lib/cassandra_object/schema.rb +83 -0
- data/lib/cassandra_object/schemaless.rb +83 -0
- data/lib/cassandra_object/scope.rb +86 -0
- data/lib/cassandra_object/scope/finder_methods.rb +54 -0
- data/lib/cassandra_object/scope/query_methods.rb +69 -0
- data/lib/cassandra_object/scoping.rb +27 -0
- data/lib/cassandra_object/serialization.rb +6 -0
- data/lib/cassandra_object/tasks/ks.rake +54 -0
- data/lib/cassandra_object/timestamps.rb +19 -0
- data/lib/cassandra_object/type.rb +16 -0
- data/lib/cassandra_object/types.rb +8 -0
- data/lib/cassandra_object/types/array_type.rb +16 -0
- data/lib/cassandra_object/types/base_type.rb +26 -0
- data/lib/cassandra_object/types/boolean_type.rb +20 -0
- data/lib/cassandra_object/types/date_type.rb +22 -0
- data/lib/cassandra_object/types/float_type.rb +16 -0
- data/lib/cassandra_object/types/integer_type.rb +20 -0
- data/lib/cassandra_object/types/json_type.rb +13 -0
- data/lib/cassandra_object/types/string_type.rb +19 -0
- data/lib/cassandra_object/types/time_type.rb +16 -0
- data/lib/cassandra_object/types/type_helper.rb +39 -0
- data/lib/cassandra_object/validations.rb +44 -0
- data/test/support/cassandra.rb +63 -0
- data/test/support/issue.rb +12 -0
- data/test/support/issue_dynamic.rb +12 -0
- data/test/support/issue_schema.rb +17 -0
- data/test/support/issue_schema_child.rb +17 -0
- data/test/support/issue_schema_father.rb +13 -0
- data/test/test_helper.rb +41 -0
- data/test/unit/active_model_test.rb +18 -0
- data/test/unit/adapters/adapter_test.rb +6 -0
- data/test/unit/attribute_methods/definition_test.rb +13 -0
- data/test/unit/attribute_methods/dirty_test.rb +72 -0
- data/test/unit/attribute_methods/primary_key_test.rb +26 -0
- data/test/unit/attribute_methods/typecasting_test.rb +119 -0
- data/test/unit/attribute_methods_test.rb +51 -0
- data/test/unit/base_test.rb +20 -0
- data/test/unit/belongs_to/reflection_test.rb +12 -0
- data/test/unit/belongs_to_test.rb +63 -0
- data/test/unit/callbacks_test.rb +46 -0
- data/test/unit/connection_test.rb +6 -0
- data/test/unit/connections/connections_test.rb +55 -0
- data/test/unit/core_test.rb +55 -0
- data/test/unit/identity_test.rb +26 -0
- data/test/unit/inspect_test.rb +26 -0
- data/test/unit/log_subscriber_test.rb +25 -0
- data/test/unit/persistence_schema_test.rb +156 -0
- data/test/unit/persistence_test.rb +266 -0
- data/test/unit/railties/controller_runtime_test.rb +48 -0
- data/test/unit/schema/tasks_test.rb +32 -0
- data/test/unit/schema_test.rb +115 -0
- data/test/unit/schemaless_test.rb +100 -0
- data/test/unit/scope/finder_methods_test.rb +117 -0
- data/test/unit/scope/query_methods_test.rb +32 -0
- data/test/unit/scoping_test.rb +7 -0
- data/test/unit/timestamps_test.rb +27 -0
- data/test/unit/types/array_type_test.rb +17 -0
- data/test/unit/types/base_type_test.rb +19 -0
- data/test/unit/types/boolean_type_test.rb +24 -0
- data/test/unit/types/date_type_test.rb +15 -0
- data/test/unit/types/float_type_test.rb +17 -0
- data/test/unit/types/integer_type_test.rb +19 -0
- data/test/unit/types/json_type_test.rb +23 -0
- data/test/unit/types/string_type_test.rb +25 -0
- data/test/unit/types/time_type_test.rb +14 -0
- data/test/unit/validations_test.rb +27 -0
- metadata +202 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Scoping
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
singleton_class.class_eval do
|
7
|
+
delegate :find, :find_by_id, :find_all_in_batches, :first, to: :scope
|
8
|
+
delegate :select, :where, :where_ids, to: :scope
|
9
|
+
delegate :cql_response, :columns, :limit, :per_page, to: :scope
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
def scope
|
15
|
+
self.current_scope ||= Scope.new(self)
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_scope
|
19
|
+
Thread.current["#{self}_current_scope"]
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_scope=(new_scope)
|
23
|
+
Thread.current["#{self}_current_scope"] = new_scope
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
ks_namespace = namespace :ks do
|
2
|
+
desc 'Create the keyspace in config/cassandra.yml for the current environment'
|
3
|
+
task create: :environment do
|
4
|
+
begin
|
5
|
+
CassandraObject::Schema.create_keyspace CassandraObject::Base.config[:keyspace], CassandraObject::Base.config[:keyspace_options]
|
6
|
+
rescue Exception => e
|
7
|
+
if e.message =~ /conflicts/
|
8
|
+
p "Keyspace #{CassandraObject::Base.config[:keyspace]} already exists"
|
9
|
+
else
|
10
|
+
raise e
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
task drop: :environment do
|
16
|
+
begin
|
17
|
+
CassandraObject::Schema.drop_keyspace CassandraObject::Base.config[:keyspace]
|
18
|
+
rescue Exception => e
|
19
|
+
if e.message =~ /non existing keyspace/
|
20
|
+
p "Keyspace #{CassandraObject::Base.config[:keyspace]} does not exist"
|
21
|
+
else
|
22
|
+
raise e
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
task reset: [:drop, :setup]
|
28
|
+
|
29
|
+
task setup: [:create, :_load]
|
30
|
+
|
31
|
+
namespace :structure do
|
32
|
+
task dump: :environment do
|
33
|
+
filename = ENV['SCHEMA'] || "#{Rails.root}/ks/structure.cql"
|
34
|
+
File.open(filename, "w:utf-8") do |file|
|
35
|
+
CassandraObject::Schema.dump(file)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
task load: :environment do
|
40
|
+
filename = ENV['SCHEMA'] || "#{Rails.root}/ks/structure.cql"
|
41
|
+
File.open(filename) do |file|
|
42
|
+
CassandraObject::Schema.load(file)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
task :_dump do
|
48
|
+
ks_namespace["structure:dump"].invoke
|
49
|
+
end
|
50
|
+
|
51
|
+
task :_load do
|
52
|
+
ks_namespace["structure:load"].invoke
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Timestamps
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
attribute :created_at, type: :time
|
7
|
+
attribute :updated_at, type: :time
|
8
|
+
|
9
|
+
before_create do
|
10
|
+
self.created_at ||= Time.current
|
11
|
+
self.updated_at ||= Time.current
|
12
|
+
end
|
13
|
+
|
14
|
+
before_update if: :changed? do
|
15
|
+
self.updated_at = Time.current
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
class Type
|
3
|
+
cattr_accessor :attribute_types
|
4
|
+
self.attribute_types = {}.with_indifferent_access
|
5
|
+
|
6
|
+
class << self
|
7
|
+
def register(name, coder)
|
8
|
+
attribute_types[name] = coder
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_coder(name)
|
12
|
+
attribute_types[name]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
CassandraObject::Type.register(:array, CassandraObject::Types::ArrayType)
|
2
|
+
CassandraObject::Type.register(:boolean, CassandraObject::Types::BooleanType)
|
3
|
+
CassandraObject::Type.register(:date, CassandraObject::Types::DateType)
|
4
|
+
CassandraObject::Type.register(:float, CassandraObject::Types::FloatType)
|
5
|
+
CassandraObject::Type.register(:integer, CassandraObject::Types::IntegerType)
|
6
|
+
CassandraObject::Type.register(:json, CassandraObject::Types::JsonType)
|
7
|
+
CassandraObject::Type.register(:time, CassandraObject::Types::TimeType)
|
8
|
+
CassandraObject::Type.register(:string, CassandraObject::Types::StringType)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class ArrayType < BaseType
|
4
|
+
def encode(array)
|
5
|
+
raise ArgumentError.new("#{array.inspect} is not an Array") unless array.kind_of?(Array)
|
6
|
+
array.to_a.to_json
|
7
|
+
end
|
8
|
+
|
9
|
+
def decode(str)
|
10
|
+
return nil if str.blank?
|
11
|
+
|
12
|
+
ActiveSupport::JSON.decode(str)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class BaseType
|
4
|
+
attr_accessor :options
|
5
|
+
def initialize(options = {})
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def default
|
10
|
+
options[:default].duplicable? ? options[:default].dup : options[:default]
|
11
|
+
end
|
12
|
+
|
13
|
+
def encode(value)
|
14
|
+
value.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def decode(str)
|
18
|
+
str
|
19
|
+
end
|
20
|
+
|
21
|
+
def typecast(value)
|
22
|
+
value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class BooleanType < BaseType
|
4
|
+
TRUE_VALS = [true, 'true', '1']
|
5
|
+
FALSE_VALS = [false, 'false', '0', '', nil]
|
6
|
+
VALID_VALS = TRUE_VALS + FALSE_VALS
|
7
|
+
|
8
|
+
def encode(bool)
|
9
|
+
unless VALID_VALS.include?(bool)
|
10
|
+
raise ArgumentError.new("#{bool.inspect} is not a Boolean")
|
11
|
+
end
|
12
|
+
TRUE_VALS.include?(bool) ? '1' : '0'
|
13
|
+
end
|
14
|
+
|
15
|
+
def decode(str)
|
16
|
+
TRUE_VALS.include?(str)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class DateType < BaseType
|
4
|
+
FORMAT = '%Y-%m-%d'
|
5
|
+
REGEX = /\A\d{4}-\d{2}-\d{2}\Z/
|
6
|
+
|
7
|
+
def encode(value)
|
8
|
+
raise ArgumentError.new("#{value.inspect} is not a Date") unless value.kind_of?(Date)
|
9
|
+
value.strftime(FORMAT)
|
10
|
+
end
|
11
|
+
|
12
|
+
def decode(str)
|
13
|
+
return nil if str.empty?
|
14
|
+
Date.parse(str)
|
15
|
+
end
|
16
|
+
|
17
|
+
def typecast(value)
|
18
|
+
value.to_date
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class FloatType < BaseType
|
4
|
+
REGEX = /\A[-+]?\d+(\.\d+)?\Z/
|
5
|
+
def encode(float)
|
6
|
+
raise ArgumentError.new("#{float.inspect} is not a Float") unless float.kind_of?(Float)
|
7
|
+
float.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def decode(str)
|
11
|
+
return nil if str.empty?
|
12
|
+
str.to_f
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class IntegerType < BaseType
|
4
|
+
REGEX = /\A[-+]?\d+\Z/
|
5
|
+
def encode(int)
|
6
|
+
raise ArgumentError.new("#{int.inspect} is not an Integer.") unless int.kind_of?(Integer)
|
7
|
+
int.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def decode(str)
|
11
|
+
return nil if str.empty?
|
12
|
+
str.to_i
|
13
|
+
end
|
14
|
+
|
15
|
+
def typecast(value)
|
16
|
+
value.to_i
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class StringType < BaseType
|
4
|
+
def encode(str)
|
5
|
+
raise ArgumentError.new("#{str.inspect} is not a String") unless str.kind_of?(String)
|
6
|
+
|
7
|
+
unless str.encoding == Encoding::UTF_8
|
8
|
+
(str.frozen? ? str.dup : str).force_encoding('UTF-8')
|
9
|
+
else
|
10
|
+
str
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def typecast(value)
|
15
|
+
value.to_s
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class TimeType < BaseType
|
4
|
+
def encode(time)
|
5
|
+
raise ArgumentError.new("#{time.inspect} is not a Time") unless time.kind_of?(Time)
|
6
|
+
time.utc.xmlschema(6)
|
7
|
+
end
|
8
|
+
|
9
|
+
def decode(str)
|
10
|
+
Time.parse(str).utc.in_time_zone if str
|
11
|
+
rescue
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
module Types
|
3
|
+
class TypeHelper
|
4
|
+
|
5
|
+
def self.guess_type(object)
|
6
|
+
case object
|
7
|
+
when ::String then Cassandra::Types.varchar
|
8
|
+
when ::Fixnum then Cassandra::Types.int
|
9
|
+
when ::Integer then Cassandra::Types.int
|
10
|
+
when ::Float then Cassandra::Types.float
|
11
|
+
when ::Bignum then Cassandra::Types.varint
|
12
|
+
when ::BigDecimal then Cassandra::Types.decimal
|
13
|
+
when ::TrueClass then Cassandra::Types.boolean
|
14
|
+
when ::FalseClass then Cassandra::Types.boolean
|
15
|
+
when ::NilClass then Cassandra::Types.bigint
|
16
|
+
# when Uuid then Cassandra::Types.uuid
|
17
|
+
# when TimeUuid then Cassandra::Types.timeuuid
|
18
|
+
when ::IPAddr then Cassandra::Types.inet
|
19
|
+
when ::Time then Cassandra::Types.timestamp
|
20
|
+
when ::Hash
|
21
|
+
pair = object.first
|
22
|
+
Types.map(guess_type(pair[0]), guess_type(pair[1]))
|
23
|
+
when ::Array then Types.list(guess_type(object.first))
|
24
|
+
when ::Set then Types.set(guess_type(object.first))
|
25
|
+
# when Tuple::Strict then Types.tuple(*object.types)
|
26
|
+
# when Tuple then Types.tuple(*object.map {|v| guess_type(v)})
|
27
|
+
# when UDT::Strict
|
28
|
+
# Types.udt(object.keyspace, object.name, object.types)
|
29
|
+
# when UDT
|
30
|
+
# Types.udt('unknown', 'unknown', object.map {|k, v| [k, guess_type(v)]})
|
31
|
+
when Cassandra::CustomData then object.class.type
|
32
|
+
else
|
33
|
+
raise ::ArgumentError, "Unable to guess the type of the argument: #{object.inspect}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module CassandraObject
|
2
|
+
class RecordInvalid < StandardError
|
3
|
+
attr_reader :record
|
4
|
+
def initialize(record)
|
5
|
+
@record = record
|
6
|
+
super("Invalid record: #{@record.errors.full_messages.to_sentence}")
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Validations
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
include ActiveModel::Validations
|
13
|
+
|
14
|
+
included do
|
15
|
+
define_callbacks :validate, scope: :name
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def create!(attributes = {})
|
20
|
+
new(attributes).tap do |object|
|
21
|
+
object.save!
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def save(options={})
|
27
|
+
if perform_validations(options)
|
28
|
+
super
|
29
|
+
true
|
30
|
+
else
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def save!
|
36
|
+
save || raise(RecordInvalid.new(self))
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
def perform_validations(options={})
|
41
|
+
(options[:validate] != false) ? valid? : true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
Bundler.require :cassandra
|
2
|
+
|
3
|
+
CassandraObject::Base.config = {
|
4
|
+
keyspace: 'cassandra_object_test',
|
5
|
+
hosts: ['127.0.0.1'],
|
6
|
+
compression: :lz4,
|
7
|
+
connect_timeout: 1,
|
8
|
+
timeout: 30,
|
9
|
+
consistency: :quorum,
|
10
|
+
protocol_version: 3,
|
11
|
+
page_size: 10000,
|
12
|
+
trace: true,
|
13
|
+
connections_per_local_node: 4,
|
14
|
+
schema_refresh_delay: 0.1,
|
15
|
+
schema_refresh_timeout: 0.1,
|
16
|
+
# connections_per_remote_node: nil,
|
17
|
+
# logger: Logger.new($stderr)
|
18
|
+
}
|
19
|
+
|
20
|
+
begin
|
21
|
+
CassandraObject::Schema.drop_keyspace 'cassandra_object_test', true
|
22
|
+
CassandraObject::Schema.drop_keyspace 'blah', true
|
23
|
+
rescue Exception => e
|
24
|
+
puts e.message
|
25
|
+
end
|
26
|
+
|
27
|
+
sleep 1
|
28
|
+
CassandraObject::Schema.create_keyspace 'cassandra_object_test'
|
29
|
+
CassandraObject::Schemaless.create_column_family 'Issues'
|
30
|
+
CassandraObject::Schema.create_column_family 'IssueSchemas', {attributes: 'id text, title text, description text, field float, intero int, created_at timestamp, updated_at timestamp, PRIMARY KEY (id)', options: {}}
|
31
|
+
CassandraObject::Schemaless.create_column_family 'IssueDynamics'
|
32
|
+
CassandraObject::Schema.create_column_family 'IssueSchemaFathers', {attributes: 'id text, title text, field float, created_at timestamp, updated_at timestamp, PRIMARY KEY (id)', options: {}}
|
33
|
+
CassandraObject::Schema.create_column_family 'IssueSchemaChildren', {attributes: 'id text, title text, description text, field float, created_at timestamp, updated_at timestamp, issue_schema_father_id text, PRIMARY KEY (id)', options: {}}
|
34
|
+
CassandraObject::BaseSchemaless.adapter.consistency = :quorum
|
35
|
+
CassandraObject::BaseSchemalessDynamic.adapter.consistency = :quorum
|
36
|
+
CassandraObject::BaseSchema.adapter.consistency = :quorum
|
37
|
+
|
38
|
+
CassandraObject::Base.class_eval do
|
39
|
+
class_attribute :created_records
|
40
|
+
self.created_records = []
|
41
|
+
|
42
|
+
after_create do
|
43
|
+
created_records << self
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.delete_after_test
|
47
|
+
# created_records.reject(&:destroyed?).each(&:destroy)
|
48
|
+
Issue.delete_all
|
49
|
+
IssueSchema.delete_all
|
50
|
+
IssueDynamic.delete_all
|
51
|
+
created_records.clear
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
module ActiveSupport
|
56
|
+
class TestCase
|
57
|
+
teardown do
|
58
|
+
if CassandraObject::Base.created_records.any?
|
59
|
+
CassandraObject::Base.delete_after_test
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|