cassandra_archive 0.2.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 +10 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +67 -0
- data/LICENSE.txt +22 -0
- data/README.md +61 -0
- data/Rakefile +11 -0
- data/cassandra_archive.gemspec +27 -0
- data/lib/cassandra_archive.rb +62 -0
- data/lib/cassandra_archive/helper.rb +17 -0
- data/lib/cassandra_archive/version.rb +4 -0
- data/test/schema.rb +7 -0
- data/test/test_helper.rb +30 -0
- data/test/unit/cassandra_archive_test.rb +105 -0
- metadata +145 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'activesupport', '~> 3'
|
4
|
+
gem 'activemodel', '~> 3'
|
5
|
+
gem 'activerecord', '~> 3'
|
6
|
+
gem 'exception_helper'
|
7
|
+
|
8
|
+
gem "cassandra", :require => 'cassandra/1.2'
|
9
|
+
gem 'active_attr', :git => "http://github.com/backupify/active_attr.git"
|
10
|
+
|
11
|
+
# Add dependencies to develop your gem here.
|
12
|
+
# Include everything needed to run rake, tests, features, etc.
|
13
|
+
group :development do
|
14
|
+
gem "shoulda"
|
15
|
+
gem "factory_girl"
|
16
|
+
gem "bundler"
|
17
|
+
gem 'mocha'
|
18
|
+
gem 'sqlite3'
|
19
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
GIT
|
2
|
+
remote: http://github.com/backupify/active_attr.git
|
3
|
+
revision: 69951a36e62bc348b6d2c86ce50c1251ad709e34
|
4
|
+
specs:
|
5
|
+
active_attr (0.8.2)
|
6
|
+
activemodel (>= 3.0.2, < 4.1)
|
7
|
+
activesupport (>= 3.0.2, < 4.1)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.2.14)
|
13
|
+
activesupport (= 3.2.14)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activerecord (3.2.14)
|
16
|
+
activemodel (= 3.2.14)
|
17
|
+
activesupport (= 3.2.14)
|
18
|
+
arel (~> 3.0.2)
|
19
|
+
tzinfo (~> 0.3.29)
|
20
|
+
activesupport (3.2.14)
|
21
|
+
i18n (~> 0.6, >= 0.6.4)
|
22
|
+
multi_json (~> 1.0)
|
23
|
+
arel (3.0.2)
|
24
|
+
builder (3.0.4)
|
25
|
+
cassandra (0.22.0)
|
26
|
+
json
|
27
|
+
rake
|
28
|
+
simple_uuid (~> 0.2.0)
|
29
|
+
thrift_client (~> 0.7, < 0.9)
|
30
|
+
exception_helper (0.1.2)
|
31
|
+
factory_girl (4.2.0)
|
32
|
+
activesupport (>= 3.0.0)
|
33
|
+
i18n (0.6.5)
|
34
|
+
json (1.8.0)
|
35
|
+
metaclass (0.0.1)
|
36
|
+
mocha (0.14.0)
|
37
|
+
metaclass (~> 0.0.1)
|
38
|
+
multi_json (1.7.9)
|
39
|
+
rake (10.1.0)
|
40
|
+
shoulda (3.5.0)
|
41
|
+
shoulda-context (~> 1.0, >= 1.0.1)
|
42
|
+
shoulda-matchers (>= 1.4.1, < 3.0)
|
43
|
+
shoulda-context (1.1.5)
|
44
|
+
shoulda-matchers (2.3.0)
|
45
|
+
activesupport (>= 3.0.0)
|
46
|
+
simple_uuid (0.2.0)
|
47
|
+
sqlite3 (1.3.8)
|
48
|
+
thrift (0.8.0)
|
49
|
+
thrift_client (0.8.4)
|
50
|
+
thrift (~> 0.8.0)
|
51
|
+
tzinfo (0.3.37)
|
52
|
+
|
53
|
+
PLATFORMS
|
54
|
+
ruby
|
55
|
+
|
56
|
+
DEPENDENCIES
|
57
|
+
active_attr!
|
58
|
+
activemodel (~> 3)
|
59
|
+
activerecord (~> 3)
|
60
|
+
activesupport (~> 3)
|
61
|
+
bundler
|
62
|
+
cassandra
|
63
|
+
exception_helper
|
64
|
+
factory_girl
|
65
|
+
mocha
|
66
|
+
shoulda
|
67
|
+
sqlite3
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Backupify
|
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,61 @@
|
|
1
|
+
# Description
|
2
|
+
|
3
|
+
The active record extension implements the archive functionality to cassandra database. After record get deleted it replicates the copy of all attributes of that object to cassandra.
|
4
|
+
|
5
|
+
# Example of usage
|
6
|
+
|
7
|
+
Before you start using library you need to create column family where archived records will be stored
|
8
|
+
|
9
|
+
create keyspace CassandraArchive_test;
|
10
|
+
create column family DeletedRecords with column_type='Super' and comparator='UTF8Type' and subcomparator='UTF8Type';
|
11
|
+
|
12
|
+
initialize cassandra connection
|
13
|
+
|
14
|
+
::CASSANDRA_CLIENT = Cassandra.new(keyspace, hosts)
|
15
|
+
|
16
|
+
and include module into model you want to archive after destroying
|
17
|
+
|
18
|
+
class Service < ActiveRecord::Base
|
19
|
+
include CassandraArchive
|
20
|
+
end
|
21
|
+
|
22
|
+
After you delete a record, it will be automatically replicated to cassandra in the following format
|
23
|
+
|
24
|
+
column_family will be 'DeletedRecords'
|
25
|
+
row_id will be the same as table name, for example above it will be 'services'
|
26
|
+
column_name is the removal timestamp, it looks like '1361974054666398'
|
27
|
+
column_attributes will contain the active record attributes
|
28
|
+
|
29
|
+
The model will be extended with :archived method
|
30
|
+
|
31
|
+
Service.archived # returns list of all archived records for that model
|
32
|
+
Service.archived(:after => 3.day.ago) # returns list of archived records for last 3 days
|
33
|
+
|
34
|
+
Service.archived do |timestamp, attributes|
|
35
|
+
# the block is called for each archived record
|
36
|
+
# timestamp shows when record has been archived
|
37
|
+
end
|
38
|
+
|
39
|
+
You may want to store the data which is not presented as active record attribute, it can be dynamic attribute or something like that. For that purpose you define :cassandra_archive_attributes method where you define the list of attributes you want to archive.
|
40
|
+
|
41
|
+
class Service < ActiveRecord::Base
|
42
|
+
include CassandraArchive
|
43
|
+
|
44
|
+
def cassandra_archive_attributes
|
45
|
+
# all active record attributes will be archived plus :account_name
|
46
|
+
attributes.keys + [:account_name]
|
47
|
+
end
|
48
|
+
|
49
|
+
def account_name
|
50
|
+
# the code here does request to the service in order to get account name
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
## Running tests
|
55
|
+
|
56
|
+
Before you run tests do this in cassandra-cli:
|
57
|
+
|
58
|
+
use CassandraArchive_test; # create it first if it doesn't exist
|
59
|
+
create column family DeletedRecords with column_type='Super' and comparator='UTF8Type' and subcomparator='UTF8Type';
|
60
|
+
|
61
|
+
then run rake
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cassandra_archive/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "cassandra_archive"
|
8
|
+
gem.version = CassandraArchive::VERSION
|
9
|
+
gem.authors = ["Alexander Litvinovsky","Jason Haruska"]
|
10
|
+
gem.email = ["dev@backupify.com"]
|
11
|
+
gem.description = "The library allows to archive destroyed record to cassandra. For that moment ActiveRecord is supported."
|
12
|
+
gem.summary = "Archiving and retrieving records to cassandra"
|
13
|
+
gem.homepage = "http://github.com/backupify/cassandra_archive"
|
14
|
+
gem.license = "MIT"
|
15
|
+
|
16
|
+
gem.add_runtime_dependency("activerecord", [">= 3.0.0"])
|
17
|
+
gem.add_runtime_dependency("cassandra", [">= 0.12.2"])
|
18
|
+
|
19
|
+
gem.add_development_dependency('sqlite3')
|
20
|
+
gem.add_development_dependency('shoulda')
|
21
|
+
gem.add_development_dependency('mocha')
|
22
|
+
|
23
|
+
gem.files = `git ls-files`.split($/)
|
24
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
25
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
26
|
+
gem.require_paths = ["lib"]
|
27
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'cassandra'
|
2
|
+
require 'active_support/concern'
|
3
|
+
|
4
|
+
require 'cassandra_archive/version'
|
5
|
+
require 'cassandra_archive/helper'
|
6
|
+
|
7
|
+
module CassandraArchive
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
|
10
|
+
included do
|
11
|
+
after_commit :on => :destroy do
|
12
|
+
archive
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def archive
|
17
|
+
time = DateTime.current
|
18
|
+
|
19
|
+
cassandra_timestamp = Helper.timestamp(time)
|
20
|
+
unix_timestamp = time.to_i.to_s
|
21
|
+
|
22
|
+
cassandra_attributes = archived_attributes.merge('archived_at' => unix_timestamp)
|
23
|
+
::CASSANDRA_CLIENT.insert('DeletedRecords', self.class.table_name, {cassandra_timestamp.to_s => cassandra_attributes})
|
24
|
+
end
|
25
|
+
|
26
|
+
def cassandra_archive_attributes
|
27
|
+
# return active record attributes by default
|
28
|
+
attributes.keys
|
29
|
+
end
|
30
|
+
|
31
|
+
def archived_attributes
|
32
|
+
cassandra_archive_attributes.inject({}) do |hash, attribute|
|
33
|
+
value = send(attribute).to_s
|
34
|
+
cassandra_encoded_value = Helper.encode_for_cassandra(value)
|
35
|
+
hash[attribute.to_s] = cassandra_encoded_value
|
36
|
+
hash
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
module ClassMethods
|
41
|
+
def archived(options = {})
|
42
|
+
if time = options.delete(:after)
|
43
|
+
options[:start] = Helper.timestamp(time).to_s
|
44
|
+
end
|
45
|
+
|
46
|
+
records = ::CASSANDRA_CLIENT.get('DeletedRecords', table_name, options)
|
47
|
+
|
48
|
+
# encode attributes to utf8
|
49
|
+
records.each_entry do |entry|
|
50
|
+
entry.last.keys.each do |key|
|
51
|
+
entry.last[key].force_encoding('UTF-8')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
if block_given?
|
56
|
+
records.each {|key, value| yield key, value}
|
57
|
+
end
|
58
|
+
|
59
|
+
records
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CassandraArchive
|
2
|
+
module Helper
|
3
|
+
def self.timestamp(time)
|
4
|
+
(time.to_f * 1_000_000).to_i
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.encode_for_cassandra(str, opts = {})
|
8
|
+
encode_opts = {
|
9
|
+
:invalid => :replace,
|
10
|
+
:undef => :replace,
|
11
|
+
:replace => ''
|
12
|
+
}.merge(opts)
|
13
|
+
|
14
|
+
str.encode('UTF-8', encode_opts).force_encoding('ASCII-8BIT')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/test/schema.rb
ADDED
data/test/test_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'mocha/setup'
|
3
|
+
require 'shoulda'
|
4
|
+
|
5
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
6
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
+
|
8
|
+
require 'cassandra_archive'
|
9
|
+
|
10
|
+
::CASSANDRA_CLIENT = Cassandra.new('CassandraArchive_test', %w[localhost:9160])
|
11
|
+
|
12
|
+
class Test::Unit::TestCase
|
13
|
+
def setup
|
14
|
+
::CASSANDRA_CLIENT.clear_keyspace!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'active_record'
|
19
|
+
|
20
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
21
|
+
load(File.dirname(__FILE__) + "/schema.rb")
|
22
|
+
|
23
|
+
# enable coverage reports for jenkins only
|
24
|
+
if ENV['CI']
|
25
|
+
puts "Enabling simplecov(rcov) for jenkins"
|
26
|
+
require 'simplecov'
|
27
|
+
require 'simplecov-rcov'
|
28
|
+
SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
|
29
|
+
SimpleCov.start
|
30
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../test_helper.rb')
|
4
|
+
|
5
|
+
class TestModel < ActiveRecord::Base
|
6
|
+
include ::CassandraArchive
|
7
|
+
|
8
|
+
def cassandra_archive_attributes
|
9
|
+
[:id, :firstname, :lastname, :fullname]
|
10
|
+
end
|
11
|
+
|
12
|
+
def fullname
|
13
|
+
"#{firstname} #{lastname}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class CassandraArchiveTest < Test::Unit::TestCase
|
18
|
+
context 'archived' do
|
19
|
+
setup do
|
20
|
+
@record = TestModel.create(:firstname => "firstname", :lastname => "lastname")
|
21
|
+
@record.destroy
|
22
|
+
end
|
23
|
+
|
24
|
+
should 'archive record to cassandra after record destroying' do
|
25
|
+
archived_record = find_archived_record(@record)
|
26
|
+
|
27
|
+
assert_equal @record.id.to_s, archived_record['id']
|
28
|
+
assert_equal @record.firstname, archived_record['firstname']
|
29
|
+
assert_equal @record.lastname, archived_record['lastname']
|
30
|
+
assert_equal @record.fullname, archived_record['fullname']
|
31
|
+
|
32
|
+
# we didn't list created_at attribute in cassandra_archive_attributes method, so it should not be archived
|
33
|
+
assert_equal nil, archived_record['created_at']
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'archive record if attributes contain not ASCII chars' do
|
37
|
+
@record = TestModel.create(:firstname => "Иван", :lastname => "Иванов")
|
38
|
+
@record.destroy
|
39
|
+
|
40
|
+
archived_record = find_archived_record(@record)
|
41
|
+
|
42
|
+
assert_equal @record.id.to_s, archived_record['id']
|
43
|
+
assert_equal @record.firstname, archived_record['firstname']
|
44
|
+
assert_equal @record.lastname, archived_record['lastname']
|
45
|
+
assert_equal @record.fullname, archived_record['fullname']
|
46
|
+
|
47
|
+
# we didn't list created_at attribute in cassandra_archive_attributes method, so it should not be archived
|
48
|
+
assert_equal nil, archived_record['created_at']
|
49
|
+
end
|
50
|
+
|
51
|
+
should 'set archived_at attribute' do
|
52
|
+
time = DateTime.current
|
53
|
+
DateTime.stubs(:current).returns(time)
|
54
|
+
|
55
|
+
archived_at = time.to_i.to_s
|
56
|
+
|
57
|
+
record = TestModel.create(:firstname => "firstname", :lastname => "lastname")
|
58
|
+
record.destroy
|
59
|
+
|
60
|
+
archived_record = find_archived_record(@record)
|
61
|
+
assert_equal archived_at, archived_record['archived_at']
|
62
|
+
end
|
63
|
+
|
64
|
+
should 'return the number of archived records' do
|
65
|
+
assert_equal 1, TestModel.archived.size
|
66
|
+
|
67
|
+
another_record = TestModel.create(:firstname => "firstname", :lastname => "lastname")
|
68
|
+
another_record.destroy
|
69
|
+
|
70
|
+
assert_equal 2, TestModel.archived.size
|
71
|
+
end
|
72
|
+
|
73
|
+
should 'return records archived after specified date if :after option is passed as timestamp' do
|
74
|
+
assert_equal 1, TestModel.archived(:after => @record.created_at.to_i).size
|
75
|
+
end
|
76
|
+
|
77
|
+
should 'return records archived after specified date if :after option is passed via rails helper' do
|
78
|
+
assert_equal 1, TestModel.archived(:after => 10.seconds.ago).size
|
79
|
+
assert_equal 0, TestModel.archived(:after => 10.seconds.since(DateTime.current)).size
|
80
|
+
end
|
81
|
+
|
82
|
+
should 'go through each archived record if block passed' do
|
83
|
+
TestModel.archived do |timestamp, attributes|
|
84
|
+
assert_equal @record.id.to_s, attributes['id']
|
85
|
+
assert_equal @record.firstname, attributes['firstname']
|
86
|
+
assert_equal @record.lastname, attributes['lastname']
|
87
|
+
assert_equal @record.fullname, attributes['fullname']
|
88
|
+
|
89
|
+
# we didn't list created_at attribute in cassandra_archive_attributes method, so it should not be archived
|
90
|
+
assert_equal nil, attributes['created_at']
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_archived_record(record)
|
96
|
+
# find archived record, it returns array with two elements
|
97
|
+
# first element is key, second is hash with attributes
|
98
|
+
archived_record = record.class.archived.find do |key, value|
|
99
|
+
value['id'] == record.id.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
# return record attributes
|
103
|
+
archived_record.last
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cassandra_archive
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Alexander Litvinovsky
|
9
|
+
- Jason Haruska
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2013-09-06 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
type: :runtime
|
17
|
+
name: activerecord
|
18
|
+
prerelease: false
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ! '>='
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 3.0.0
|
24
|
+
none: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.0.0
|
30
|
+
none: false
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
type: :runtime
|
33
|
+
name: cassandra
|
34
|
+
prerelease: false
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ! '>='
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 0.12.2
|
40
|
+
none: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.12.2
|
46
|
+
none: false
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
type: :development
|
49
|
+
name: sqlite3
|
50
|
+
prerelease: false
|
51
|
+
requirement: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
none: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
none: false
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
type: :development
|
65
|
+
name: shoulda
|
66
|
+
prerelease: false
|
67
|
+
requirement: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
none: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
none: false
|
79
|
+
- !ruby/object:Gem::Dependency
|
80
|
+
type: :development
|
81
|
+
name: mocha
|
82
|
+
prerelease: false
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
none: false
|
89
|
+
version_requirements: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
none: false
|
95
|
+
description: The library allows to archive destroyed record to cassandra. For that
|
96
|
+
moment ActiveRecord is supported.
|
97
|
+
email:
|
98
|
+
- dev@backupify.com
|
99
|
+
executables: []
|
100
|
+
extensions: []
|
101
|
+
extra_rdoc_files: []
|
102
|
+
files:
|
103
|
+
- .gitignore
|
104
|
+
- Gemfile
|
105
|
+
- Gemfile.lock
|
106
|
+
- LICENSE.txt
|
107
|
+
- README.md
|
108
|
+
- Rakefile
|
109
|
+
- cassandra_archive.gemspec
|
110
|
+
- lib/cassandra_archive.rb
|
111
|
+
- lib/cassandra_archive/helper.rb
|
112
|
+
- lib/cassandra_archive/version.rb
|
113
|
+
- test/schema.rb
|
114
|
+
- test/test_helper.rb
|
115
|
+
- test/unit/cassandra_archive_test.rb
|
116
|
+
homepage: http://github.com/backupify/cassandra_archive
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
post_install_message:
|
120
|
+
rdoc_options: []
|
121
|
+
require_paths:
|
122
|
+
- lib
|
123
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
none: false
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
none: false
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 1.8.23
|
138
|
+
signing_key:
|
139
|
+
specification_version: 3
|
140
|
+
summary: Archiving and retrieving records to cassandra
|
141
|
+
test_files:
|
142
|
+
- test/schema.rb
|
143
|
+
- test/test_helper.rb
|
144
|
+
- test/unit/cassandra_archive_test.rb
|
145
|
+
has_rdoc:
|