simplevoc-open 1.8.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/.document +5 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +26 -0
- data/LICENSE.txt +202 -0
- data/README.md +152 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/config.yml.sample +4 -0
- data/lib/simplevoc-open.rb +16 -0
- data/lib/simplevoc/open/base.rb +68 -0
- data/lib/simplevoc/open/client.rb +225 -0
- data/lib/simplevoc/open/configuration.rb +24 -0
- data/lib/simplevoc/open/exceptions.rb +40 -0
- data/lib/simplevoc/open/hash.rb +68 -0
- data/simplevoc-open.gemspec +88 -0
- data/test/config.yml +5 -0
- data/test/helper.rb +18 -0
- data/test/test_client.rb +240 -0
- data/test/test_hash.rb +37 -0
- data/test/test_non_strict_client.rb +102 -0
- data/test/test_simplevoc.rb +54 -0
- metadata +216 -0
@@ -0,0 +1,88 @@
|
|
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 = %q{simplevoc-open}
|
8
|
+
s.version = "1.8.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["triAGENS GmbH", "Oliver Kiessler"]
|
12
|
+
s.date = %q{2011-03-07}
|
13
|
+
s.description = %q{Easy installation, easy administration and simple to use is the focus of the SimpleVOC. It is a pure in-memory key/value store with a REST interface. Unlike other key/value stores the SimpleVOC provides a prefix search!}
|
14
|
+
s.email = %q{kiessler@inceedo.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.md",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"config.yml.sample",
|
28
|
+
"lib/simplevoc-open.rb",
|
29
|
+
"lib/simplevoc/open/base.rb",
|
30
|
+
"lib/simplevoc/open/client.rb",
|
31
|
+
"lib/simplevoc/open/configuration.rb",
|
32
|
+
"lib/simplevoc/open/exceptions.rb",
|
33
|
+
"lib/simplevoc/open/hash.rb",
|
34
|
+
"simplevoc-open.gemspec",
|
35
|
+
"test/config.yml",
|
36
|
+
"test/helper.rb",
|
37
|
+
"test/test_client.rb",
|
38
|
+
"test/test_hash.rb",
|
39
|
+
"test/test_non_strict_client.rb",
|
40
|
+
"test/test_simplevoc.rb"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://www.worldofvoc.com/products/simplevoc/summary/}
|
43
|
+
s.licenses = ["Apache License Version 2.0, January 2004"]
|
44
|
+
s.require_paths = ["lib"]
|
45
|
+
s.rubygems_version = %q{1.5.2}
|
46
|
+
s.summary = %q{A pure in-memory key/value store with a REST interface}
|
47
|
+
s.test_files = [
|
48
|
+
"test/helper.rb",
|
49
|
+
"test/test_client.rb",
|
50
|
+
"test/test_hash.rb",
|
51
|
+
"test/test_non_strict_client.rb",
|
52
|
+
"test/test_simplevoc.rb"
|
53
|
+
]
|
54
|
+
|
55
|
+
if s.respond_to? :specification_version then
|
56
|
+
s.specification_version = 3
|
57
|
+
|
58
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
59
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0.7.4"])
|
60
|
+
s.add_runtime_dependency(%q<json>, [">= 1.4.6"])
|
61
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
62
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
63
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
64
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
65
|
+
s.add_runtime_dependency(%q<httparty>, [">= 0.7.4"])
|
66
|
+
s.add_runtime_dependency(%q<json>, [">= 1.4.6"])
|
67
|
+
else
|
68
|
+
s.add_dependency(%q<httparty>, [">= 0.7.4"])
|
69
|
+
s.add_dependency(%q<json>, [">= 1.4.6"])
|
70
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
71
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
72
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
73
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
74
|
+
s.add_dependency(%q<httparty>, [">= 0.7.4"])
|
75
|
+
s.add_dependency(%q<json>, [">= 1.4.6"])
|
76
|
+
end
|
77
|
+
else
|
78
|
+
s.add_dependency(%q<httparty>, [">= 0.7.4"])
|
79
|
+
s.add_dependency(%q<json>, [">= 1.4.6"])
|
80
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
81
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
82
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
83
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
84
|
+
s.add_dependency(%q<httparty>, [">= 0.7.4"])
|
85
|
+
s.add_dependency(%q<json>, [">= 1.4.6"])
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
data/test/config.yml
ADDED
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
require 'shoulda'
|
12
|
+
|
13
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
require 'simplevoc-open'
|
16
|
+
|
17
|
+
class Test::Unit::TestCase
|
18
|
+
end
|
data/test/test_client.rb
ADDED
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
class TestClient < Test::Unit::TestCase
|
5
|
+
should "fail to connect" do
|
6
|
+
my_client = Simplevoc::Open::Client.new('host' => 'localhost', 'port' => '111111111')
|
7
|
+
assert_raise Simplevoc::Open::ConnectionRefusedException do
|
8
|
+
my_client.insert('a', 'b')
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
should "insert value for key a" do
|
13
|
+
assert client.flush
|
14
|
+
assert client.insert("a", "b")
|
15
|
+
|
16
|
+
sv_response = client.get("a")
|
17
|
+
assert_equal sv_response.class, Hash
|
18
|
+
assert_not_nil sv_response['value']
|
19
|
+
assert_equal sv_response['value'], 'b'
|
20
|
+
|
21
|
+
sv_response = client.get('a', false)
|
22
|
+
assert_equal sv_response, 'b'
|
23
|
+
|
24
|
+
assert_raise Simplevoc::Open::ValueExistsException do
|
25
|
+
client.insert('a', 'b')
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
should 'fail inserting value when the value is empty' do
|
30
|
+
assert_raise Simplevoc::Open::EmptyValueException do
|
31
|
+
client.insert('a', nil)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'fail inserting value when the key is empty' do
|
36
|
+
assert_raise Simplevoc::Open::EmptyKeyException do
|
37
|
+
client.insert(nil, nil)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
should 'insert value for key b with extended value from hash' do
|
42
|
+
assert client.insert_with_extended_values('b', 'c', {'name' => 'testvalue'})
|
43
|
+
|
44
|
+
sv_response = client.get("b")
|
45
|
+
assert_equal sv_response.class, Hash
|
46
|
+
assert_not_nil sv_response['value']
|
47
|
+
assert_equal sv_response['value'], 'c'
|
48
|
+
assert_not_nil sv_response['created']
|
49
|
+
assert_not_nil sv_response['flags']
|
50
|
+
assert_not_nil sv_response['extended-values']
|
51
|
+
assert sv_response['extended-values'].class, Hash
|
52
|
+
assert_not_nil sv_response['extended-values']['name']
|
53
|
+
assert_equal sv_response['extended-values']['name'], 'testvalue'
|
54
|
+
end
|
55
|
+
|
56
|
+
should 'fail inserting unknown extended key value' do
|
57
|
+
assert client.insert_with_extended_values('b2', 'c', '{"name2":"testvalue"}')
|
58
|
+
|
59
|
+
sv_response = client.get("b2")
|
60
|
+
assert_equal sv_response.class, Hash
|
61
|
+
assert_not_nil sv_response['extended-values']
|
62
|
+
assert_nil sv_response['extended-values']['name']
|
63
|
+
end
|
64
|
+
|
65
|
+
should "insert or update value for key c" do
|
66
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
67
|
+
client.get('c')
|
68
|
+
end
|
69
|
+
|
70
|
+
assert client.insert_or_update('c', 'd')
|
71
|
+
sv_response = client.get('c')
|
72
|
+
assert_not_nil sv_response
|
73
|
+
assert_equal sv_response['value'], 'd'
|
74
|
+
|
75
|
+
assert client.insert_or_update('c', 'd2')
|
76
|
+
sv_response = client.get('c')
|
77
|
+
assert_not_nil sv_response
|
78
|
+
assert_equal sv_response['value'], 'd2'
|
79
|
+
end
|
80
|
+
|
81
|
+
should 'fail creating or updating value when the value is empty' do
|
82
|
+
assert_raise Simplevoc::Open::EmptyValueException do
|
83
|
+
client.insert_or_update('a', nil)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
should 'fail creating or updating value when the key is empty' do
|
88
|
+
assert_raise Simplevoc::Open::EmptyKeyException do
|
89
|
+
client.insert_or_update(nil, nil)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
should "update value for key a" do
|
94
|
+
assert client.update('a', 'c')
|
95
|
+
sv_response = client.get('a')
|
96
|
+
assert_equal sv_response['value'], 'c'
|
97
|
+
end
|
98
|
+
|
99
|
+
should 'fail when trying to update a value for a missing key' do
|
100
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
101
|
+
client.update('a2', 'b2')
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
should 'fail updating when the value is empty' do
|
106
|
+
assert_raise Simplevoc::Open::EmptyValueException do
|
107
|
+
client.update('a2', nil)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
should 'fail updating when the key is empty' do
|
112
|
+
assert_raise Simplevoc::Open::EmptyKeyException do
|
113
|
+
client.update(nil, nil)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
should 'delete a value for a key' do
|
118
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
119
|
+
client.get('d')
|
120
|
+
end
|
121
|
+
|
122
|
+
assert client.insert('d', 'e')
|
123
|
+
|
124
|
+
sv_response = client.get('d')
|
125
|
+
assert_equal sv_response['value'], 'e'
|
126
|
+
assert client.delete('d')
|
127
|
+
|
128
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
129
|
+
client.get('d')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
should 'fail deleting when the key does not exist' do
|
134
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
135
|
+
client.delete('d2')
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
should 'fail deleting when the key is empty' do
|
140
|
+
assert_raise Simplevoc::Open::EmptyKeyException do
|
141
|
+
client.delete(nil)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
should 'get response hash with value for key e' do
|
146
|
+
assert client.insert('e', 'f')
|
147
|
+
|
148
|
+
sv_response = client.get('e')
|
149
|
+
assert_equal sv_response['value'], 'f'
|
150
|
+
assert_not_nil sv_response['created']
|
151
|
+
assert_not_nil sv_response['flags']
|
152
|
+
end
|
153
|
+
|
154
|
+
should 'get value only for key f' do
|
155
|
+
assert client.insert('f', 'g')
|
156
|
+
assert_equal client.get('f', false), 'g'
|
157
|
+
end
|
158
|
+
|
159
|
+
should 'fail getting when the key does not exist' do
|
160
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
161
|
+
client.get('e2')
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
should 'fail getting when the key is empty' do
|
166
|
+
assert_raise Simplevoc::Open::EmptyKeyException do
|
167
|
+
client.get(nil)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
should 'get keys for a given prefix' do
|
172
|
+
assert client.insert('g', 'h')
|
173
|
+
assert client.insert('gg', 'hh')
|
174
|
+
assert client.insert('ggg', 'ggg')
|
175
|
+
|
176
|
+
keys = client.keys('g')
|
177
|
+
assert_not_nil keys
|
178
|
+
assert_equal keys.size, 3
|
179
|
+
assert keys.include?('g')
|
180
|
+
assert keys.include?('gg')
|
181
|
+
assert keys.include?('ggg')
|
182
|
+
|
183
|
+
keys = client.keys('gg')
|
184
|
+
assert_not_nil keys
|
185
|
+
assert_equal keys.size, 2
|
186
|
+
assert keys.include?('gg')
|
187
|
+
assert keys.include?('ggg')
|
188
|
+
|
189
|
+
keys = client.keys('ggg')
|
190
|
+
assert_not_nil keys
|
191
|
+
assert_equal keys.size, 1
|
192
|
+
assert keys.include?('ggg')
|
193
|
+
end
|
194
|
+
|
195
|
+
should 'fail when a no key for a given prefix can be found' do
|
196
|
+
assert_raise Simplevoc::Open::PrefixNotFoundException do
|
197
|
+
client.keys('test')
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
should 'flush all keys' do
|
202
|
+
assert client.insert('h', 'i')
|
203
|
+
assert_equal client.get('h', false), 'i'
|
204
|
+
assert client.flush
|
205
|
+
assert_raise Simplevoc::Open::KeyNotFoundException do
|
206
|
+
client.get('h')
|
207
|
+
end
|
208
|
+
# I know this doesn't really prove the flushing...
|
209
|
+
end
|
210
|
+
|
211
|
+
should 'get the server version number' do
|
212
|
+
assert_not_nil client.server_version
|
213
|
+
end
|
214
|
+
|
215
|
+
should 'get the server info including version number' do
|
216
|
+
info = client.server_info
|
217
|
+
assert_not_nil info
|
218
|
+
assert_not_nil info['version']
|
219
|
+
assert_not_nil info['server']
|
220
|
+
end
|
221
|
+
|
222
|
+
should 'create a correct header options hash' do
|
223
|
+
test_date_time_object = Time.now.utc.iso8601
|
224
|
+
extra_options = client.extra_options(test_date_time_object, 1, test_date_time_object, test_date_time_object)
|
225
|
+
assert_not_nil extra_options
|
226
|
+
assert extra_options.include?(:headers)
|
227
|
+
assert_equal extra_options[:headers]['x-voc-expires'], test_date_time_object.to_s
|
228
|
+
assert_equal extra_options[:headers]['x-voc-flags'], "1"
|
229
|
+
assert_equal extra_options[:headers]['x-voc-delete-time'], test_date_time_object.to_s
|
230
|
+
assert_equal extra_options[:headers]['x-voc-flush-delay'], test_date_time_object.to_s
|
231
|
+
end
|
232
|
+
|
233
|
+
private
|
234
|
+
def client
|
235
|
+
port = ENV['SIMPLEVOC_PORT'] || '12345'
|
236
|
+
host = ENV['SIMPLEVOC_HOST'] || 'localhost'
|
237
|
+
@client ||= Simplevoc::Open::Client.new('host' => host, 'port' => port, 'log_level' => Logger::DEBUG, 'strict_mode' => true)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
data/test/test_hash.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
class TestHash < Test::Unit::TestCase
|
5
|
+
should 'insert/get a value' do
|
6
|
+
assert hash["a"] = "b"
|
7
|
+
assert_equal hash["a"], "b"
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'update a value' do
|
11
|
+
assert_equal hash["a"], "b"
|
12
|
+
assert hash["a"] = "b2"
|
13
|
+
assert_equal hash["a"], "b2"
|
14
|
+
end
|
15
|
+
|
16
|
+
should 'check for the existence of a key' do
|
17
|
+
hash["x"] = "y"
|
18
|
+
assert hash.has_key?("x")
|
19
|
+
end
|
20
|
+
|
21
|
+
should 'get multiple values at once' do
|
22
|
+
hash["x"] = "y"
|
23
|
+
hash["x2"] = "y2"
|
24
|
+
values_hash = hash.values_at(["x", "x2"])
|
25
|
+
assert_not_nil values_hash
|
26
|
+
assert_equal values_hash["x"], "y"
|
27
|
+
assert_equal values_hash["x2"], "y2"
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def hash
|
32
|
+
port = ENV['SIMPLEVOC_PORT'] || '12345'
|
33
|
+
host = ENV['SIMPLEVOC_HOST'] || 'localhost'
|
34
|
+
@hash ||= Simplevoc::Open::Hash.new('host' => host, 'port' => port, :log_level => Logger::DEBUG)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'logger'
|
3
|
+
|
4
|
+
class TestNonStrictClient < Test::Unit::TestCase
|
5
|
+
should "insert value for key a" do
|
6
|
+
assert client.flush
|
7
|
+
assert client.insert("a", "b")
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'fail inserting value when the value is empty' do
|
11
|
+
assert !client.insert('a', nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'fail inserting value when the key is empty' do
|
15
|
+
assert !client.insert(nil, nil)
|
16
|
+
end
|
17
|
+
|
18
|
+
should "fail inserting value for key a when value for key a exists" do
|
19
|
+
assert !client.insert('a', 'b')
|
20
|
+
end
|
21
|
+
|
22
|
+
should "insert or update value for key c" do
|
23
|
+
assert !client.get('c')
|
24
|
+
|
25
|
+
assert client.insert_or_update('c', 'd')
|
26
|
+
sv_response = client.get('c')
|
27
|
+
assert_not_nil sv_response
|
28
|
+
assert_equal sv_response['value'], 'd'
|
29
|
+
|
30
|
+
assert client.insert_or_update('c', 'd2')
|
31
|
+
sv_response = client.get('c')
|
32
|
+
assert_not_nil sv_response
|
33
|
+
assert_equal sv_response['value'], 'd2'
|
34
|
+
end
|
35
|
+
|
36
|
+
should 'fail creating or updating value when the value is empty' do
|
37
|
+
assert !client.insert_or_update('a', nil)
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'fail creating or updating value when the key is empty' do
|
41
|
+
assert !client.insert_or_update(nil, nil)
|
42
|
+
end
|
43
|
+
|
44
|
+
should 'fail when trying to update a value for a missing key' do
|
45
|
+
assert !client.update('a2', 'b2')
|
46
|
+
end
|
47
|
+
|
48
|
+
should 'fail updating when the value is empty' do
|
49
|
+
assert !client.update('a2', nil)
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'fail updating when the key is empty' do
|
53
|
+
assert !client.update(nil, nil)
|
54
|
+
end
|
55
|
+
|
56
|
+
should 'delete a value for a key' do
|
57
|
+
assert_nil client.get('d')
|
58
|
+
|
59
|
+
assert client.insert('d', 'e')
|
60
|
+
|
61
|
+
sv_response = client.get('d')
|
62
|
+
assert_equal sv_response['value'], 'e'
|
63
|
+
assert client.delete('d')
|
64
|
+
|
65
|
+
assert_nil client.get('d')
|
66
|
+
end
|
67
|
+
|
68
|
+
should 'fail deleting when the key does not exist' do
|
69
|
+
assert !client.delete('d2')
|
70
|
+
end
|
71
|
+
|
72
|
+
should 'fail deleting when the key is empty' do
|
73
|
+
assert !client.delete(nil)
|
74
|
+
end
|
75
|
+
|
76
|
+
should 'fail getting when the key does not exist' do
|
77
|
+
assert !client.get('e2')
|
78
|
+
end
|
79
|
+
|
80
|
+
should 'fail getting when the key is empty' do
|
81
|
+
assert !client.get(nil)
|
82
|
+
end
|
83
|
+
|
84
|
+
should 'flush all keys' do
|
85
|
+
assert client.insert('h', 'i')
|
86
|
+
assert_equal client.get('h', false), 'i'
|
87
|
+
assert client.flush
|
88
|
+
assert !client.get('h')
|
89
|
+
end
|
90
|
+
|
91
|
+
should 'fail when a no key for a given prefix can be found' do
|
92
|
+
assert_nil = client.keys('test')
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
def client
|
97
|
+
port = ENV['SIMPLEVOC_PORT'] || '12345'
|
98
|
+
host = ENV['SIMPLEVOC_HOST'] || 'localhost'
|
99
|
+
@client ||= Simplevoc::Open::Client.new('host' => host, 'port' => port, 'log_level' => Logger::DEBUG, 'strict_mode' => false)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|