sdb_dal 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -21,14 +21,15 @@ module SdbDal
21
21
  else
22
22
  repo_class=SdbDal::Repository
23
23
  end
24
- domain_prefix= sdb_dal_config["sdb_domain_prefix"]
24
+ domain_prefix= sdb_dal_config["sdb_domain_prefix"] || ""
25
25
  clob_bucket= sdb_dal_config["s3_clob_bucket"]
26
26
  aws_key_id = sdb_dal_config["aws_key_id"]
27
27
  aws_secret_key = sdb_dal_config["aws_secret_key"]
28
28
  memcache_servers= sdb_dal_config['memcache_servers']
29
29
  memcache_servers = memcache_servers.split(",") if memcache_servers
30
-
31
- @repository= repo_class.new(domain_prefix,clob_bucket,aws_key_id,aws_secret_key,memcache_servers)
30
+
31
+ append_table_to_domain=sdb_dal_config['append_table_to_domain']
32
+ @repository= repo_class.new(domain_prefix,clob_bucket,aws_key_id,aws_secret_key,memcache_servers,nil,append_table_to_domain)
32
33
  end
33
34
  end
34
35
 
data/lib/sdb_dal/s3.rb CHANGED
@@ -29,7 +29,6 @@ if (RUBY_VERSION < '1.8.3')
29
29
  end
30
30
  end
31
31
  module SdbDal
32
-
33
32
  # this module has two big classes: AWSAuthConnection and
34
33
  # QueryStringAuthGenerator. both use identical apis, but the first actually
35
34
  # performs the operation, while the second simply outputs urls with the
@@ -41,7 +40,7 @@ module S3
41
40
  METADATA_PREFIX = 'x-amz-meta-'
42
41
  AMAZON_HEADER_PREFIX = 'x-amz-'
43
42
  AMAZON_TOKEN_HEADER_PREFIX = "x-amz-security-token"
44
-
43
+ CANONICAL_STRING_WORTHY_PATH_ARGS=['acl','torrent','logging','requestPayment']
45
44
  # builds the canonical string for signing.
46
45
  def S3.canonical_string(method, bucket="", path="", path_args={}, headers={}, expires=nil)
47
46
  interesting_headers = {}
@@ -78,25 +77,24 @@ module S3
78
77
  buf << "#{value}\n"
79
78
  end
80
79
  end
81
-
80
+
82
81
  # build the path using the bucket and key
83
82
  if not bucket.empty?
84
83
  buf << "/#{bucket}"
85
84
  end
86
- # append the key (it might be empty string)
85
+ # append the key (it might be empty string)
87
86
  # append a slash regardless
88
87
  buf << "/#{path}"
89
88
 
90
- # if there is an acl, logging, or torrent parameter
89
+ # if there is an acl, logging, torrent, or requestPayment parameter
91
90
  # add them to the string
92
- if path_args.has_key?('acl')
93
- buf << '?acl'
94
- elsif path_args.has_key?('torrent')
95
- buf << '?torrent'
96
- elsif path_args.has_key?('logging')
97
- buf << '?logging'
98
- end
99
-
91
+ CANONICAL_STRING_WORTHY_PATH_ARGS.each do |arg_name|
92
+ if path_args.has_key?(arg_name)
93
+ buf << "?#{arg_name}"
94
+ break
95
+ end
96
+ end
97
+
100
98
  return buf
101
99
  end
102
100
 
@@ -121,7 +119,7 @@ module S3
121
119
  def S3.path_args_hash_to_string(path_args={})
122
120
  arg_string = ''
