cassmap 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +108 -0
- data/Rakefile +1 -0
- data/cassmap.gemspec +34 -0
- data/lib/cassmap.rb +5 -0
- data/lib/cassmap/version.rb +3 -0
- metadata +133 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3ac34ccacfc5d09afe56514f7fa60de8d37bb315
|
4
|
+
data.tar.gz: 7f3d63ea8ea0982f74dec94f2aa45bfc7d268ca5
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6ac974dc98013fc333025b39dce7ea5d356d9ebbb6a11378cdade208340a4490bf04d7edd7b57a00615d2b258b1ec945dce596bc082788277ee7aa62c9f9ef0a
|
7
|
+
data.tar.gz: 1ae4a8e1a5d02a34a9259099333fce324087e0ff0378cdfcfb0f8388f6d4a7fb1859e274eafe9217f07195ef10d8f62bb0a0cb6f444629b9e45a6ee7dec817ab
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Ryan Svihla
|
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,108 @@
|
|
1
|
+
# Cassmap
|
2
|
+
|
3
|
+
<p><b>Consider this pre-alpha and use at your own risk. This will take at least a month to not suck.</b></p>
|
4
|
+
|
5
|
+
<p>Cassmap provides ActiveRecord like functionality with <b>full query table tracking</b> for those on Rails wishing to use
|
6
|
+
the excellent Cassandra distributed data store.
|
7
|
+
</p>
|
8
|
+
|
9
|
+
#What's query table tracking?
|
10
|
+
|
11
|
+
<p>Good Cassandra data modeling embraces the distributed nature of the database, and makes heavy use of
|
12
|
+
materialized views or as I like to refer to them "Query Tables". In this concept you denormalize your data
|
13
|
+
and model your tables after the queries you need to preform in your application. Denormalization of course has
|
14
|
+
downsides when it comes to data consistency and performance if you're making roundtrips for each table.
|
15
|
+
</p>
|
16
|
+
|
17
|
+
<p>Cassandra's api helps us solve the data consistency between query tables problem with the BATCH statment. Other
|
18
|
+
Active Record implmentations do not allow you to batch these updates easily and most people resort to hand CQL and respositories
|
19
|
+
to keep their data consisten. I aim to eliminate this boilerplate.</p>
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
### ActiveModel Implementation
|
24
|
+
|
25
|
+
I'm aiming to be as compatible as possible with ActiveRecord's in syntax, I do not believe this will be 100%
|
26
|
+
possible
|
27
|
+
|
28
|
+
In the simplest case, given a model that looks like this:
|
29
|
+
|
30
|
+
class Trade < Cassmap::Base
|
31
|
+
add_query_table :trades_by_price
|
32
|
+
end
|
33
|
+
|
34
|
+
and two tables that look like this:
|
35
|
+
|
36
|
+
CREATE TABLE trades ( id timeuuid, price decimal, quantity int, symbol text, PRIMARY KEY(id));
|
37
|
+
CREATE TABLE trades_by_price ( id timeuuid, price decimal, quantity int, symbol text, PRIMARY KEY(price));
|
38
|
+
|
39
|
+
and client code that looks like this:
|
40
|
+
|
41
|
+
#returns all trades with a price of
|
42
|
+
Trade.where( price: 100.00)
|
43
|
+
|
44
|
+
#saves data to all related query tables
|
45
|
+
#Trade.create( price: 100.00, quantity: 10, symbol: 'AA', id: UUID.timestamp_create )
|
46
|
+
|
47
|
+
<p>In more complex cases Cassmap knows when there are columns missing, and knows when there is
|
48
|
+
|
49
|
+
#### Pending important features
|
50
|
+
|
51
|
+
* Dirty Tracking
|
52
|
+
* Callback support
|
53
|
+
* Ability to apply transforms on query tables where columns are stored in a different format or is a combination of values
|
54
|
+
* Smarter handling of Where. What to do if you have two keys that overlap?
|
55
|
+
|
56
|
+
### Migrations support
|
57
|
+
|
58
|
+
<p>Typical Rails rule apply. Time format, followed by a file name that matches the class name.
|
59
|
+
|
60
|
+
#file named 2014_01_23_11_43_98_add_trades_by_minute_table_migration.rb
|
61
|
+
class AddTradesByMinuteTableMigration < Cassmap::Migration
|
62
|
+
|
63
|
+
def self.up
|
64
|
+
execute <<CQL
|
65
|
+
CREATE TABLE trades_by_price (
|
66
|
+
id timeuuid,
|
67
|
+
price decimal,
|
68
|
+
quantity int,
|
69
|
+
symbol text,
|
70
|
+
PRIMARY KEY(price));
|
71
|
+
CQL
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.down
|
75
|
+
execute "drop trades_by_price"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
after you've defined your schema files the typical Rake db commands work fine, just with cass as the parameter.
|
80
|
+
|
81
|
+
rake cass:create # creates database for environment based on cassmap.yml
|
82
|
+
rake cass:setup
|
83
|
+
rake cass:seed
|
84
|
+
rake cass:drop
|
85
|
+
rake cass:migrate
|
86
|
+
|
87
|
+
## Installation
|
88
|
+
|
89
|
+
Add this line to your application's Gemfile:
|
90
|
+
|
91
|
+
gem 'cassmap'
|
92
|
+
|
93
|
+
And then execute:
|
94
|
+
|
95
|
+
$ bundle
|
96
|
+
|
97
|
+
Or install it yourself as:
|
98
|
+
|
99
|
+
$ gem install cassmap
|
100
|
+
|
101
|
+
## Contributing
|
102
|
+
|
103
|
+
1. Fork it
|
104
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
105
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
106
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
107
|
+
5. Create new Pull Request
|
108
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/cassmap.gemspec
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'cassmap/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "cassmap"
|
8
|
+
spec.version = Cassmap::VERSION
|
9
|
+
spec.authors = ["Ryan Svihla"]
|
10
|
+
spec.email = ["rs@foundev.pro"]
|
11
|
+
spec.description = %q{Cassandra ActiveModel implementation for Rails with migrations and full query table support.}
|
12
|
+
spec.summary = <<SUMMARY
|
13
|
+
Good Cassandra data modeling embraces the distributed nature of the database, and makes heavy use of materialized views or as I like to refer to them "Query Tables". In this concept you denormalize your data and model your tables after the queries you need to preform in your application. Denormalization of course has downsides when it comes to data consistency and performance if you're making roundtrips for each table. Cassandra's api helps us solve the data consistency between query tables problem with the BATCH statment. Other Active Record implmentations do not allow you to batch these updates easily and most people resort to hand CQL and respositories to keep their data consisten. I aim to eliminate this boilerplate.
|
14
|
+
SUMMARY
|
15
|
+
spec.homepage = "https://github.com/rssvihla/cassmap"
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
spec.has_rdoc = true
|
23
|
+
spec.extra_rdoc_files = 'README.md'
|
24
|
+
|
25
|
+
spec.required_ruby_version = ">= 2.0"
|
26
|
+
spec.add_runtime_dependency "cql-rb", "~> 1.2"
|
27
|
+
spec.add_runtime_dependency "activemodel", ">= 4.0.0"
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
29
|
+
spec.add_development_dependency "rake"
|
30
|
+
spec.add_development_dependency "rspec", "~> 2.1"
|
31
|
+
|
32
|
+
spec.requirements << 'Cassandra >= 2.0.0'
|
33
|
+
|
34
|
+
end
|
data/lib/cassmap.rb
ADDED
metadata
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cassmap
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Svihla
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: cql-rb
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activemodel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.0.0
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ~>
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.1'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ~>
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.1'
|
83
|
+
description: Cassandra ActiveModel implementation for Rails with migrations and full
|
84
|
+
query table support.
|
85
|
+
email:
|
86
|
+
- rs@foundev.pro
|
87
|
+
executables: []
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files:
|
90
|
+
- README.md
|
91
|
+
files:
|
92
|
+
- .gitignore
|
93
|
+
- Gemfile
|
94
|
+
- LICENSE.txt
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- cassmap.gemspec
|
98
|
+
- lib/cassmap.rb
|
99
|
+
- lib/cassmap/version.rb
|
100
|
+
homepage: https://github.com/rssvihla/cassmap
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '2.0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements:
|
119
|
+
- Cassandra >= 2.0.0
|
120
|
+
rubyforge_project:
|
121
|
+
rubygems_version: 2.0.14
|
122
|
+
signing_key:
|
123
|
+
specification_version: 4
|
124
|
+
summary: Good Cassandra data modeling embraces the distributed nature of the database,
|
125
|
+
and makes heavy use of materialized views or as I like to refer to them "Query Tables".
|
126
|
+
In this concept you denormalize your data and model your tables after the queries
|
127
|
+
you need to preform in your application. Denormalization of course has downsides
|
128
|
+
when it comes to data consistency and performance if you're making roundtrips for
|
129
|
+
each table. Cassandra's api helps us solve the data consistency between query tables
|
130
|
+
problem with the BATCH statment. Other Active Record implmentations do not allow
|
131
|
+
you to batch these updates easily and most people resort to hand CQL and respositories
|
132
|
+
to keep their data consisten. I aim to eliminate this boilerplate.
|
133
|
+
test_files: []
|