simply_stored 0.3.9 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/CHANGELOG.md +38 -0
  2. data/README.md +45 -24
  3. data/lib/simply_stored/couch/association_property.rb +27 -0
  4. data/lib/simply_stored/couch/belongs_to.rb +5 -7
  5. data/lib/simply_stored/couch/finders.rb +5 -1
  6. data/lib/simply_stored/couch/has_and_belongs_to_many.rb +202 -0
  7. data/lib/simply_stored/couch/has_many.rb +6 -51
  8. data/lib/simply_stored/couch/has_one.rb +4 -29
  9. data/lib/simply_stored/couch/properties.rb +11 -0
  10. data/lib/simply_stored/couch.rb +38 -2
  11. data/lib/simply_stored/instance_methods.rb +68 -29
  12. data/lib/simply_stored.rb +3 -1
  13. data/test/{couchdb/couch_active_model_compatibility_test.rb → active_model_compatibility_test.rb} +2 -2
  14. data/test/{couchdb/couch_belongs_to_test.rb → belongs_to_test.rb} +13 -3
  15. data/test/{couchdb/couch_conflict_handling_test.rb → conflict_handling_test.rb} +3 -3
  16. data/test/{couchdb/couch_finder_test.rb → finder_test.rb} +8 -3
  17. data/test/fixtures/couch.rb +55 -0
  18. data/test/has_and_belongs_to_many_test.rb +639 -0
  19. data/test/{couchdb/couch_has_many_test.rb → has_many_test.rb} +13 -3
  20. data/test/{couchdb/couch_has_one_test.rb → has_one_test.rb} +13 -3
  21. data/test/{couchdb/couch_instance_lifecycle_test.rb → instance_lifecycle_test.rb} +3 -3
  22. data/test/{couchdb/couch_mass_assignment_protection_test.rb → mass_assignment_protection_test.rb} +3 -3
  23. data/test/{couchdb/couch_s3_test.rb → s3_test.rb} +3 -3
  24. data/test/{couchdb/couch_soft_deletable_test.rb → soft_deletable_test.rb} +3 -3
  25. data/test/test_helper.rb +1 -5
  26. data/test/{couchdb/couch_validations_test.rb → validations_test.rb} +3 -3
  27. data/test/{couchdb/custom_views_test.rb → views_test.rb} +3 -3
  28. metadata +36 -234
  29. data/lib/simply_stored/simpledb/associations.rb +0 -215
  30. data/lib/simply_stored/simpledb/attributes.rb +0 -173
  31. data/lib/simply_stored/simpledb/storag.rb +0 -85
  32. data/lib/simply_stored/simpledb/validations.rb +0 -88
  33. data/lib/simply_stored/simpledb.rb +0 -216
  34. data/test/fixtures/simpledb/item.rb +0 -11
  35. data/test/fixtures/simpledb/item_daddy.rb +0 -8
  36. data/test/fixtures/simpledb/log_item.rb +0 -3
  37. data/test/fixtures/simpledb/namespace_bar.rb +0 -5
  38. data/test/fixtures/simpledb/namespace_foo.rb +0 -7
  39. data/test/fixtures/simpledb/protected_item.rb +0 -3
  40. data/test/simply_stored_simpledb_test.rb +0 -1376
  41. data/test/vendor/dhaka-2.2.1/lib/dhaka/dot/dot.rb +0 -29
  42. data/test/vendor/dhaka-2.2.1/lib/dhaka/evaluator/evaluator.rb +0 -133
  43. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/closure_hash.rb +0 -15
  44. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar.rb +0 -240
  45. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/grammar_symbol.rb +0 -27
  46. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/precedence.rb +0 -19
  47. data/test/vendor/dhaka-2.2.1/lib/dhaka/grammar/production.rb +0 -36
  48. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/accept_actions.rb +0 -36
  49. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/alphabet.rb +0 -21
  50. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/compiled_lexer.rb +0 -46
  51. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/dfa.rb +0 -121
  52. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexeme.rb +0 -32
  53. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer.rb +0 -70
  54. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/lexer_run.rb +0 -78
  55. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_grammar.rb +0 -392
  56. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_parser.rb +0 -2010
  57. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/regex_tokenizer.rb +0 -14
  58. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/specification.rb +0 -96
  59. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state.rb +0 -68
  60. data/test/vendor/dhaka-2.2.1/lib/dhaka/lexer/state_machine.rb +0 -37
  61. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/action.rb +0 -55
  62. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/channel.rb +0 -58
  63. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/compiled_parser.rb +0 -51
  64. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/conflict.rb +0 -54
  65. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/item.rb +0 -42
  66. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_result.rb +0 -50
  67. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parse_tree.rb +0 -66
  68. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser.rb +0 -165
  69. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_methods.rb +0 -11
  70. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_run.rb +0 -39
  71. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/parser_state.rb +0 -74
  72. data/test/vendor/dhaka-2.2.1/lib/dhaka/parser/token.rb +0 -22
  73. data/test/vendor/dhaka-2.2.1/lib/dhaka/runtime.rb +0 -51
  74. data/test/vendor/dhaka-2.2.1/lib/dhaka/tokenizer/tokenizer.rb +0 -190
  75. data/test/vendor/dhaka-2.2.1/lib/dhaka.rb +0 -62
  76. data/test/vendor/dhaka-2.2.1/test/all_tests.rb +0 -5
  77. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator.rb +0 -64
  78. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_evaluator_test.rb +0 -43
  79. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar.rb +0 -41
  80. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_grammar_test.rb +0 -9
  81. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_test_methods.rb +0 -9
  82. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer.rb +0 -39
  83. data/test/vendor/dhaka-2.2.1/test/arithmetic/arithmetic_tokenizer_test.rb +0 -38
  84. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_evaluator.rb +0 -43
  85. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar.rb +0 -24
  86. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_grammar_test.rb +0 -30
  87. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_lexer_specification.rb +0 -23
  88. data/test/vendor/dhaka-2.2.1/test/arithmetic_precedence/arithmetic_precedence_parser_test.rb +0 -33
  89. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_grammar.rb +0 -23
  90. data/test/vendor/dhaka-2.2.1/test/brackets/bracket_tokenizer.rb +0 -22
  91. data/test/vendor/dhaka-2.2.1/test/brackets/brackets_test.rb +0 -28
  92. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver.rb +0 -46
  93. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_driver_test.rb +0 -276
  94. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator.rb +0 -284
  95. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_evaluator_test.rb +0 -38
  96. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_grammar.rb +0 -104
  97. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer.rb +0 -109
  98. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_specification.rb +0 -37
  99. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_lexer_test.rb +0 -58
  100. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser.rb +0 -879
  101. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_parser_test.rb +0 -55
  102. data/test/vendor/dhaka-2.2.1/test/chittagong/chittagong_test.rb +0 -170
  103. data/test/vendor/dhaka-2.2.1/test/core/another_lalr_but_not_slr_grammar.rb +0 -20
  104. data/test/vendor/dhaka-2.2.1/test/core/compiled_parser_test.rb +0 -44
  105. data/test/vendor/dhaka-2.2.1/test/core/dfa_test.rb +0 -170
  106. data/test/vendor/dhaka-2.2.1/test/core/evaluator_test.rb +0 -22
  107. data/test/vendor/dhaka-2.2.1/test/core/grammar_test.rb +0 -83
  108. data/test/vendor/dhaka-2.2.1/test/core/lalr_but_not_slr_grammar.rb +0 -19
  109. data/test/vendor/dhaka-2.2.1/test/core/lexer_test.rb +0 -139
  110. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar.rb +0 -7
  111. data/test/vendor/dhaka-2.2.1/test/core/malformed_grammar_test.rb +0 -8
  112. data/test/vendor/dhaka-2.2.1/test/core/nullable_grammar.rb +0 -21
  113. data/test/vendor/dhaka-2.2.1/test/core/parse_result_test.rb +0 -44
  114. data/test/vendor/dhaka-2.2.1/test/core/parser_state_test.rb +0 -24
  115. data/test/vendor/dhaka-2.2.1/test/core/parser_test.rb +0 -131
  116. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar.rb +0 -17
  117. data/test/vendor/dhaka-2.2.1/test/core/precedence_grammar_test.rb +0 -9
  118. data/test/vendor/dhaka-2.2.1/test/core/rr_conflict_grammar.rb +0 -21
  119. data/test/vendor/dhaka-2.2.1/test/core/simple_grammar.rb +0 -22
  120. data/test/vendor/dhaka-2.2.1/test/core/sr_conflict_grammar.rb +0 -16
  121. data/test/vendor/dhaka-2.2.1/test/dhaka_test_helper.rb +0 -17
  122. data/test/vendor/dhaka-2.2.1/test/fake_logger.rb +0 -17
  123. data/test/vendor/simplerdb-0.2/lib/simplerdb/client_exception.rb +0 -10
  124. data/test/vendor/simplerdb-0.2/lib/simplerdb/db.rb +0 -146
  125. data/test/vendor/simplerdb-0.2/lib/simplerdb/query_language.rb +0 -266
  126. data/test/vendor/simplerdb-0.2/lib/simplerdb/server.rb +0 -33
  127. data/test/vendor/simplerdb-0.2/lib/simplerdb/servlet.rb +0 -191
  128. data/test/vendor/simplerdb-0.2/lib/simplerdb.rb +0 -3
  129. data/test/vendor/simplerdb-0.2/test/functional_test.rb +0 -81
  130. data/test/vendor/simplerdb-0.2/test/query_evaluator_test.rb +0 -73
  131. data/test/vendor/simplerdb-0.2/test/query_parser_test.rb +0 -64
  132. data/test/vendor/simplerdb-0.2/test/simplerdb_test.rb +0 -80