123
121
  path_args.each { |k, v|
124
- arg_string << k.to_s
122
+ arg_string << k
125
123
  if not v.nil?
126
124
  arg_string << "=#{CGI::escape(v)}"
127
125
  end
@@ -138,14 +136,14 @@ module S3
138
136
  # some connection pooling.
139
137
  class AWSAuthConnection
140
138
  attr_accessor :calling_format
141
-
142
- def initialize(aws_access_key_id,
143
- aws_secret_access_key,
139
+
140
+ def initialize(aws_access_key_id,
141
+ aws_secret_access_key,
144
142
  tokens=Array.new,
145
- is_secure=true,
146
- server=DEFAULT_HOST,
143
+ is_secure=true,
144
+ server=DEFAULT_HOST,
147
145
  port=PORTS_BY_SECURITY[is_secure],
148
- calling_format=CallingFormat::SUBDOMAIN)
146
+ calling_format=CallingFormat::REGULAR)
149
147
  @aws_access_key_id = aws_access_key_id
150
148
  @aws_secret_access_key = aws_secret_access_key
151
149
  @server = server
@@ -183,26 +181,6 @@ module S3
183
181
  make_request('PUT', bucket, CGI::escape(key), {}, headers, object.data, object.metadata)
184
182
  )
185
183
  end
186
- def copy(source_bucket, source_key, destination_bucket,destination_key, headers={})
187
- headers['x-amz-copy-source']="#{source_bucket}/#{source_key}"
188
- headers['x-amz-metadata-directive']="REPLACE "
189
- return GetResponse.new(make_request('PUT', destination_bucket, CGI::escape(destination_key),{}, headers))
190
- end
191
-
192
- def get_head(bucket, key, headers={})
193
- return GetResponse.new(make_request('HEAD',bucket, CGI::escape(key),{}, headers))
194
- end
195
- def get_content_type(bucket, key, headers={})
196
- response= get_head(bucket, key, headers)
197
- if response.http_response.code=='404'
198
- return nil
199
-
200
- elsif response.http_response.code=='200'
201
- return response.http_response.header.content_type
202
- end
203
- raise response.http_response.code
204
- end
205
-
206
184
 
207
185
  def get(bucket, key, headers={})
208
186
  return GetResponse.new(make_request('GET', bucket, CGI::escape(key), {}, headers))
@@ -223,7 +201,7 @@ module S3
223
201
  def get_bucket_acl(bucket, headers={})
224
202
  return get_acl(bucket, '', headers)
225
203
  end
226
-
204
+
227
205
  # returns an xml document representing the access control list.
228
206
  # this could be parsed into an object.
229
207
  def get_acl(bucket, key, headers={})
@@ -242,13 +220,46 @@ module S3
242
220
  )
243
221
  end
244
222
 
223
+
224
+ #payer may be RequestPayer::REQUESTER or RequestPayer::BUCKET_OWNER
225
+ def put_bucket_request_payment( bucket, payer=RequestPayer::REQUESTER, headers={})
226
+
227
+ body = "<RequestPaymentConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Payer>#{payer}</Payer></RequestPaymentConfiguration>"
228
+
229
+ result= make_request(
230
+ 'PUT',
231
+ bucket,
232
+ '',
233
+ {'requestPayment' => nil },
234
+ headers,
235
+ body,
236
+ {} )
237
+ return GetResponse.new(result)
238
+
239
+ end
240
+
241
+ def get_bucket_request_payment( bucket, headers={})
242
+
243
+ result= make_request(
244
+ 'GET',
245
+ bucket,
246
+ '',
247
+ {'requestPayment' => nil },
248
+ headers,
249
+ '',
250
+ {} )
251
+ return GetResponse.new(result)
252
+
253
+ end
254
+
255
+
245
256
  def list_all_my_buckets(headers={})
246
257
  return ListAllMyBucketsResponse.new(make_request('GET', '', '', {}, headers))
247
258
  end
248
259
 
249
260
  private
250
261
  def make_request(method, bucket='', key='', path_args={}, headers={}, data='', metadata={})
251
-
262
+
252
263
  # build the domain based on the calling format
253
264
  server = ''
254
265
  if bucket.empty?
@@ -257,9 +268,9 @@ module S3
257
268
  # does not make sense for vanity domains
