1
# Copyright (c) 2006-2008 Mitch Garnaat http://garnaat.org/
3
# Permission is hereby granted, free of charge, to any person obtaining a
4
# copy of this software and associated documentation files (the
5
# "Software"), to deal in the Software without restriction, including
6
# without limitation the rights to use, copy, modify, merge, publish, dis-
7
# tribute, sublicense, and/or sell copies of the Software, and to permit
8
# persons to whom the Software is furnished to do so, subject to the fol-
11
# The above copyright notice and this permission notice shall be included
12
# in all copies or substantial portions of the Software.
14
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26
from boto.sdb.persist.object import SDBObject
27
from boto.sdb.persist.property import StringProperty, ObjectProperty, DateTimeProperty, ObjectListProperty, S3KeyProperty
30
HEX_DIGITS = '0123456789abcdef'
32
class Identifier(object):
38
suffix += random.choice(HEX_DIGITS)
39
return prefix + '-' + suffix
42
class Version(SDBObject):
44
name = StringProperty()
45
pdb = ObjectProperty(ref_class=SDBObject)
46
date = DateTimeProperty()
48
def __init__(self, id=None, manager=None):
49
SDBObject.__init__(self, id, manager)
51
self.name = Identifier.gen('v')
52
self.date = datetime.datetime.now()
53
print 'created Version %s' % self.name
57
Return an iterator containing all Partition objects related to this Version.
59
:rtype: iterator of :class:`boto.mapreduce.partitiondb.Partition`
60
:return: The Partitions in this Version
62
return self.get_related_objects('version', Partition)
64
def add_partition(self, name=None):
66
Add a new Partition to this Version.
69
:param name: The name of the new Partition (optional)
71
:rtype: :class:`boto.mapreduce.partitiondb.Partition`
72
:return: The new Partition object
74
p = Partition(manager=self.manager, name=name)
80
def get_s3_prefix(self):
82
raise ValueError, 'pdb attribute must be set to compute S3 prefix'
83
return self.pdb.get_s3_prefix() + self.name + '/'
85
class PartitionDB(SDBObject):
87
name = StringProperty()
88
bucket_name = StringProperty()
89
versions = ObjectListProperty(ref_class=Version)
91
def __init__(self, id=None, manager=None, name='', bucket_name=''):
92
SDBObject.__init__(self, id, manager)
95
self.bucket_name = bucket_name
97
def get_s3_prefix(self):
98
return self.name + '/'
100
def add_version(self):
102
Add a new Version to this PartitionDB. The newly added version becomes the
105
:rtype: :class:`boto.mapreduce.partitiondb.Version`
106
:return: The newly created Version object.
111
self.versions.append(v)
116
Revert to the previous version of this PartitionDB. The current version is removed from the
117
list of Versions and the Version immediately preceeding it becomes the current version.
118
Note that this method does not delete the Version object or any Partitions related to the
121
:rtype: :class:`boto.mapreduce.partitiondb.Version`
122
:return: The previous current Version object.
124
v = self.current_version()
126
self.versions.remove(v)
129
def current_version(self):
131
Get the currently active Version of this PartitionDB object.
133
:rtype: :class:`boto.mapreduce.partitiondb.Version`
134
:return: The current Version object or None if there are no Versions associated
135
with this PartitionDB object.
138
if len(self.versions) > 0:
139
return self.versions[-1]
142
class Partition(SDBObject):
144
def __init__(self, id=None, manager=None, name=None):
145
SDBObject.__init__(self, id, manager)
149
name = StringProperty()
150
version = ObjectProperty(ref_class=Version)
151
pdb = ObjectProperty(ref_class=PartitionDB)
152
data = S3KeyProperty()
154
def get_key_name(self):
155
return self.version.get_s3_prefix() + self.name
157
def upload(self, path, bucket_name=None):
159
bucket_name = self.version.pdb.bucket_name
160
s3 = self.manager.get_s3_connection()
161
bucket = s3.lookup(bucket_name)
162
directory, filename = os.path.split(path)
164
key = bucket.new_key(self.get_key_name())
165
key.set_contents_from_filename(path)
172
SDBObject.delete(self)