vines-services 0.1.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/LICENSE +19 -0
- data/README +40 -0
- data/Rakefile +130 -0
- data/bin/vines-services +95 -0
- data/conf/config.rb +25 -0
- data/lib/vines/services/command/init.rb +209 -0
- data/lib/vines/services/command/restart.rb +14 -0
- data/lib/vines/services/command/start.rb +30 -0
- data/lib/vines/services/command/stop.rb +20 -0
- data/lib/vines/services/command/views.rb +26 -0
- data/lib/vines/services/component.rb +26 -0
- data/lib/vines/services/config.rb +105 -0
- data/lib/vines/services/connection.rb +120 -0
- data/lib/vines/services/controller/attributes_controller.rb +19 -0
- data/lib/vines/services/controller/base_controller.rb +99 -0
- data/lib/vines/services/controller/disco_info_controller.rb +61 -0
- data/lib/vines/services/controller/labels_controller.rb +17 -0
- data/lib/vines/services/controller/members_controller.rb +44 -0
- data/lib/vines/services/controller/messages_controller.rb +66 -0
- data/lib/vines/services/controller/probes_controller.rb +45 -0
- data/lib/vines/services/controller/services_controller.rb +81 -0
- data/lib/vines/services/controller/subscriptions_controller.rb +39 -0
- data/lib/vines/services/controller/systems_controller.rb +45 -0
- data/lib/vines/services/controller/transfers_controller.rb +58 -0
- data/lib/vines/services/controller/uploads_controller.rb +62 -0
- data/lib/vines/services/controller/users_controller.rb +127 -0
- data/lib/vines/services/core_ext/blather.rb +46 -0
- data/lib/vines/services/core_ext/couchrest.rb +33 -0
- data/lib/vines/services/indexer.rb +195 -0
- data/lib/vines/services/priority_queue.rb +94 -0
- data/lib/vines/services/roster.rb +70 -0
- data/lib/vines/services/storage/couchdb/fragment.rb +23 -0
- data/lib/vines/services/storage/couchdb/service.rb +170 -0
- data/lib/vines/services/storage/couchdb/system.rb +141 -0
- data/lib/vines/services/storage/couchdb/upload.rb +66 -0
- data/lib/vines/services/storage/couchdb/user.rb +137 -0
- data/lib/vines/services/storage/couchdb/vcard.rb +13 -0
- data/lib/vines/services/storage/couchdb.rb +157 -0
- data/lib/vines/services/storage.rb +33 -0
- data/lib/vines/services/throttle.rb +26 -0
- data/lib/vines/services/version.rb +7 -0
- data/lib/vines/services/vql/compiler.rb +94 -0
- data/lib/vines/services/vql/vql.citrus +115 -0
- data/lib/vines/services/vql/vql.rb +186 -0
- data/lib/vines/services.rb +71 -0
- data/test/config_test.rb +242 -0
- data/test/priority_queue_test.rb +23 -0
- data/test/storage/couchdb_test.rb +30 -0
- data/test/vql/compiler_test.rb +96 -0
- data/test/vql/vql_test.rb +233 -0
- data/web/coffeescripts/api.coffee +51 -0
- data/web/coffeescripts/commands.coffee +18 -0
- data/web/coffeescripts/files.coffee +315 -0
- data/web/coffeescripts/init.coffee +21 -0
- data/web/coffeescripts/services.coffee +356 -0
- data/web/coffeescripts/setup.coffee +503 -0
- data/web/coffeescripts/systems.coffee +371 -0
- data/web/images/default-service.png +0 -0
- data/web/images/linux.png +0 -0
- data/web/images/mac.png +0 -0
- data/web/images/run.png +0 -0
- data/web/images/windows.png +0 -0
- data/web/index.html +17 -0
- data/web/stylesheets/common.css +52 -0
- data/web/stylesheets/files.css +218 -0
- data/web/stylesheets/services.css +181 -0
- data/web/stylesheets/setup.css +117 -0
- data/web/stylesheets/systems.css +142 -0
- metadata +230 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Vines
|
4
|
+
module Services
|
5
|
+
class Storage
|
6
|
+
class CouchDB < Storage
|
7
|
+
register :couchdb
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
# Override CouchRest::Model::Persistence::ClassMethods#build_from_database
|
11
|
+
# to instantiate the fully qualified model class name. We store the
|
12
|
+
# bare class name in doc['type'] (e.g. Service rather than
|
13
|
+
# Vines::Services::CouchModels::Service), so outside query processes
|
14
|
+
# don't need to know our class hierarchy.
|
15
|
+
def build_from_database(doc = {}, options = {}, &block)
|
16
|
+
src = doc[model_type_key]
|
17
|
+
base = (src.blank? || src == self.to_s) ? self : "Vines::Services::CouchModels::#{src}".constantize
|
18
|
+
base.new(doc, options.merge(:directly_set_attributes => true), &block)
|
19
|
+
end
|
20
|
+
|
21
|
+
# CouchRest::Model uses Class#to_s to determine design document names
|
22
|
+
# as well as the value of doc['type']. Strip off all module names to
|
23
|
+
# get clean design document URLs.
|
24
|
+
def to_s
|
25
|
+
self.name.split('::').last
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
%w[host port database tls username password index_dir].each do |name|
|
30
|
+
define_method(name) do |*args|
|
31
|
+
if args.first
|
32
|
+
@config[name.to_sym] = args.first
|
33
|
+
else
|
34
|
+
@config[name.to_sym]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize(&block)
|
40
|
+
@config = {}
|
41
|
+
instance_eval(&block)
|
42
|
+
[:host, :port, :database, :index_dir].each do |key|
|
43
|
+
raise "Must provide #{key}" unless @config[key]
|
44
|
+
end
|
45
|
+
|
46
|
+
@config[:index_dir] = File.expand_path(@config[:index_dir])
|
47
|
+
unless File.directory?(@config[:index_dir]) && File.writable?(@config[:index_dir])
|
48
|
+
raise 'Must provide a writable index directory'
|
49
|
+
end
|
50
|
+
|
51
|
+
@url = url(@config)
|
52
|
+
init_couch_rest
|
53
|
+
|
54
|
+
db = "%s-%s-%s.db" % [host, port, database]
|
55
|
+
@index = Indexer[File.join(@config[:index_dir], db)]
|
56
|
+
end
|
57
|
+
|
58
|
+
def get(path, &callback)
|
59
|
+
http(path, :get, &callback)
|
60
|
+
end
|
61
|
+
|
62
|
+
def post(path, body, &callback)
|
63
|
+
http(path, :post, body, &callback)
|
64
|
+
end
|
65
|
+
|
66
|
+
def delete(path, &callback)
|
67
|
+
http(path, :get) do |doc|
|
68
|
+
if doc
|
69
|
+
http("#{path}?rev=#{doc['_rev']}", :delete, &callback)
|
70
|
+
else
|
71
|
+
yield
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def save(doc, &callback)
|
77
|
+
http('', :post, doc.to_json, &callback)
|
78
|
+
end
|
79
|
+
|
80
|
+
def index(system)
|
81
|
+
@index << system.ohai
|
82
|
+
end
|
83
|
+
|
84
|
+
def query(sql, *params, &callback)
|
85
|
+
@index.find(sql, params, &callback)
|
86
|
+
end
|
87
|
+
|
88
|
+
def store_file(path)
|
89
|
+
file = CouchModels::Upload.find_by_name(File.basename(path))
|
90
|
+
unless file
|
91
|
+
File.delete(path)
|
92
|
+
return
|
93
|
+
end
|
94
|
+
|
95
|
+
http = EM::HttpRequest.new("#{@url}/#{file.id}/data?rev=#{file.rev}").put(
|
96
|
+
head: {'Content-Type' => 'application/octet-stream'},
|
97
|
+
file: path
|
98
|
+
)
|
99
|
+
http.callback {|chunk| yield }
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_views
|
103
|
+
# FIXME Use views in CouchRest::Model classes to populate db
|
104
|
+
designs = {}
|
105
|
+
|
106
|
+
EM.run do
|
107
|
+
http('', :put) do # create db
|
108
|
+
designs.each do |name, views|
|
109
|
+
get("/_design/#{name}") do |doc|
|
110
|
+
doc ||= {"_id" => "_design/#{name}"}
|
111
|
+
doc['language'] = 'javascript'
|
112
|
+
doc['views'] = views
|
113
|
+
save(doc) { EM.stop }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def http(path, method, body=nil)
|
123
|
+
args = {}.tap do |opts|
|
124
|
+
opts[:head] = {'Content-Type' => 'application/json'}
|
125
|
+
opts[:body] = body if body
|
126
|
+
end
|
127
|
+
|
128
|
+
http = EM::HttpRequest.new("#{@url}#{path}").send(method, args)
|
129
|
+
http.errback { yield }
|
130
|
+
http.callback do
|
131
|
+
doc = if (200...300).include?(http.response_header.status)
|
132
|
+
JSON.parse(http.response) rescue nil
|
133
|
+
end
|
134
|
+
yield doc
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def url(config)
|
139
|
+
scheme = config[:tls] ? 'https' : 'http'
|
140
|
+
user, password = config.values_at(:username, :password)
|
141
|
+
credentials = empty?(user, password) ? '' : "%s:%s@" % [user, password]
|
142
|
+
"%s://%s%s:%s/%s" % [scheme, credentials, *config.values_at(:host, :port, :database)]
|
143
|
+
end
|
144
|
+
|
145
|
+
def init_couch_rest
|
146
|
+
*url, _ = @url.split('/')
|
147
|
+
server = CouchRest::Server.new(url.join('/'))
|
148
|
+
CouchRest::Model::Base.database = server.database(database)
|
149
|
+
end
|
150
|
+
|
151
|
+
def escape(jid)
|
152
|
+
URI.escape(jid, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Vines
|
4
|
+
module Services
|
5
|
+
class Storage
|
6
|
+
include Vines::Log
|
7
|
+
|
8
|
+
@@nicks = {}
|
9
|
+
|
10
|
+
# Register a nickname that can be used in the config file to specify this
|
11
|
+
# storage implementation.
|
12
|
+
def self.register(name)
|
13
|
+
@@nicks[name.to_sym] = self
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.from_name(name, &block)
|
17
|
+
klass = @@nicks[name.to_sym]
|
18
|
+
raise "#{name} storage class not found" unless klass
|
19
|
+
klass.new(&block)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
# Return true if any of the arguments are nil or empty strings.
|
25
|
+
# For example:
|
26
|
+
# username, password = 'alice@wonderland.lit', ''
|
27
|
+
# empty?(username, password) #=> true
|
28
|
+
def empty?(*args)
|
29
|
+
args.flatten.any? {|arg| (arg || '').strip.empty? }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Vines
|
4
|
+
module Services
|
5
|
+
# Send many outgoing stanzas to the server at a sustained rate that won't
|
6
|
+
# cause the server to shutdown the component's stream with a policy_violation
|
7
|
+
# error.
|
8
|
+
class Throttle
|
9
|
+
def initialize(stream, delay=0.1)
|
10
|
+
@stream, @delay = stream, delay
|
11
|
+
end
|
12
|
+
|
13
|
+
# Send the nodes to the server at a constant rate. The nodes are sent
|
14
|
+
# asynchronously, so this method returns immediately.
|
15
|
+
def async_send(nodes)
|
16
|
+
timer = EM::PeriodicTimer.new(@delay) do
|
17
|
+
if node = nodes.shift
|
18
|
+
@stream.write(node)
|
19
|
+
else
|
20
|
+
timer.cancel
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
module Vines
|
4
|
+
module Services
|
5
|
+
module VQL
|
6
|
+
# Compiles Vines Query Language queries into JavaScript for CouchDB views
|
7
|
+
# and SQL for sqlite queries. The output of the compiler is a fully formed
|
8
|
+
# query that can be sent directly to the database.
|
9
|
+
class Compiler
|
10
|
+
Citrus.load(File.expand_path('../vql.citrus', __FILE__))
|
11
|
+
|
12
|
+
# Return the compiled CouchDB map function. Raise an exception on
|
13
|
+
# compilation failure. The exception's error message can be shown to
|
14
|
+
# the user to debug the syntax.
|
15
|
+
def to_js(code)
|
16
|
+
raise ArgumentError, 'code required' if code.nil? || code.strip.empty?
|
17
|
+
expr = VinesQL.parse(code.strip)
|
18
|
+
%Q{
|
19
|
+
function(doc) {
|
20
|
+
if (doc.type != 'System') return;
|
21
|
+
try {
|
22
|
+
var match = #{expr.js};
|
23
|
+
if (match) {
|
24
|
+
var name = doc['_id'].replace('system:', '');
|
25
|
+
var os = doc.ohai.kernel.os.toLowerCase().replace('gnu/', '');
|
26
|
+
emit(name, os);
|
27
|
+
}
|
28
|
+
} catch(e) {
|
29
|
+
log(e.message);
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
# Return the compiled CouchDB map function for all services. Raise an
|
36
|
+
# exception on compilation failure. The exception's error message can
|
37
|
+
# be shown to the user to debug the syntax.
|
38
|
+
def to_full_js(services)
|
39
|
+
maps = services.map do |service|
|
40
|
+
expr = VinesQL.parse(service.code.strip)
|
41
|
+
%Q{
|
42
|
+
try {
|
43
|
+
var match = #{expr.js};
|
44
|
+
if (match) {
|
45
|
+
emit([0, '#{service.id}'], {name: name, os: os});
|
46
|
+
emit([1, name], '#{service.id}');
|
47
|
+
}
|
48
|
+
} catch(e) {
|
49
|
+
log(e.message);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
%Q{
|
55
|
+
function(doc) {
|
56
|
+
if (doc.type != 'System') return;
|
57
|
+
var name = doc['_id'].replace('system:', '');
|
58
|
+
var os = doc.ohai.kernel.os.toLowerCase().replace('gnu/', '');
|
59
|
+
#{maps.join}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
# Return the compiled sqlite SQL query along with an array of parameter
|
65
|
+
# replacement values. Raise an exception on compilation failure. The
|
66
|
+
# exception's error message can be shown to the user to debug the syntax.
|
67
|
+
def to_sql(code)
|
68
|
+
raise ArgumentError, 'code required' if code.nil? || code.strip.empty?
|
69
|
+
expr = VinesQL.parse(code.strip)
|
70
|
+
|
71
|
+
keys, values = expr.params.partition.each_with_index {|p, ix| ix % 2 == 0 }
|
72
|
+
joins = keys.each_with_index.map do |k, ix|
|
73
|
+
"inner join attributes a%s on id=a%s.system_id and a%s.key=?" % [ix, ix, ix]
|
74
|
+
end
|
75
|
+
|
76
|
+
where = expr.sql.tap do |sql|
|
77
|
+
values.size.times do |ix|
|
78
|
+
sql.sub!(/(^|[^\.])value/, "\\1a#{ix}.value")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
sql = %Q{
|
83
|
+
select name, os from systems
|
84
|
+
#{joins.join("\n")}
|
85
|
+
where #{where}
|
86
|
+
order by name
|
87
|
+
}
|
88
|
+
|
89
|
+
[sql, [keys, values].flatten]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
grammar VinesQL
|
2
|
+
rule expr
|
3
|
+
expr:(disjunctive | stmt)
|
4
|
+
end
|
5
|
+
|
6
|
+
rule disjunctive
|
7
|
+
(lhs:stmt 'or' ws rhs:expr) <Vines::Services::VQL::Or>
|
8
|
+
end
|
9
|
+
|
10
|
+
rule stmt
|
11
|
+
stmt:(conjunctive | term)
|
12
|
+
end
|
13
|
+
|
14
|
+
rule conjunctive
|
15
|
+
(lhs:term 'and' ws rhs:stmt) <Vines::Services::VQL::And>
|
16
|
+
end
|
17
|
+
|
18
|
+
rule term
|
19
|
+
is_not | is | ltgt | starts_with | ends_with | not_like | like | group
|
20
|
+
end
|
21
|
+
|
22
|
+
rule is
|
23
|
+
(lhs:member 'is' ws rhs:value) <Vines::Services::VQL::Is>
|
24
|
+
end
|
25
|
+
|
26
|
+
rule is_not
|
27
|
+
(lhs:member 'is' ws 'not' ws rhs:value) <Vines::Services::VQL::IsNot>
|
28
|
+
end
|
29
|
+
|
30
|
+
rule like
|
31
|
+
(lhs:member 'like' ws rhs:string) <Vines::Services::VQL::Like>
|
32
|
+
end
|
33
|
+
|
34
|
+
rule not_like
|
35
|
+
(lhs:member 'not' ws 'like' ws rhs:string) <Vines::Services::VQL::NotLike>
|
36
|
+
end
|
37
|
+
|
38
|
+
rule starts_with
|
39
|
+
(lhs:member 'starts' ws 'with' ws rhs:string) <Vines::Services::VQL::StartsWith>
|
40
|
+
end
|
41
|
+
|
42
|
+
rule ends_with
|
43
|
+
(lhs:member 'ends' ws 'with' ws rhs:string) <Vines::Services::VQL::EndsWith>
|
44
|
+
end
|
45
|
+
|
46
|
+
rule ltgt
|
47
|
+
(lhs:member op:([<>] '='?) ws rhs:number) <Vines::Services::VQL::LtGt>
|
48
|
+
end
|
49
|
+
|
50
|
+
rule value
|
51
|
+
string | number | keyword
|
52
|
+
end
|
53
|
+
|
54
|
+
rule group
|
55
|
+
(lparen expr rparen) <Vines::Services::VQL::Group>
|
56
|
+
end
|
57
|
+
|
58
|
+
rule member
|
59
|
+
(str:(ident ('.' ident)*) ws) <Vines::Services::VQL::Member>
|
60
|
+
end
|
61
|
+
|
62
|
+
rule ident
|
63
|
+
(alpha | '_') (alpha | '_' | digits)*
|
64
|
+
end
|
65
|
+
|
66
|
+
rule string
|
67
|
+
single_quoted | double_quoted
|
68
|
+
end
|
69
|
+
|
70
|
+
rule single_quoted
|
71
|
+
("'" str:(~"'") "'" ws) <Vines::Services::VQL::SingleQuoted>
|
72
|
+
end
|
73
|
+
|
74
|
+
rule double_quoted
|
75
|
+
('"' str:(~'"') '"' ws) <Vines::Services::VQL::DoubleQuoted>
|
76
|
+
end
|
77
|
+
|
78
|
+
rule keyword
|
79
|
+
(str:'null' ws) <Vines::Services::VQL::Null>
|
80
|
+
| (str:'true' ws) <Vines::Services::VQL::Terminal>
|
81
|
+
| (str:'false' ws) <Vines::Services::VQL::Terminal>
|
82
|
+
end
|
83
|
+
|
84
|
+
rule number
|
85
|
+
float | int
|
86
|
+
end
|
87
|
+
|
88
|
+
rule float
|
89
|
+
(str:('-'? digits '.' digits) ws) <Vines::Services::VQL::Terminal>
|
90
|
+
end
|
91
|
+
|
92
|
+
rule int
|
93
|
+
(str:('-'? digits) ws) <Vines::Services::VQL::Terminal>
|
94
|
+
end
|
95
|
+
|
96
|
+
rule digits
|
97
|
+
[0-9]+
|
98
|
+
end
|
99
|
+
|
100
|
+
rule alpha
|
101
|
+
[a-zA-Z]+
|
102
|
+
end
|
103
|
+
|
104
|
+
rule lparen
|
105
|
+
'(' ws
|
106
|
+
end
|
107
|
+
|
108
|
+
rule rparen
|
109
|
+
')' ws
|
110
|
+
end
|
111
|
+
|
112
|
+
rule ws
|
113
|
+
[ \t\n\r]*
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,186 @@
|
|
1
|
+
module Vines
|
2
|
+
module Services
|
3
|
+
# These modules give semantic meaning to the Vines Query Language Citrus
|
4
|
+
# parser. The query language is translated into JavaScript and SQL fragments
|
5
|
+
# for use in CouchDB views or sqlite queries. This file must be loaded before
|
6
|
+
# vql.citrus.
|
7
|
+
module VQL
|
8
|
+
module Or
|
9
|
+
def js
|
10
|
+
"%s || %s" % [lhs.js, rhs.js]
|
11
|
+
end
|
12
|
+
def sql
|
13
|
+
"%s or %s" % [lhs.sql, rhs.sql]
|
14
|
+
end
|
15
|
+
def params
|
16
|
+
[lhs.params, rhs.params].flatten
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module And
|
21
|
+
def js
|
22
|
+
"%s && %s" % [lhs.js, rhs.js]
|
23
|
+
end
|
24
|
+
def sql
|
25
|
+
"%s and %s" % [lhs.sql, rhs.sql]
|
26
|
+
end
|
27
|
+
def params
|
28
|
+
[lhs.params, rhs.params].flatten
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module Is
|
33
|
+
def js
|
34
|
+
"(%s === %s)" % [lhs.js, rhs.js]
|
35
|
+
end
|
36
|
+
def sql
|
37
|
+
case rhs
|
38
|
+
when Vines::Services::VQL::Null
|
39
|
+
"value is null"
|
40
|
+
else
|
41
|
+
"value=?"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def params
|
45
|
+
case rhs
|
46
|
+
when Vines::Services::VQL::Null
|
47
|
+
[lhs.sql]
|
48
|
+
else
|
49
|
+
[lhs.sql, rhs.sql]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module IsNot
|
55
|
+
def js
|
56
|
+
"(%s !== %s)" % [lhs.js, rhs.js]
|
57
|
+
end
|
58
|
+
def sql
|
59
|
+
case rhs
|
60
|
+
when Vines::Services::VQL::Null
|
61
|
+
"value is not null"
|
62
|
+
else
|
63
|
+
"value <> ?"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
def params
|
67
|
+
case rhs
|
68
|
+
when Vines::Services::VQL::Null
|
69
|
+
[lhs.sql]
|
70
|
+
else
|
71
|
+
[lhs.sql, rhs.sql]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
module Like
|
77
|
+
def js
|
78
|
+
"(%s.indexOf(%s) !== -1)" % [lhs.js, rhs.js]
|
79
|
+
end
|
80
|
+
def sql
|
81
|
+
"value like ?"
|
82
|
+
end
|
83
|
+
def params
|
84
|
+
[lhs.sql, "%#{rhs.sql}%"]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
module NotLike
|
89
|
+
def js
|
90
|
+
"(%s.indexOf(%s) === -1)" % [lhs.js, rhs.js]
|
91
|
+
end
|
92
|
+
def sql
|
93
|
+
"value not like ?"
|
94
|
+
end
|
95
|
+
def params
|
96
|
+
[lhs.sql, "%#{rhs.sql}%"]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
module StartsWith
|
101
|
+
def js
|
102
|
+
"(%s.lastIndexOf(%s, 0) === 0)" % [lhs.js, rhs.js]
|
103
|
+
end
|
104
|
+
def sql
|
105
|
+
"value like ?"
|
106
|
+
end
|
107
|
+
def params
|
108
|
+
[lhs.sql, "#{rhs.sql}%"]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
module EndsWith
|
113
|
+
def js
|
114
|
+
"(%s.match(%s + '$'))" % [lhs.js, rhs.js]
|
115
|
+
end
|
116
|
+
def sql
|
117
|
+
"value like ?"
|
118
|
+
end
|
119
|
+
def params
|
120
|
+
[lhs.sql, "%#{rhs.sql}"]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
module LtGt
|
125
|
+
def js
|
126
|
+
"(%s %s %s)" % [lhs.js, op, rhs.js]
|
127
|
+
end
|
128
|
+
def sql
|
129
|
+
"cast(value as number) %s ?" % op
|
130
|
+
end
|
131
|
+
def params
|
132
|
+
[lhs.sql, rhs.sql]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
module Group
|
137
|
+
def js
|
138
|
+
"(%s)" % expr.js
|
139
|
+
end
|
140
|
+
def sql
|
141
|
+
"(%s)" % expr.sql
|
142
|
+
end
|
143
|
+
def params
|
144
|
+
expr.params
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
module Terminal
|
149
|
+
def js
|
150
|
+
str.to_s
|
151
|
+
end
|
152
|
+
def sql
|
153
|
+
str.to_s
|
154
|
+
end
|
155
|
+
def params
|
156
|
+
[]
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
module Member
|
161
|
+
include Terminal
|
162
|
+
def js
|
163
|
+
"doc.ohai.#{str}"
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
module SingleQuoted
|
168
|
+
include Terminal
|
169
|
+
def js
|
170
|
+
"'%s'" % str
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
module DoubleQuoted
|
175
|
+
include Terminal
|
176
|
+
def js
|
177
|
+
'"%s"' % str
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
module Null
|
182
|
+
include Terminal
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
%w[
|
4
|
+
couchrest_model
|
5
|
+
logger
|
6
|
+
bcrypt
|
7
|
+
blather/client/client
|
8
|
+
cgi
|
9
|
+
citrus
|
10
|
+
em-http
|
11
|
+
fiber
|
12
|
+
fileutils
|
13
|
+
json
|
14
|
+
nokogiri
|
15
|
+
sqlite3
|
16
|
+
uri
|
17
|
+
|
18
|
+
vines/log
|
19
|
+
vines/daemon
|
20
|
+
vines/jid
|
21
|
+
vines/kit
|
22
|
+
|
23
|
+
vines/services/core_ext/blather
|
24
|
+
vines/services/core_ext/couchrest
|
25
|
+
|
26
|
+
vines/services/version
|
27
|
+
vines/services/connection
|
28
|
+
vines/services/config
|
29
|
+
vines/services/component
|
30
|
+
vines/services/priority_queue
|
31
|
+
vines/services/indexer
|
32
|
+
vines/services/throttle
|
33
|
+
|
34
|
+
vines/services/vql/vql
|
35
|
+
vines/services/vql/compiler
|
36
|
+
|
37
|
+
vines/services/command/init
|
38
|
+
vines/services/command/restart
|
39
|
+
vines/services/command/start
|
40
|
+
vines/services/command/stop
|
41
|
+
vines/services/command/views
|
42
|
+
|
43
|
+
vines/services/storage
|
44
|
+
vines/services/storage/couchdb
|
45
|
+
vines/services/storage/couchdb/fragment
|
46
|
+
vines/services/storage/couchdb/service
|
47
|
+
vines/services/storage/couchdb/system
|
48
|
+
vines/services/storage/couchdb/upload
|
49
|
+
vines/services/storage/couchdb/user
|
50
|
+
vines/services/storage/couchdb/vcard
|
51
|
+
|
52
|
+
vines/services/controller/base_controller
|
53
|
+
vines/services/controller/attributes_controller
|
54
|
+
vines/services/controller/disco_info_controller
|
55
|
+
vines/services/controller/uploads_controller
|
56
|
+
vines/services/controller/labels_controller
|
57
|
+
vines/services/controller/members_controller
|
58
|
+
vines/services/controller/messages_controller
|
59
|
+
vines/services/controller/probes_controller
|
60
|
+
vines/services/controller/services_controller
|
61
|
+
vines/services/controller/subscriptions_controller
|
62
|
+
vines/services/controller/systems_controller
|
63
|
+
vines/services/controller/transfers_controller
|
64
|
+
vines/services/controller/users_controller
|
65
|
+
].each {|f| require f }
|
66
|
+
|
67
|
+
module Vines
|
68
|
+
module Services
|
69
|
+
class Forbidden < StandardError; end
|
70
|
+
end
|
71
|
+
end
|