258
269
  server = @server
259
270
  elsif @calling_format == CallingFormat::SUBDOMAIN
260
- server = "#{bucket}.#{@server}"
271
+ server = "#{bucket}.#{@server}"
261
272
  elsif @calling_format == CallingFormat::VANITY
262
- server = bucket
273
+ server = bucket
263
274
  else
264
275
  server = @server
265
276
  end
@@ -274,11 +285,11 @@ module S3
274
285
  path << "/#{key}"
275
286
 
276
287
  # build the path_argument string
277
- # add the ? in all cases since
288
+ # add the ? in all cases since
278
289
  # signature and credentials follow path args
279
290
  path << '?'
280
- path << S3.path_args_hash_to_string(path_args)
281
-
291
+ path << S3.path_args_hash_to_string(path_args)
292
+
282
293
  http = Net::HTTP.new(server, @port)
283
294
  http.use_ssl = @is_secure
284
295
  http.start do
@@ -295,7 +306,6 @@ module S3
295
306
  return http.request(req)
296
307
  end
297
308
  end
298
-
299
309
  end
300
310
 
301
311
  def method_to_request_class(method)
@@ -306,8 +316,6 @@ module S3
306
316
  return Net::HTTP::Put
307
317
  when 'DELETE'
308
318
  return Net::HTTP::Delete
309
- when 'HEAD'
310
- return Net::HTTP::Head
311
319
  else
312
320
  raise "Unsupported method #{method}"
313
321
  end
@@ -348,8 +356,12 @@ module S3
348
356
  end
349
357
  end
350
358
 
359
+ module RequestPayer
360
+ REQUESTER="Requester"
361
+ BUCKET_OWNER="BucketOwner"
362
+ end
351
363
  # class for storing calling format constants
352
- module CallingFormat
364
+ module CallingFormat
353
365
  REGULAR = 0 # http://s3.amazonaws.com/bucket/key
354
366
  SUBDOMAIN = 1 # http://bucket.s3.amazonaws.com/key
355
367
  VANITY = 2 # http://<vanity_domain>/key -- vanity_domain resolves to s3.amazonaws.com
@@ -366,7 +378,7 @@ module S3
366
378
  else
367
379
  build_url_base << "#{server}:#{port}/#{bucket}"
368
380
  end
369
- return build_url_base
381
+ return build_url_base
370
382
  end
371
383
  end
372
384
 
@@ -418,7 +430,7 @@ module S3
418
430
  @curr_entry.owner = Owner.new
419
431
  elsif name == 'CommonPrefixes'
420
432
  @common_prefix_entry = CommonPrefixEntry.new
421
- end
433
+ end
422
434
  end
423
435
 
424
436
  # we have one, add him to the entries list
@@ -427,7 +439,7 @@ module S3
427
439
  if name == 'Name'
428
440
  @properties.name = @curr_text
429
441
  elsif name == 'Prefix' and @is_echoed_prefix
430
- @properties.prefix = @curr_text
442
+ @properties.prefix = @curr_text
431
443
  @is_echoed_prefix = nil
432
444
  elsif name == 'Marker'
433
445
  @properties.marker = @curr_text
@@ -437,7 +449,7 @@ module S3
437
449
  @properties.delimiter = @curr_text
438
450
  elsif name == 'IsTruncated'
439
451
  @properties.is_truncated = @curr_text == 'true'
440
- elsif name == 'NextMarker'
452
+ elsif name == 'NextMarker'
441
453
  @properties.next_marker = @curr_text
442
454
  elsif name == 'Contents'
443
455
  @entries << @curr_entry
@@ -456,7 +468,7 @@ module S3
456
468
  elsif name == 'DisplayName'
457
469
  @curr_entry.owner.display_name = @curr_text
458
470
  elsif name == 'CommonPrefixes'
459
- @common_prefixes << @common_prefix_entry
471
+ @common_prefixes << @common_prefix_entry
460
472
  elsif name == 'Prefix'
