rethinkdb 1.2.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/base_classes.rb +39 -0
- data/lib/bt.rb +148 -0
- data/lib/data_collectors.rb +35 -0
- data/lib/jsons.rb +136 -0
- data/lib/net.rb +275 -0
- data/lib/protob_compiler.rb +137 -0
- data/lib/query.rb +111 -0
- data/lib/query_language.pb.rb +687 -0
- data/lib/rethinkdb.rb +16 -0
- data/lib/rql.rb +458 -0
- data/lib/sequence.rb +349 -0
- data/lib/streams.rb +101 -0
- data/lib/tables.rb +123 -0
- data/lib/utils.rb +118 -0
- data/lib/writes.rb +24 -0
- metadata +80 -0
data/lib/tables.rb
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
# Copyright 2010-2012 RethinkDB, all rights reserved.
|
2
|
+
module RethinkDB
|
3
|
+
# A database stored on the cluster. Usually created with the <b>+r+</b>
|
4
|
+
# shortcut, like:
|
5
|
+
# r.db('test')
|
6
|
+
class Database
|
7
|
+
# Refer to the database named <b>+name+</b>. Usually you would
|
8
|
+
# use the <b>+r+</b> shortcut instead:
|
9
|
+
# r.db(name)
|
10
|
+
def initialize(name); @db_name = name.to_s; end
|
11
|
+
|
12
|
+
# Access the table <b>+name+</b> in this database. For example:
|
13
|
+
# r.db('test').table('tbl')
|
14
|
+
# May also provide a set of options <b>+opts+</b>. Right now the only
|
15
|
+
# useful option is :use_outdated:
|
16
|
+
# r.db('test').table('tbl', {:use_outdated => true})
|
17
|
+
def table(name, opts={:use_outdated => false}); Table.new(@db_name, name, opts); end
|
18
|
+
|
19
|
+
# Create a new table in this database. You may also optionally
|
20
|
+
# specify the datacenter it should reside in, its primary key, and
|
21
|
+
# its cache size. For example:
|
22
|
+
# r.db('db').table_create('tbl', {:datacenter => 'dc',
|
23
|
+
# :primary_key => 'id',
|
24
|
+
# :cache_size => 1073741824})
|
25
|
+
# When run, either returns <b>+nil+</b> or throws on error.
|
26
|
+
def table_create(name, optargs={})
|
27
|
+
S.check_opts(optargs, [:datacenter, :primary_key, :cache_size])
|
28
|
+
dc = optargs[:datacenter] || S.skip
|
29
|
+
pkey = optargs[:primary_key] || S.skip
|
30
|
+
cache = optargs[:cache_size] || S.skip
|
31
|
+
BT.alt_inspect(Meta_Query.new [:create_table, dc, [@db_name, name], pkey, cache]) {
|
32
|
+
"db(#{@db_name.inspect}).create_table(#{name.inspect})"
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Drop the table <b>+name+</b> from this database. When run,
|
37
|
+
# either returns <b>+nil+</b> or throws on error.
|
38
|
+
def table_drop(name)
|
39
|
+
BT.alt_inspect(Meta_Query.new [:drop_table, @db_name, name]) {
|
40
|
+
"db(#{@db_name.inspect}).drop_table(#{name.inspect})"
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# List all the tables in this database. When run, either returns
|
45
|
+
# <b>+nil+</b> or throws on error.
|
46
|
+
def table_list
|
47
|
+
BT.alt_inspect(Meta_Query.new [:list_tables, @db_name]) {
|
48
|
+
"db(#{@db_name.inspect}).list_tables"
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
def inspect # :nodoc:
|
53
|
+
real_inspect({:str => @db_name})
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# A table in a particular RethinkDB database. If you call a
|
58
|
+
# function from Sequence on it, it will be treated as a
|
59
|
+
# Stream_Expression reading from the table.
|
60
|
+
class Table
|
61
|
+
def inspect # :nodoc:
|
62
|
+
to_mrs.inspect
|
63
|
+
end
|
64
|
+
|
65
|
+
attr_accessor :opts
|
66
|
+
# A table named <b>+name+</b> residing in database
|
67
|
+
# <b>+db_name+</b>. Usually you would instead write:
|
68
|
+
# r.db(db_name).table(name)
|
69
|
+
def initialize(db_name, name, opts)
|
70
|
+
@db_name = db_name;
|
71
|
+
@table_name = name;
|
72
|
+
@opts = opts
|
73
|
+
@context = caller
|
74
|
+
S.check_opts(@opts, [:use_outdated])
|
75
|
+
use_od = (@opts.include? :use_outdated) ? @opts[:use_outdated] : S.conn_outdated
|
76
|
+
@body = [:table, @db_name, @table_name, use_od]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Insert one or more rows into the table. For example:
|
80
|
+
# table.insert({:id => 0})
|
81
|
+
# table.insert([{:id => 1}, {:id => 2}])
|
82
|
+
# If you try to insert a
|
83
|
+
# row with a primary key already in the table, you will get back
|
84
|
+
# an error. For example, if you have a table <b>+table+</b>:
|
85
|
+
# table.insert([{:id => 1}, {:id => 1}])
|
86
|
+
# Will return something like:
|
87
|
+
# {'inserted' => 1, 'errors' => 1, 'first_error' => ...}
|
88
|
+
# If you want to overwrite a row, you should specifiy <b>+mode+</b> to be
|
89
|
+
# <b>+:upsert+</b>, like so:
|
90
|
+
# table.insert([{:id => 1}, {:id => 1}], :upsert)
|
91
|
+
# which will return:
|
92
|
+
# {'inserted' => 2, 'errors' => 0}
|
93
|
+
# You may also provide a stream. So to make a copy of a table, you can do:
|
94
|
+
# r.db_create('new_db').run
|
95
|
+
# r.db('new_db').table_create('new_table').run
|
96
|
+
# r.db('new_db').new_table.insert(table).run
|
97
|
+
def insert(rows, mode=:new)
|
98
|
+
raise_if_outdated
|
99
|
+
rows = [rows] if rows.class != Array
|
100
|
+
do_upsert = (mode == :upsert ? true : false)
|
101
|
+
Write_Query.new [:insert, [@db_name, @table_name], rows.map{|x| S.r(x)}, do_upsert]
|
102
|
+
end
|
103
|
+
|
104
|
+
# Get the row with key <b>+key+</b>. You may also
|
105
|
+
# optionally specify the name of the attribute to use as your key
|
106
|
+
# (<b>+keyname+</b>), but note that your table must be indexed by that
|
107
|
+
# attribute. For example, if we have a table <b>+table+</b>:
|
108
|
+
# table.get(0)
|
109
|
+
def get(key, keyname=:id)
|
110
|
+
Single_Row_Selection.new [:getbykey, [@db_name, @table_name], keyname, S.r(key)]
|
111
|
+
end
|
112
|
+
|
113
|
+
def method_missing(m, *args, &block) # :nodoc:
|
114
|
+
to_mrs.send(m, *args, &block);
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_mrs # :nodoc:
|
118
|
+
BT.alt_inspect(Multi_Row_Selection.new(@body, @context, @opts)) {
|
119
|
+
"db(#{@db_name.inspect}).table(#{@table_name.inspect})"
|
120
|
+
}
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/utils.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
# Copyright 2010-2012 RethinkDB, all rights reserved.
|
2
|
+
module RethinkDB
|
3
|
+
module C_Mixin #Constants
|
4
|
+
# We often have shorter names for things, or inline variants, specified here.
|
5
|
+
def method_aliases
|
6
|
+
{ :attr => :getattr, :attrs => :pickattrs, :attr? => :hasattr,
|
7
|
+
:get => :getattr, :pick => :pickattrs, :has => :hasattr,
|
8
|
+
:equals => :eq, :neq => :ne,
|
9
|
+
:sub => :subtract, :mul => :multiply, :div => :divide, :mod => :modulo,
|
10
|
+
:+ => :add, :- => :subtract, :* => :multiply, :/ => :divide, :% => :modulo,
|
11
|
+
:and => :all, :or => :any, :to_stream => :array_to_stream, :to_array => :stream_to_array} end
|
12
|
+
|
13
|
+
# Allows us to identify protobuf classes which are actually variant types,
|
14
|
+
# and to get their corresponding enums.
|
15
|
+
def class_types
|
16
|
+
{ Query => Query::QueryType, WriteQuery => WriteQuery::WriteQueryType,
|
17
|
+
Term => Term::TermType, Builtin => Builtin::BuiltinType,
|
18
|
+
MetaQuery => MetaQuery::MetaQueryType} end
|
19
|
+
|
20
|
+
# The protobuf spec often has a field with a slightly different name from
|
21
|
+
# the enum constant, which we list here.
|
22
|
+
def query_rewrites
|
23
|
+
{ :getattr => :attr,
|
24
|
+
:hasattr => :attr,
|
25
|
+
:without => :attrs,
|
26
|
+
:pickattrs => :attrs,
|
27
|
+
:string => :valuestring, :json => :jsonstring, :bool => :valuebool,
|
28
|
+
:if => :if_, :getbykey => :get_by_key, :groupedmapreduce => :grouped_map_reduce,
|
29
|
+
:insertstream => :insert_stream, :foreach => :for_each, :orderby => :order_by,
|
30
|
+
:pointupdate => :point_update, :pointdelete => :point_delete,
|
31
|
+
:pointmutate => :point_mutate, :concatmap => :concat_map,
|
32
|
+
:read => :read_query, :write => :write_query, :meta => :meta_query,
|
33
|
+
:create_db => :db_name, :drop_db => :db_name, :list_tables => :db_name
|
34
|
+
} end
|
35
|
+
|
36
|
+
def name_rewrites
|
37
|
+
{ :between => :range, :js => :javascript,
|
38
|
+
:array_to_stream => :arraytostream, :stream_to_array => :streamtoarray,
|
39
|
+
:merge => :mapmerge, :branch => :if, :pick => :pickattrs, :unpick => :without,
|
40
|
+
:replace => :mutate, :pointreplace => :pointmutate, :contains => :hasattr,
|
41
|
+
:count => :length
|
42
|
+
} end
|
43
|
+
|
44
|
+
# These classes go through a useless intermediate type.
|
45
|
+
def trampolines; [:table, :map, :concatmap, :filter] end
|
46
|
+
|
47
|
+
# These classes expect repeating arguments.
|
48
|
+
def repeats; [:insert, :foreach]; end
|
49
|
+
|
50
|
+
# These classes reference a tableref directly, rather than a term.
|
51
|
+
def table_directs
|
52
|
+
[:insert, :insertstream, :pointupdate, :pointdelete, :pointmutate,
|
53
|
+
:create, :drop] end
|
54
|
+
|
55
|
+
def nonatomic_variants
|
56
|
+
[:update_nonatomic, :replace_nonatomic,
|
57
|
+
:pointupdate_nonatomic, :pointreplace_nonatomic] end
|
58
|
+
end
|
59
|
+
module C; extend C_Mixin; end
|
60
|
+
|
61
|
+
module P_Mixin #Protobuf Utils
|
62
|
+
def enum_type(_class, _type); _class.values[_type.to_s.upcase.to_sym]; end
|
63
|
+
def message_field(_class, _type); _class.fields.select{|x,y|
|
64
|
+
y.instance_eval{@name} == _type
|
65
|
+
#TODO: why did the following stop working? (Or, why did it ever work?)
|
66
|
+
#y.name == _type
|
67
|
+
}[0]; end
|
68
|
+
def message_set(message, key, val); message.send((key.to_s+'=').to_sym, val); end
|
69
|
+
end
|
70
|
+
module P; extend P_Mixin; end
|
71
|
+
|
72
|
+
module S_Mixin #S-expression Utils
|
73
|
+
def rewrite(q); C.name_rewrites[q] || q; end
|
74
|
+
def mark_boolop(x); class << x; def boolop?; true; end; end; x; end
|
75
|
+
def check_opts(opts, set)
|
76
|
+
if (bad_opts = opts.map{|k,_|k} - set) != []
|
77
|
+
raise ArgumentError,"Unrecognized options: #{bad_opts.inspect}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
@@gensym_counter = 1000
|
81
|
+
def gensym; '_var_'+(@@gensym_counter += 1).to_s; end
|
82
|
+
def with_var
|
83
|
+
sym = gensym
|
84
|
+
yield sym, var(sym)
|
85
|
+
end
|
86
|
+
def var(varname)
|
87
|
+
BT.alt_inspect(Var_Expression.new [:var, varname]) { |expr| expr.body[1] }
|
88
|
+
end
|
89
|
+
def r x; x.equal?(skip) ? x : RQL.expr(x); end
|
90
|
+
def skip; :skip_2222ebd4_2c16_485e_8c27_bbe43674a852; end
|
91
|
+
def conn_outdated; :conn_outdated_2222ebd4_2c16_485e_8c27_bbe43674a852; end
|
92
|
+
|
93
|
+
def arg_or_block(*args, &block)
|
94
|
+
if args.length == 1 && block
|
95
|
+
raise ArgumentError,"Cannot provide both an argument *and* a block."
|
96
|
+
end
|
97
|
+
return lambda { args[0] } if (args.length == 1)
|
98
|
+
return block if block
|
99
|
+
raise ArgumentError,"Must provide either an argument or a block."
|
100
|
+
end
|
101
|
+
|
102
|
+
def clean_lst lst # :nodoc:
|
103
|
+
return lst.sexp if lst.kind_of? RQL_Query
|
104
|
+
return lst.class == Array ? lst.map{|z| clean_lst(z)} : lst
|
105
|
+
end
|
106
|
+
|
107
|
+
def replace(sexp, map)
|
108
|
+
return sexp.map{|x| replace x,map} if sexp.class == Array
|
109
|
+
return (map.include? sexp) ? map[sexp] : sexp
|
110
|
+
end
|
111
|
+
|
112
|
+
def checkdict s
|
113
|
+
return s.to_s if s.class == String || s.class == Symbol
|
114
|
+
raise RuntimeError, "Invalid JSON dict key: #{s.inspect}"
|
115
|
+
end
|
116
|
+
end
|
117
|
+
module S; extend S_Mixin; end
|
118
|
+
end
|
data/lib/writes.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright 2010-2012 RethinkDB, all rights reserved.
|
2
|
+
module RethinkDB
|
3
|
+
# A write operation, like an insert.
|
4
|
+
class Write_Query < RQL_Query
|
5
|
+
# Internal tool for when we have commands that take a flag but
|
6
|
+
# which are most easily processed by the protobuf compiler as a
|
7
|
+
# separate command.
|
8
|
+
def apply_variant(variant) # :nodoc:
|
9
|
+
return self if variant.nil?
|
10
|
+
if variant == :non_atomic
|
11
|
+
@body[0] = case @body[0]
|
12
|
+
when :update then :update_nonatomic
|
13
|
+
when :replace then :replace_nonatomic
|
14
|
+
when :pointupdate then :pointupdate_nonatomic
|
15
|
+
when :pointreplace then :pointreplace_nonatomic
|
16
|
+
else raise RuntimeError,"#{@body[0]} cannot be made nonatomic"
|
17
|
+
end
|
18
|
+
else
|
19
|
+
raise RuntimeError,"Unknown variant #{@body[0]}; did you mean `:non_atomic`?"
|
20
|
+
end
|
21
|
+
return self
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rethinkdb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 77
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
- 1
|
11
|
+
version: 1.2.0.1
|
12
|
+
platform: ruby
|
13
|
+
authors:
|
14
|
+
- Rethinkdb Inc.
|
15
|
+
autorequire:
|
16
|
+
bindir: bin
|
17
|
+
cert_chain: []
|
18
|
+
|
19
|
+
date: 2012-11-09 00:00:00 Z
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: bugs@rethinkdb.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- lib/tables.rb
|
32
|
+
- lib/jsons.rb
|
33
|
+
- lib/query.rb
|
34
|
+
- lib/rethinkdb.rb
|
35
|
+
- lib/bt.rb
|
36
|
+
- lib/writes.rb
|
37
|
+
- lib/rql.rb
|
38
|
+
- lib/utils.rb
|
39
|
+
- lib/protob_compiler.rb
|
40
|
+
- lib/net.rb
|
41
|
+
- lib/query_language.pb.rb
|
42
|
+
- lib/sequence.rb
|
43
|
+
- lib/base_classes.rb
|
44
|
+
- lib/streams.rb
|
45
|
+
- lib/data_collectors.rb
|
46
|
+
homepage: http://rethinkdb.com
|
47
|
+
licenses:
|
48
|
+
- Apache-2
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ">="
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 3
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
version: "0"
|
63
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
requirements: []
|
73
|
+
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.8.24
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: This package provides the Ruby driver library for the RethinkDB database server.
|
79
|
+
test_files: []
|
80
|
+
|