cql-model 0.3.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/.ruby-version +1 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +56 -0
- data/README.md +24 -0
- data/Rakefile +54 -0
- data/VERSION +1 -0
- data/cql-model.gemspec +85 -0
- data/cql_model.rconf +11 -0
- data/lib/cql/model.rb +49 -0
- data/lib/cql/model/class_methods.rb +178 -0
- data/lib/cql/model/instance_methods.rb +50 -0
- data/lib/cql/model/query.rb +107 -0
- data/lib/cql/model/query/comparison_expression.rb +126 -0
- data/lib/cql/model/query/expression.rb +5 -0
- data/lib/cql/model/query/insert_statement.rb +51 -0
- data/lib/cql/model/query/mutation_statement.rb +48 -0
- data/lib/cql/model/query/select_statement.rb +143 -0
- data/lib/cql/model/query/statement.rb +44 -0
- data/lib/cql/model/query/update_expression.rb +104 -0
- data/lib/cql/model/query/update_statement.rb +91 -0
- metadata +227 -0
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p392
|
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
# Runtime dependencies
|
4
|
+
gem "cql-rb", "~> 1.0.0.pre4"
|
5
|
+
|
6
|
+
# Gems used during test and development
|
7
|
+
group :development do
|
8
|
+
gem "rake", "~> 0.9"
|
9
|
+
gem "rspec", "~> 2.0"
|
10
|
+
gem "cucumber", "~> 1.0"
|
11
|
+
gem "jeweler", "~> 1.8.3"
|
12
|
+
gem "debugger"
|
13
|
+
gem "rdoc", ">= 2.4.2"
|
14
|
+
gem "flexmock", "~> 0.8"
|
15
|
+
gem "syntax", "~> 1.0.0" #rspec will syntax-highlight code snippets if this gem is available
|
16
|
+
gem "nokogiri", "~> 1.5"
|
17
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
builder (3.1.4)
|
5
|
+
columnize (0.3.6)
|
6
|
+
cql-rb (1.0.0.pre4)
|
7
|
+
cucumber (1.2.1)
|
8
|
+
builder (>= 2.1.2)
|
9
|
+
diff-lcs (>= 1.1.3)
|
10
|
+
gherkin (~> 2.11.0)
|
11
|
+
json (>= 1.4.6)
|
12
|
+
debugger (1.5.0)
|
13
|
+
columnize (>= 0.3.1)
|
14
|
+
debugger-linecache (~> 1.2.0)
|
15
|
+
debugger-ruby_core_source (~> 1.2.0)
|
16
|
+
debugger-linecache (1.2.0)
|
17
|
+
debugger-ruby_core_source (1.2.0)
|
18
|
+
diff-lcs (1.1.3)
|
19
|
+
flexmock (0.9.0)
|
20
|
+
gherkin (2.11.6)
|
21
|
+
json (>= 1.7.6)
|
22
|
+
git (1.2.5)
|
23
|
+
jeweler (1.8.4)
|
24
|
+
bundler (~> 1.0)
|
25
|
+
git (>= 1.2.5)
|
26
|
+
rake
|
27
|
+
rdoc
|
28
|
+
json (1.7.7)
|
29
|
+
nokogiri (1.5.9)
|
30
|
+
rake (0.9.6)
|
31
|
+
rdoc (4.0.1)
|
32
|
+
json (~> 1.4)
|
33
|
+
rspec (2.12.0)
|
34
|
+
rspec-core (~> 2.12.0)
|
35
|
+
rspec-expectations (~> 2.12.0)
|
36
|
+
rspec-mocks (~> 2.12.0)
|
37
|
+
rspec-core (2.12.2)
|
38
|
+
rspec-expectations (2.12.1)
|
39
|
+
diff-lcs (~> 1.1.3)
|
40
|
+
rspec-mocks (2.12.2)
|
41
|
+
syntax (1.0.0)
|
42
|
+
|
43
|
+
PLATFORMS
|
44
|
+
ruby
|
45
|
+
|
46
|
+
DEPENDENCIES
|
47
|
+
cql-rb (~> 1.0.0.pre4)
|
48
|
+
cucumber (~> 1.0)
|
49
|
+
debugger
|
50
|
+
flexmock (~> 0.8)
|
51
|
+
jeweler (~> 1.8.3)
|
52
|
+
nokogiri (~> 1.5)
|
53
|
+
rake (~> 0.9)
|
54
|
+
rdoc (>= 2.4.2)
|
55
|
+
rspec (~> 2.0)
|
56
|
+
syntax (~> 1.0.0)
|
data/README.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Overview
|
2
|
+
========
|
3
|
+
|
4
|
+
[](https://travis-ci.org/xeger/cql-model)
|
5
|
+
|
6
|
+
TODO
|
7
|
+
|
8
|
+
To-Do List
|
9
|
+
==========
|
10
|
+
|
11
|
+
## Features
|
12
|
+
|
13
|
+
* Add support for Time and other obvious Cassandra data types
|
14
|
+
* Using-keyspace override
|
15
|
+
* Declaration, read and write of set/list/map properties
|
16
|
+
* Batch mutations
|
17
|
+
* Notation for composite partition key (CompositeType), e.g. `primary_key [:id, :surname], :first_name`
|
18
|
+
* Prepared statement support for SELECT & named scopes
|
19
|
+
* Prepared statement support for INSERT/UPDATE
|
20
|
+
|
21
|
+
## Usability / Correctness / Performance
|
22
|
+
|
23
|
+
* Better solution for using and switching namespaces -- thread/fiber safety
|
24
|
+
* Better use of cql-rb connection pooling
|
data/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*-ruby-*-
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
|
5
|
+
require 'rake'
|
6
|
+
require 'rdoc/task'
|
7
|
+
require 'rubygems/package_task'
|
8
|
+
|
9
|
+
require 'rake/clean'
|
10
|
+
require 'rspec/core/rake_task'
|
11
|
+
require 'cucumber/rake/task'
|
12
|
+
|
13
|
+
require 'jeweler'
|
14
|
+
|
15
|
+
task :default => [:cucumber, :spec]
|
16
|
+
|
17
|
+
desc "Run unit tests"
|
18
|
+
RSpec::Core::RakeTask.new do |t|
|
19
|
+
t.pattern = Dir['spec/**/*_spec.rb']
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "Run functional tests"
|
23
|
+
Cucumber::Rake::Task.new do |t|
|
24
|
+
t.cucumber_opts = %w{--color --format pretty}
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Generate documentation for the cql-model gem.'
|
28
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
29
|
+
rdoc.rdoc_dir = 'doc'
|
30
|
+
rdoc.title = 'Cql'
|
31
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
32
|
+
rdoc.rdoc_files.include('README.md')
|
33
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
34
|
+
rdoc.rdoc_files.exclude('features/**/*')
|
35
|
+
rdoc.rdoc_files.exclude('spec/**/*')
|
36
|
+
end
|
37
|
+
|
38
|
+
Jeweler::Tasks.new do |gem|
|
39
|
+
# gem is a Gem::Specification; see http://docs.rubygems.org/read/chapter/20 for more options
|
40
|
+
gem.name = "cql-model"
|
41
|
+
gem.required_ruby_version = ">= 1.9.0"
|
42
|
+
gem.homepage = "https://github.com/xeger/cql-model"
|
43
|
+
gem.license = "MIT"
|
44
|
+
gem.summary = %Q{Cassandra CQL model.}
|
45
|
+
gem.description = %Q{Lightweight, performant OOP wrapper for Cassandra tables; inspired by DataMapper.}
|
46
|
+
gem.email = "gemspec@tracker.xeger.net"
|
47
|
+
gem.authors = ['Tony Spataro']
|
48
|
+
gem.files.exclude 'features/**/*'
|
49
|
+
gem.files.exclude 'spec/**/*'
|
50
|
+
end
|
51
|
+
|
52
|
+
Jeweler::RubygemsDotOrgTasks.new
|
53
|
+
|
54
|
+
CLEAN.include('pkg')
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.0
|
data/cql-model.gemspec
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "cql-model"
|
8
|
+
s.version = "0.3.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Tony Spataro"]
|
12
|
+
s.date = "2013-04-24"
|
13
|
+
s.description = "Lightweight, performant OOP wrapper for Cassandra tables; inspired by DataMapper."
|
14
|
+
s.email = "gemspec@tracker.xeger.net"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".ruby-version",
|
20
|
+
"Gemfile",
|
21
|
+
"Gemfile.lock",
|
22
|
+
"README.md",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"cql-model.gemspec",
|
26
|
+
"cql_model.rconf",
|
27
|
+
"lib/cql/model.rb",
|
28
|
+
"lib/cql/model/dsl.rb",
|
29
|
+
"lib/cql/model/query.rb",
|
30
|
+
"lib/cql/model/query/comparison_expression.rb",
|
31
|
+
"lib/cql/model/query/expression.rb",
|
32
|
+
"lib/cql/model/query/insert_statement.rb",
|
33
|
+
"lib/cql/model/query/mutation_statement.rb",
|
34
|
+
"lib/cql/model/query/select_statement.rb",
|
35
|
+
"lib/cql/model/query/statement.rb",
|
36
|
+
"lib/cql/model/query/update_expression.rb",
|
37
|
+
"lib/cql/model/query/update_statement.rb"
|
38
|
+
]
|
39
|
+
s.homepage = "https://github.com/xeger/cql-model"
|
40
|
+
s.licenses = ["MIT"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.required_ruby_version = Gem::Requirement.new(">= 1.9.0")
|
43
|
+
s.rubygems_version = "1.8.23"
|
44
|
+
s.summary = "Cassandra CQL model."
|
45
|
+
|
46
|
+
if s.respond_to? :specification_version then
|
47
|
+
s.specification_version = 3
|
48
|
+
|
49
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
50
|
+
s.add_runtime_dependency(%q<cql-rb>, ["~> 1.0.0.pre4"])
|
51
|
+
s.add_development_dependency(%q<rake>, ["~> 0.9"])
|
52
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.0"])
|
53
|
+
s.add_development_dependency(%q<cucumber>, ["~> 1.0"])
|
54
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.3"])
|
55
|
+
s.add_development_dependency(%q<debugger>, [">= 0"])
|
56
|
+
s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
|
57
|
+
s.add_development_dependency(%q<flexmock>, ["~> 0.8"])
|
58
|
+
s.add_development_dependency(%q<syntax>, ["~> 1.0.0"])
|
59
|
+
s.add_development_dependency(%q<nokogiri>, ["~> 1.5"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<cql-rb>, ["~> 1.0.0.pre4"])
|
62
|
+
s.add_dependency(%q<rake>, ["~> 0.9"])
|
63
|
+
s.add_dependency(%q<rspec>, ["~> 2.0"])
|
64
|
+
s.add_dependency(%q<cucumber>, ["~> 1.0"])
|
65
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
66
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
67
|
+
s.add_dependency(%q<rdoc>, [">= 2.4.2"])
|
68
|
+
s.add_dependency(%q<flexmock>, ["~> 0.8"])
|
69
|
+
s.add_dependency(%q<syntax>, ["~> 1.0.0"])
|
70
|
+
s.add_dependency(%q<nokogiri>, ["~> 1.5"])
|
71
|
+
end
|
72
|
+
else
|
73
|
+
s.add_dependency(%q<cql-rb>, ["~> 1.0.0.pre4"])
|
74
|
+
s.add_dependency(%q<rake>, ["~> 0.9"])
|
75
|
+
s.add_dependency(%q<rspec>, ["~> 2.0"])
|
76
|
+
s.add_dependency(%q<cucumber>, ["~> 1.0"])
|
77
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.3"])
|
78
|
+
s.add_dependency(%q<debugger>, [">= 0"])
|
79
|
+
s.add_dependency(%q<rdoc>, [">= 2.4.2"])
|
80
|
+
s.add_dependency(%q<flexmock>, ["~> 0.8"])
|
81
|
+
s.add_dependency(%q<syntax>, ["~> 1.0.0"])
|
82
|
+
s.add_dependency(%q<nokogiri>, ["~> 1.5"])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
data/cql_model.rconf
ADDED
data/lib/cql/model.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'thread'
|
2
|
+
require 'cql'
|
3
|
+
|
4
|
+
module Cql::Model
|
5
|
+
# Raised if the user calls DSL that cannot generate valid CQL
|
6
|
+
class SyntaxError < Exception; end
|
7
|
+
|
8
|
+
# Raised if an insert statement does not specify all the primary keys
|
9
|
+
# or if an update statement does not specify any key (part of a composite primary key or a primary key)
|
10
|
+
class MissingKey < Exception; end
|
11
|
+
|
12
|
+
# Type aliases for use with the property-declaration DSL.
|
13
|
+
Uuid = Cql::Uuid
|
14
|
+
UUID = Uuid
|
15
|
+
|
16
|
+
# Type alias for use with the property-declaration DSL.
|
17
|
+
Boolean = TrueClass
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
require 'cql/model/query'
|
22
|
+
require 'cql/model/class_methods'
|
23
|
+
require 'cql/model/instance_methods'
|
24
|
+
|
25
|
+
module Cql::Model
|
26
|
+
def self.included(klass)
|
27
|
+
klass.__send__(:extend, Cql::Model::ClassMethods)
|
28
|
+
klass.__send__(:include, Cql::Model::InstanceMethods)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Get or set the "master" client connection shared by every model that doesn't bother to
|
32
|
+
# set its own. Defaults to a localhost connection with no default keyspace; every query
|
33
|
+
# must be wrapped in a "using_keyspace" method call.
|
34
|
+
#
|
35
|
+
# @param [optional, Cql::Client] new_client the new client to set
|
36
|
+
# @return [Cql::Client] the current client
|
37
|
+
def self.cql_client(new_client=nil)
|
38
|
+
if new_client
|
39
|
+
@@cql_model_mutex.synchronize do
|
40
|
+
@@cql_client = new_client
|
41
|
+
end
|
42
|
+
else
|
43
|
+
@@cql_client ||= Cql::Client.new
|
44
|
+
@@cql_client.start! unless @@cql_client.connected?
|
45
|
+
end
|
46
|
+
|
47
|
+
@@cql_client
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,178 @@
|
|
1
|
+
module Cql::Model::ClassMethods
|
2
|
+
def self.extended(klass)
|
3
|
+
klass.instance_eval do
|
4
|
+
# The mutex is shared by all Cql::Model inheritors
|
5
|
+
@@cql_model_mutex ||= Mutex.new
|
6
|
+
|
7
|
+
# Other attributes are tracked per-class
|
8
|
+
@cql_table_name ||= klass.name.split('::').last
|
9
|
+
@cql_model_properties ||= {}
|
10
|
+
@cql_model_keys ||= []
|
11
|
+
@cql_model_read_consistency ||= 'LOCAL_QUORUM'
|
12
|
+
@cql_model_write_consistency ||= 'LOCAL_QUORUM'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Get or set the client connection used by this class.
|
17
|
+
#
|
18
|
+
# @param [optional, Cql::Client] new_client the new client to set
|
19
|
+
# @return [Cql::Client] the current client
|
20
|
+
def cql_client(new_client=nil)
|
21
|
+
if new_client
|
22
|
+
@@cql_model_mutex.synchronize do
|
23
|
+
@cql_client = new_client
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
@cql_client || ::Cql::Model.cql_client
|
28
|
+
end
|
29
|
+
|
30
|
+
# @TODO docs
|
31
|
+
def table_name(new_name=nil)
|
32
|
+
if new_name
|
33
|
+
@@cql_model_mutex.synchronize do
|
34
|
+
# Set the table name
|
35
|
+
@cql_table_name = new_name
|
36
|
+
end
|
37
|
+
else
|
38
|
+
# Get the table name
|
39
|
+
@cql_table_name
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @TODO docs
|
44
|
+
def read_consistency(new_consistency=nil)
|
45
|
+
if new_consistency
|
46
|
+
@cql_model_read_consistency = new_consistency
|
47
|
+
else
|
48
|
+
@cql_model_read_consistency
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @TODO docs
|
53
|
+
def write_consistency(new_consistency=nil)
|
54
|
+
if new_consistency
|
55
|
+
@cql_model_write_consistency = new_consistency
|
56
|
+
else
|
57
|
+
@cql_model_write_consistency
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Specify or get a primary key or a composite primary key
|
62
|
+
#
|
63
|
+
# @param key_vals [Symbol|Array<Symbol>] single key name or composite key names
|
64
|
+
#
|
65
|
+
# @return [Cql::Model] self
|
66
|
+
def primary_key(*keys)
|
67
|
+
if keys.empty?
|
68
|
+
@cql_model_keys
|
69
|
+
else
|
70
|
+
@@cql_model_mutex.synchronize do
|
71
|
+
@cql_model_keys = keys
|
72
|
+
end
|
73
|
+
self
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @TODO docs
|
78
|
+
def property(name, type, opts={})
|
79
|
+
definition = {}
|
80
|
+
|
81
|
+
# If the user specified the name as a symbol, then they automatically get
|
82
|
+
# a reader and writer because the property has a predictable, fixed column
|
83
|
+
# name.
|
84
|
+
if name.is_a?(Symbol)
|
85
|
+
definition[:reader] = opts[:reader] || name
|
86
|
+
definition[:writer] = opts[:writer] || "#{definition[:reader]}=".to_sym
|
87
|
+
name = name.to_s
|
88
|
+
end
|
89
|
+
|
90
|
+
@@cql_model_mutex.synchronize do
|
91
|
+
definition[:type] = type
|
92
|
+
|
93
|
+
if @cql_model_properties.key?(name) && (@cql_model_properties[name] != definition)
|
94
|
+
raise ArgumentError, "Property #{name} is already defined"
|
95
|
+
end
|
96
|
+
|
97
|
+
unless @cql_model_properties.key?(name)
|
98
|
+
@cql_model_properties[name] = definition
|
99
|
+
|
100
|
+
__send__(:define_method, definition[:reader]) do
|
101
|
+
self[name]
|
102
|
+
end if definition[:reader]
|
103
|
+
|
104
|
+
__send__(:define_method, definition[:writer]) do |value|
|
105
|
+
self[name] = value
|
106
|
+
end if definition[:writer]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
self
|
111
|
+
end
|
112
|
+
|
113
|
+
# @TODO docs
|
114
|
+
def scope(name, &block)
|
115
|
+
@@cql_model_mutex.synchronize do
|
116
|
+
eigenclass = class <<self
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
eigenclass.instance_eval do
|
121
|
+
define_method(name.to_sym) do |*params|
|
122
|
+
# @TODO use a prepared statement for speed
|
123
|
+
self.select.where(*params, &block)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
self
|
129
|
+
end
|
130
|
+
|
131
|
+
# Begin building a CQL SELECT statement.
|
132
|
+
#
|
133
|
+
# @param [Object] *params list of yield parameters for the block
|
134
|
+
#
|
135
|
+
# @example tell us how old Joe is
|
136
|
+
# Person.select.where { name == 'Joe' }.each { |person| puts person.age }
|
137
|
+
def select(*params)
|
138
|
+
Cql::Model::Query::SelectStatement.new(self).select(*params)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Begin building a CQL INSERT statement.
|
142
|
+
# @see Cql::Model::Query::InsertStatement
|
143
|
+
#
|
144
|
+
# @param [Hash] values Hash of column values indexed by column name
|
145
|
+
# @return [Cql::Model::Query::InsertStatement] a query object to customize (timestamp, ttl, etc) or execute
|
146
|
+
#
|
147
|
+
# @example
|
148
|
+
# Person.create(:name => 'Joe', :age => 25).ttl(3600).execute
|
149
|
+
def insert(values)
|
150
|
+
Cql::Model::Query::InsertStatement.new(self).insert(values)
|
151
|
+
end
|
152
|
+
|
153
|
+
alias create insert
|
154
|
+
|
155
|
+
# Start an UPDATE CQL statement
|
156
|
+
# The method #keys must be called on the result before #execute
|
157
|
+
# @see Cql::Model::Query::UpdateStatement
|
158
|
+
#
|
159
|
+
# @param [Hash] values Hash of column values indexed by column name, optional
|
160
|
+
# @return [Cql::Model::Query::UpdateStatement] a query object to customize (keys, ttl, timestamp etc) then execute
|
161
|
+
#
|
162
|
+
# @example
|
163
|
+
# Person.update(:updated_at => Time.now.utc).keys(:name => ['joe', 'john', 'jane'])
|
164
|
+
# Person.update.ttl(3600).keys(:name => 'joe')
|
165
|
+
def update(values={})
|
166
|
+
Cql::Model::Query::UpdateStatement.new(self).update(values)
|
167
|
+
end
|
168
|
+
|
169
|
+
# @TODO docs
|
170
|
+
def each_row(&block)
|
171
|
+
Cql::Model::Query::SelectStatement.new(self).each_row(&block)
|
172
|
+
end
|
173
|
+
|
174
|
+
# @TODO docs
|
175
|
+
def each(&block)
|
176
|
+
Cql::Model::Query::SelectStatement.new(self).each(&block)
|
177
|
+
end
|
178
|
+
end
|