461
473
  # this is the common prefix for keys that match up to the delimiter
462
474
  @common_prefix_entry.prefix = @curr_text
@@ -591,4 +603,4 @@ module S3
591
603
  end
592
604
  end
593
605
  end
594
- end
606
+ end
@@ -0,0 +1,47 @@
1
+ require 'logger'
2
+ require 'time'
3
+ require 'cgi'
4
+ require 'uri'
5
+ require 'net/http'
6
+ require 'base64'
7
+ require 'openssl'
8
+ require 'rexml/document'
9
+ require 'rexml/xpath'
10
+
11
+ module AwsSdb
12
+ class Service
13
+ def query_with_attributes(domain, query, max = nil, token = nil)
14
+ params = {
15
+ 'Action' => 'QueryWithAttributes',
16
+ 'QueryExpression' => query,
17
+ 'DomainName' => domain.to_s
18
+ }
19
+ params['NextToken'] =
20
+ token unless token.nil? || token.empty?
21
+ params['MaxNumberOfItems'] =
22
+ max.to_s unless max.nil? || max.to_i == 0
23
+ doc = call(:get, params)
24
+ results = {}
25
+ REXML::XPath.each(doc, '//Item') do |item|
26
+ item_attributes={}
27
+ item_name = REXML::XPath.first(item, './Name/text()').to_s
28
+
29
+
30
+ REXML::XPath.each(item, "./Attribute") do |attr|
31
+
32
+ key = REXML::XPath.first(attr, './Name/text()').to_s
33
+ value = REXML::XPath.first(attr, './Value/text()').to_s
34
+ item_attributes[key]= value
35
+ end
36
+ results[item_name]=item_attributes
37
+
38
+ end
39
+ return results, REXML::XPath.first(doc, '//NextToken/text()').to_s
40
+ end
41
+
42
+
43
+
44
+
45
+
46
+ end
47
+ end
@@ -80,13 +80,13 @@ class Storage
80
80
  real_s3.create_bucket(bucket,headers)
81
81
  end
82
82
  def real_s3_put(bucket,key,object,attributes)
83
-
83
+ x=nil
84
84
  20.times do |i|
85
85
  begin
86
- real_s3.put(bucket,key,S3::S3Object.new(object),attributes)
87
-
88
- return
86
+ x= real_s3.put(bucket,key,S3::S3Object.new(object),attributes)
87
+
89
88
 
89
+ break
90
90
  rescue =>e
91
91
  s= "#{e.message}\n#{e.backtrace}"
92
92
  puts(s)
@@ -95,6 +95,10 @@ class Storage
95
95
  #try again
96
96
  end
97
97
  end
98
+ if x.http_response.code!="200"
99
+
100
+ raise "bucket #{bucket} key #{key} response #{x.http_response.code}"
101
+ end
98
102
  end
99
103
  def delete(bucket,key)
100
104
  if @cache
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdb_dal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Knight
@@ -9,7 +9,7 @@ autorequire: sdb_dal
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-12-22 00:00:00 -08:00
12
+ date: 2009-01-03 00:00:00 -08:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -43,6 +43,7 @@ files:
43
43
  - ./lib/sdb_dal/repository_factory.rb
44
44
  - ./lib/sdb_dal/s3.rb
45
45
  - ./lib/sdb_dal/sdb_formatter.rb
46
+ - ./lib/sdb_dal/sdb_monkey_patch.rb
46
47
  - ./lib/sdb_dal/starts_with_condition.rb
47
48
  - ./lib/sdb_dal/storage.rb
48
49
  - ./lib/sdb_dal/tag_cloud.rb
@@ -68,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
68
69
  version:
69
70
  requirements: []
70
71
 
71
- rubyforge_project:
72
+ rubyforge_project: sdb-dal
72
73
  rubygems_version: 1.3.1
73
74
  signing_key:
74
75
  specification_version: 2