vines-services 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|