@@ -1,266 +0,0 @@
1
- require 'rubygems'
2
- require 'dhaka'
3
- require 'set'
4
-
5
- module SimplerDB
6
- # Uses the lexer/parser/evaluator to perform the query and do simple paging
7
- class QueryExecutor
8
- ERROR_MARKER = ">>>"
9
-
10
- def initialize
11
- @lexer = Dhaka::Lexer.new(QueryLexerSpec)
12
- @parser = Dhaka::Parser.new(QueryGrammar)
13
- end
14
-
15
- # Execute the query
16
- def do_query(query, domain, max = 100, token = 0)
17
- parse_result = @parser.parse(@lexer.lex(query))
18
- token = 0 if token.nil?
19
-
20
- case parse_result
21
- when Dhaka::TokenizerErrorResult
22
- raise tokenize_error_message(parse_result.unexpected_char_index, query)
23
- when Dhaka::ParseErrorResult
24
- raise parse_error_message(parse_result.unexpected_token, query)
25
- end
26
-
27
- items = QueryEvaluator.new(domain).evaluate(parse_result)
28
- results = []
29
- count = 0
30
- items.each do |item|
31
- break if results.size == max
32
- results << item if count >= token
33
- count += 1
34
- end
35
-
36
- if (count == items.size)
37
- return results,nil
38
- else
39
- return results,count
40
- end
41
- end
42
-
43
- # From dhaka examples
44
- def parse_error_message(unexpected_token, program)
45
- if unexpected_token.symbol_name == Dhaka::END_SYMBOL_NAME
46
- "Unexpected end of file."
47
- else
48
- "Unexpected token #{unexpected_token.symbol_name}:\n#{program.dup.insert(unexpected_token.input_position - 1, ERROR_MARKER)}"
49
- end
50
- end
51
-
52
- def tokenize_error_message(unexpected_char_index, program)
53
- "Unexpected character #{program[unexpected_char_index - 1].chr}:\n#{program.dup.insert(unexpected_char_index - 1, ERROR_MARKER)}"
54
- end
55
-
56
- def evaluation_error_message(evaluation_result, program)
57
- "#{evaluation_result.exception}:\n#{program.dup.insert(evaluation_result.node.tokens[0].input_position, ERROR_MARKER)}"
58
- end
59
-
60
- end
61
-
62
- # The SimpleDB query language grammar, as defined at
63
- # http://docs.amazonwebservices.com/AmazonSimpleDB/2007-11-07/DeveloperGuide/SDB_API_Query.html
64
- class QueryGrammar < Dhaka::Grammar
65
- for_symbol(Dhaka::START_SYMBOL_NAME) do
66
- start %w| predicates |
67
- end
68
-
69
- for_symbol('predicates') do
70
- single_predicate %w| predicate |
71
- not_predicate %w| not predicate |
72
- intersection %w| predicate intersection predicates |
73
- not_intersection %w| not predicate intersection predicates |
74
- union %w| predicate union predicates |
75
- not_union %w| not predicate union predicates |
76
- end
77
-
78
- for_symbol('predicate') do
79
- attribute_comparison %w| [ attribute_comparison ] |
80
- end
81
-
82
- for_symbol('attribute_comparison') do
83
- single_comparison %w| identifier comp_op constant |
84
- not_comparison %w| not identifier comp_op constant |
85
- and_comparison %w| identifier comp_op constant and attribute_comparison |
86
- not_and_comparison %w| not identifier comp_op constant and attribute_comparison |
87
- or_comparison %w| identifier comp_op constant or attribute_comparison |
88
- not_or_comparison %w| not identifier comp_op constant or attribute_comparison |
89
- end
90
-
91
- for_symbol('comp_op') do
92
- equal %w| = |
93
- greater_than %w| > |
94
- less_than %w| < |
95
- greater_or_equal %w| >= |
96
- less_or_equal %w| <= |
97
- not_equal %w| != |
98
- starts_with %w| starts-with |
99
- end
100
-
101
- for_symbol('identifier') do
102
- identifier %w| quoted_string |
103
- end
104
-
105
- for_symbol('constant') do
106
- constant %w| quoted_string |
107
- end
108
-
109
- end
110
-
111
- # The lexer for the query language.
112
- class QueryLexerSpec < Dhaka::LexerSpecification
113
-
114
- %w| = > < >= <= != starts-with |.each do |op|
115
- for_pattern(op) do
116
- create_token(op)
117
- end
118
- end
119
-
120
- for_pattern('\[') do
121
- create_token('[')
122
- end
123
-
124
- for_pattern('\]') do
125
- create_token(']')
126
- end
127
-
128
- for_pattern('\s+') do
129
- # ignore whitespace
130
- end
131
-
132
- KEYWORDS = %w| not and or union intersection |
133
- KEYWORDS.each do |keyword|
134
- for_pattern(keyword) do
135
- create_token(keyword)
136
- end
137
- end
138
-
139
- for_pattern("'(\\\\'|[^'])+'") do
140
- create_token 'quoted_string'
141
- end
142
-
143
- end
144
-
145
- # The query evaluator. This class acts on the parse tree and will return
146
- # a list of item names that match the query from the evaluate method.
147
- class QueryEvaluator < Dhaka::Evaluator
148
- self.grammar = QueryGrammar
149
-
150
- def initialize(domain = nil)
151
- @domain = domain
152
- @predicate_identifier = nil
153
- @all_items = nil
154
- end
155
-
156
- define_evaluation_rules do
157
-
158
- for_single_predicate do
159
- evaluate(child_nodes[0])
160
- end
161
-
162
- for_not_predicate do
163
- results = evaluate(child_nodes[1])
164
- all_items.difference(results)
165
- end
166
-
167
- for_intersection do
168
- results = evaluate(child_nodes[0])
169
- results.intersection(evaluate(child_nodes[2]))
170
- end
171
-
172
- # TODO Nots are probably not handled correctly. Need to play with AWS to find out for sure.
173
- for_not_intersection do
174
- results = evaluate(child_nodes[1])
175
- all_items.difference(results.intersection(evaluate(child_nodes[3])))
176
- end
177
-
178
- for_union do
179
- results = evaluate(child_nodes[0])
180
- results.union(evaluate(child_nodes[2]))
181
- end
182
-
183
- for_not_union do
184
- results = evaluate(child_nodes[1])
185
- all_items.difference(results.union(evaluate(child_nodes[3])))
186
- end
187
-
188
- for_attribute_comparison do
189
- evaluate(child_nodes[1])
190
- end
191
-
192
- for_single_comparison do
193
- do_comparison(evaluate(child_nodes[0]), evaluate(child_nodes[1]), evaluate(child_nodes[2]))
194
- end
195
-
196
- for_not_comparison do
197
- do_comparison(evaluate(child_nodes[1]), evaluate(child_nodes[2]), evaluate(child_nodes[3]), true)
198
- end
199
-
200
- for_and_comparison do
201
- results = do_comparison(evaluate(child_nodes[0]), evaluate(child_nodes[1]), evaluate(child_nodes[2]))
202
- results.intersection(evaluate(child_nodes[4]))
203
- end
204
-
205
- for_not_and_comparison do
206
- results = do_comparison(evaluate(child_nodes[1]), evaluate(child_nodes[2]), evaluate(child_nodes[3]), true)
207
- results.intersection(evaluate(child_nodes[5]))
208
- end
209
-
210
- for_or_comparison do
211
- results = do_comparison(evaluate(child_nodes[0]), evaluate(child_nodes[1]), evaluate(child_nodes[2]))
212
- results.union(evaluate(child_nodes[4]))
213
- end
214
-
215
- for_not_or_comparison do
216
- results = do_comparison(evaluate(child_nodes[1]), evaluate(child_nodes[2]), evaluate(child_nodes[3]), true)
217
- results.union(evaluate(child_nodes[5]))
218
- end
219
-
220
- for_equal { lambda { |v1, v2| v1 == v2 } }
221
- for_greater_than { lambda { |v1, v2| v1 > v2 } }
222
- for_less_than { lambda { |v1, v2| v1 < v2 } }
223
- for_greater_or_equal { lambda { |v1, v2| v1 >= v2 } }
224
- for_less_or_equal { lambda { |v1, v2| v1 <= v2 } }
225
- # TODO ['a1' != 'v2'] should return false if a1 has values v1 AND v2
226
- for_not_equal { lambda { |v1, v2| v1 != v2 } }
227
- for_starts_with { lambda { |v1, v2| v2[0...v1.length] == v1 } }
228
-
229
- for_identifier { val(child_nodes[0]) }
230
- for_constant { val(child_nodes[0]) }
231
- end
232
-
233
- def val(node)
234
- node.token.value.to_s[1..-2]
235
- end
236
-
237
- def all_items
238
- unless @all_items
239
- @all_items = @domain.items.collect { |k,v| k }.to_set
240
- end
241
-
242
- return @all_items
243
- end
244
-
245
- # Apply the given comparison params to every item in the domain
246
- def do_comparison(identifier, op, constant, negate = false)
247
- results = Set.new
248
-
249
- if @domain
250
- @domain.items.each_value do |item|
251
- attrs = item.attributes[identifier]
252
-
253
- attrs.each do |attr|
254
- match = op.call(constant, attr.value)
255
- if (match && !negate) || (negate && !match)
256
- results << item
257
- break
258
- end
259
- end
260
- end
261
- end
262
-
263
- results
264
- end
265
- end
266
- end
@@ -1,33 +0,0 @@
1
- require 'rubygems'
2
- require 'simplerdb/servlet'
3
- require 'webrick'
4
-
5
- # Runs the SimplerDB server
6
- module SimplerDB
7
- class Server
8
-
9
- # Create the server running on the given port
10
- def initialize(port = nil)
11
- @port = port || 8087
12
- end
13
-
14
- # Run the server on the configured port.
15
- def start
16
- config = { :Port => @port, :AccessLog => [] }
17
- @server = WEBrick::HTTPServer.new(config)
18
- @server.mount("/", SimplerDB::RESTServlet)
19
-
20
- ['INT', 'TERM'].each do |signal|
21
- trap(signal) { @server.shutdown }
22
- end
23
-
24
- @server.start
25
- end
26
-
27
- # Shut down the server
28
- def shutdown
29
- @server.shutdown
30
- end
31
-
32
- end
33
- end
@@ -1,191 +0,0 @@
1
- require 'rubygems'
2
- require 'webrick'
3
- require 'builder'
4
- require 'simplerdb/db'
5
- require 'simplerdb/client_exception'
6
-
7
- module SimplerDB
8
-
9
- # A WEBrick servlet to handle API requests over REST
10
- class RESTServlet < WEBrick::HTTPServlet::AbstractServlet
11
-
12
- def do_GET(req, res)
13
- action = req.query["Action"]
14
-
15
- begin
16
- if action.nil?
17
- # Raise an error
18
- raise ClientException.new(:MissingAction, "No action was supplied with this request")
19
- else
20
- # Process the action appropriately
21
- xml = send("do_#{action.downcase}", req)
22
- res.body = xml
23
- res.status = 200
24
- end
25
- rescue ClientException => e
26
- res.body = error_xml(e.code, e.msg)
27
- res.status = 400 # What is the right status?
28
- end
29
-
30
- res['content-type'] = 'text/xml'
31
- end
32
-
33
- alias do_POST do_GET
34
- alias do_DELETE do_GET
35
-
36
- # Handle CreateDomain requests
37
- def do_createdomain(req)
38
- name = req.query["DomainName"]
39
- DB.instance.create_domain(name)
40
- build_result("CreateDomain")
41
- end
42
-
43
- # Handle ListDomains requests
44
- def do_listdomains(req)
45
- max = req.query["MaxNumberOfDomains"]
46
- next_token = req.query["NextToken"]
47
-
48
- max = max.to_i if max
49
- domains,token = DB.instance.list_domains(max, next_token)
50
-
51
- build_result("ListDomains") do |doc|
52
- doc.ListDomainsResult do
53
- if domains
54
- domains.each do |domain|
55
- doc.DomainName domain
56
- end
57
- end
58
-
59
- if token
60
- doc.NextToken token
61
- end
62
- end
63
- end
64
- end
65
-
66
-
67
- # DeleteDomains requests
68
- def do_deletedomain(req)
69
- name = req.query["DomainName"]
70
- DB.instance.delete_domain(name)
71
- build_result("DeleteDomain")
72
- end
73
-
74
- # PutAttributes requests
75
- def do_putattributes(req)
76
- domain_name = req.query["DomainName"]
77
- item_name = req.query["ItemName"]
78
- attrs = parse_attribute_args(req)
79
- DB.instance.put_attributes(domain_name, item_name, attrs)
80
- build_result("PutAttributes")
81
- end
82
-
83
- # DeleteAttributes requests
84
- def do_deleteattributes(req)
85
- domain_name = req.query["DomainName"]
86
- item_name = req.query["ItemName"]
87
- attrs = parse_attribute_args(req)
88
- DB.instance.delete_attributes(domain_name, item_name, attrs)
89
- build_result("DeleteAttributes")
90
- end
91
-
92
- # GetAttributes request
93
- def do_getattributes(req)
94
- domain_name = req.query["DomainName"]
95
- item_name = req.query["ItemName"]
96
- attr_name = req.query["AttributeName"]
97
- attrs = DB.instance.get_attributes(domain_name, item_name)
98
-
99
- build_result("GetAttributes") do |doc|
100
- doc.GetAttributesResult do
101
- if attrs
102
- attrs.each do |attr|
103
- doc.Attribute do
104
- doc.Name attr.name
105
- doc.Value attr.value
106
- end
107
- end
108
- end
109
- end
110
- end
111
- end
112
-
113
- # Query request
114
- def do_query(req)
115
- domain_name = req.query["DomainName"]
116
- max_items = req.query["MaxItems"].to_i
117
- max_items = 100 if (max_items < 1 || max_items > 250)
118
- next_token = req.query["NextToken"]
119
- query = req.query["QueryExpression"]
120
-
121
- results,token = DB.instance.query(domain_name, query, max_items, next_token)
122
- build_result("Query") do |doc|
123
- doc.QueryResult do
124
- if results
125
- results.each do |res|
126
- doc.ItemName res.name
127
- end
128
- end
129
-
130
- if token
131
- doc.NextToken token
132
- end
133
- end
134
- end
135
- end
136
-
137
- # Build a result for the given action.
138
- # The given block will add action-specific return fields.
139
- def build_result(action)
140
- xml = ''
141
- doc = Builder::XmlMarkup.new(:target => xml)
142
- doc.tag!("#{action}Response", :xmlns => "http://sdb.amazonaws.com/doc/2007-11-07") do
143
- if block_given?
144
- yield doc
145
- end
146
-
147
- doc.ResponseMetadata do
148
- doc.RequestId "1234"
149
- doc.BoxUsage "0"
150
- end
151
- end
152
-
153
- xml
154
- end
155
-
156
- # Return the error response for the given error code and message
157
- def error_xml(code, msg)
158
- xml = ''
159
- doc = Builder::XmlMarkup.new(:target => xml)
160
-
161
- doc.Response do
162
- doc.Errors do
163
- doc.Error do
164
- doc.Code code.to_s
165
- doc.Message msg
166
- doc.BoxUsage "0"
167
- end
168
- end
169
-
170
- doc.RequestID "1234"
171
- end
172
-
173
- xml
174
- end
175
-
176
- def parse_attribute_args(req)
177
- args = []
178
- for i in (0...100)
179
- name = req.query["Attribute.#{i}.Name"]
180
- value = req.query["Attribute.#{i}.Value"]
181
- replace = (req.query["Attribute.#{i}.Replace"] == "true")
182
- if name && value
183
- args << AttributeParam.new(name, value, replace)
184
- end
185
- end
186
-
187
- args
188
- end
189
- end
190
-
191
- end
@@ -1,3 +0,0 @@
1
- class SimplerDB
2
- VERSION = '0.2'
3
- end
@@ -1,81 +0,0 @@
1
- require "test/unit"
2
- require 'rubygems'
3
- require 'right_aws'
4
- require 'simplerdb/server'
5
-
6
- # Test the live, running service over HTTP
7
- class FunctionalTest < Test::Unit::TestCase
8
-
9
- def setup
10
- @server = SimplerDB::Server.new(8087)
11
- @thread = Thread.new { @server.start }
12
- @sdb = RightAws::SdbInterface.new('access','secret',
13
- {:server => 'localhost', :port => 8087, :protocol => 'http'})
14
-
15
- end
16
-
17
- def teardown
18
- @server.shutdown
19
- @thread.join
20
- end
21
-
22
- def test_domains
23
- # Create/list domains
24
- @sdb.create_domain("d1")
25
- @sdb.create_domain("d2")
26
- result = @sdb.list_domains
27
- assert result[:domains].index("d1")
28
- assert result[:domains].index("d2")
29
-
30
- # List domains with paging
31
- domains = []
32
- count = 0
33
- @sdb.list_domains(1) do |result|
34
- domains += result[:domains]
35
- count += 1
36
- true
37
- end
38
-
39
- assert count == 2
40
- assert domains.index("d1")
41
- assert domains.index("d2")
42
- end
43
-
44
- def test_items
45
- # Create some bands with albums + genre
46
- @sdb.create_domain("bands")
47
-
48
- attrs = {:albums => ['Being There', 'Summer Teeth'], :genre => "rock"}
49
- @sdb.put_attributes("bands", "Wilco", attrs)
50
-
51
- attrs = {:albums => ['OK Computer', 'Kid A'], :genre => "alternative"}
52
- @sdb.put_attributes("bands", "Radiohead", attrs)
53
-
54
- attrs = {:albums => ['The Soft Bulletin'], :genre => "alternative"}
55
- @sdb.put_attributes("bands", "The Flaming Lips", attrs)
56
-
57
- # Read the attributes back
58
- results = @sdb.get_attributes("bands", "Wilco")
59
- assert results[:attributes]["albums"].sort == ['Being There', 'Summer Teeth']
60
- assert results[:attributes]["genre"] == ["rock"]
61
-
62
- # Query the bands domain
63
- results = @sdb.query("bands", "['genre' = 'alternative']")
64
- assert results[:items].sort == ["Radiohead", "The Flaming Lips"]
65
-
66
- results = @sdb.query("bands", "['albums' = 'Being There']")
67
- assert results[:items] == ["Wilco"]
68
-
69
- results = @sdb.query("bands", "['albums' starts-with 'OK' or 'albums' = 'The Soft Bulletin']")
70
- assert results[:items].sort == ["Radiohead", "The Flaming Lips"]
71
-
72
- # Modify and re-read attributes
73
- @sdb.put_attributes("bands", "The Flaming Lips", {:albums => "Yoshimi Battles the Pink Robots"})
74
- @sdb.put_attributes("bands", "The Flaming Lips", {:genre => "rock"}, :replace)
75
-
76
- results = @sdb.get_attributes("bands", "The Flaming Lips")
77
- assert results[:attributes]["albums"].sort == ["The Soft Bulletin", "Yoshimi Battles the Pink Robots"]
78
- assert results[:attributes]["genre"] == ["rock"]
79
- end
80
-
81
- end
@@ -1,73 +0,0 @@
1
- require "test/unit"
2
- require 'simplerdb/query_language'
3
- require 'simplerdb/db'
4
-
5
- # Tests the query evaluator
6
- class QueryEvaluatorTest < Test::Unit::TestCase
7
- include SimplerDB
8
-
9
- def setup
10
- @db = DB.instance
11
- @db.create_domain("test")
12
- end
13
-
14
- def teardown
15
- @db.reset
16
- end
17
-
18
- def test_single_predicate
19
- bulk_insert('i1' => [["a1", "v1"], ["a2", "v2"], ["a3", "bcd"]],
20
- 'i2' => [["a1", "vv1"]])
21
-
22
- assert_items 'i1', @db.query("test", "['a1' = 'v1']")
23
- assert_items 'i1', @db.query("test", "['a1' != 'v2']")
24
- assert_items 'i1', @db.query("test", "['a1' >= 'v1']")
25
- assert_items 'i1', @db.query("test", "['a1' <= 'v1']")
26
- assert_items 'i1', @db.query("test", "['a3' starts-with 'bc']")
27
- assert_items 'i1', @db.query("test", "['a3' > 'cde']")
28
- assert_items 'i1', @db.query("test", "['a3' < 'abc']")
29
- assert_items ['i1', 'i2'], @db.query("test", "['a1' = 'v1' or 'a1' = 'vv1']")
30
- assert_items ['i1', 'i2'], @db.query("test", "['a1' <= 'v1']")
31
-
32
- assert_empty @db.query("test", "['a2' != 'v2']")
33
- assert_empty @db.query("test", "['a2' > 'v2']")
34
- assert_empty @db.query("test", "['a2' = 'v1']")
35
- assert_empty @db.query("testxxxxx", "['a2' = 'v2']")
36
- assert_empty @db.query("test", "['a2' = 'v1']")
37
- end
38
-
39
- def test_ops
40
-
41
- end
42
-
43
- def bulk_insert(items)
44
- items.each do |name, attrs|
45
- params = []
46
- for attr in attrs
47
- params << AttributeParam.new(attr[0], attr[1])
48
- end
49
-
50
- @db.put_attributes("test", name, params)
51
- end
52
- end
53
-
54
- def assert_empty(results)
55
- assert results[0].empty?
56
- end
57
-
58
- def assert_items(items, results)
59
- results = results[0]
60
- for item in items
61
- found = false
62
- for result in results
63
- if result.name == item
64
- found = true
65
- break
66
- end
67
- end
68
-
69
- assert found, "Missing item #{item}"
70
- end
71
- end
72
-
73
- end