dict. Commit to the database with sync().
"""
+ table_name = 'sites'
+ primary_key = 'site_id'
fields = {
'site_id': Parameter(int, "Site identifier"),
'name': Parameter(str, "Full site name", max = 254),
'latitude': Parameter(float, "Decimal latitude of the site", min = -90.0, max = 90.0),
'longitude': Parameter(float, "Decimal longitude of the site", min = -180.0, max = 180.0),
'url': Parameter(str, "URL of a page that describes the site", max = 254),
- 'date_created': Parameter(int, "Date and time when site entry was created, in seconds since UNIX epoch"),
- 'last_updated': Parameter(int, "Date and time when site entry was last updated, in seconds since UNIX epoch"),
- 'deleted': Parameter(bool, "Has been deleted"),
+ 'date_created': Parameter(int, "Date and time when site entry was created, in seconds since UNIX epoch", ro = True),
+ 'last_updated': Parameter(int, "Date and time when site entry was last updated, in seconds since UNIX epoch", ro = True),
'max_slices': Parameter(int, "Maximum number of slices that the site is able to create"),
'max_slivers': Parameter(int, "Maximum number of slivers that the site is able to create"),
- 'person_ids': Parameter([int], "List of account identifiers"),
- 'slice_ids': Parameter([int], "List of slice identifiers"),
- 'address_ids': Parameter([int], "List of address identifiers"),
- # 'pcu_ids': Parameter([int], "List of PCU identifiers"),
- 'node_ids': Parameter([int], "List of site node identifiers"),
+ 'person_ids': Parameter([int], "List of account identifiers", ro = True),
+ 'slice_ids': Parameter([int], "List of slice identifiers", ro = True),
+ 'address_ids': Parameter([int], "List of address identifiers", ro = True),
+ 'pcu_ids': Parameter([int], "List of PCU identifiers", ro = True),
+ 'node_ids': Parameter([int], "List of site node identifiers", ro = True),
}
- def __init__(self, api, fields):
- Row.__init__(self, fields)
- self.api = api
+ def validate_name(self, name):
+ if not len(name):
+ raise PLCInvalidArgument, "Name must be specified"
+
+ return name
+
+ validate_abbreviated_name = validate_name
def validate_login_base(self, login_base):
- if not set(login_base).issubset(string.ascii_letters):
- raise PLCInvalidArgument, "Login base must consist only of ASCII letters"
+ if not len(login_base):
+ raise PLCInvalidArgument, "Login base must be specified"
+
+ if not set(login_base).issubset(string.ascii_letters.lower()):
+ raise PLCInvalidArgument, "Login base must consist only of lowercase ASCII letters"
- login_base = login_base.lower()
conflicts = Sites(self.api, [login_base])
for site_id, site in conflicts.iteritems():
- if not site['deleted'] and ('site_id' not in self or self['site_id'] != site_id):
+ if 'site_id' not in self or self['site_id'] != site_id:
raise PLCInvalidArgument, "login_base already in use"
return login_base
site_id = self['site_id']
person_id = person['person_id']
- self.api.db.do("INSERT INTO person_site (person_id, site_id)" \
- " VALUES(%(person_id)d, %(site_id)d)",
- locals())
- if commit:
- self.api.db.commit()
+ if person_id not in self['person_ids']:
+ assert site_id not in person['site_ids']
- if 'person_ids' in self and person_id not in self['person_ids']:
- self['person_ids'].append(person_id)
+ self.api.db.do("INSERT INTO person_site (person_id, site_id)" \
+ " VALUES(%(person_id)d, %(site_id)d)",
+ locals())
+
+ if commit:
+ self.api.db.commit()
- if 'site_ids' in person and site_id not in person['site_ids']:
+ self['person_ids'].append(person_id)
person['site_ids'].append(site_id)
def remove_person(self, person, commit = True):
site_id = self['site_id']
person_id = person['person_id']
- self.api.db.do("DELETE FROM person_site" \
- " WHERE person_id = %(person_id)d" \
- " AND site_id = %(site_id)d",
- locals())
- if commit:
- self.api.db.commit()
+ if person_id in self['person_ids']:
+ assert site_id in person['site_ids']
- if 'person_ids' in self and person_id in self['person_ids']:
- self['person_ids'].remove(person_id)
+ self.api.db.do("DELETE FROM person_site" \
+ " WHERE person_id = %(person_id)d" \
+ " AND site_id = %(site_id)d",
+ locals())
+
+ if commit:
+ self.api.db.commit()
- if 'site_ids' in person and site_id in person['site_ids']:
+ self['person_ids'].remove(person_id)
person['site_ids'].remove(site_id)
- def sync(self, commit = True):
+ def add_address(self, address, commit = True):
+ """
+ Add address to existing site.
+ """
+
+ assert 'site_id' in self
+ assert isinstance(address, Address)
+ assert 'address_id' in address
+
+ site_id = self['site_id']
+ address_id = address['address_id']
+
+ if address_id not in self['address_ids']:
+ self.api.db.do("INSERT INTO site_address (address_id, site_id)" \
+ " VALUES(%(address_id)d, %(site_id)d)",
+ locals())
+
+ if commit:
+ self.api.db.commit()
+
+ self['address_ids'].append(address_id)
+
+ def remove_address(self, address, commit = True):
"""
- Flush changes back to the database.
+ Remove address from existing site.
"""
- self.validate()
-
- try:
- if not self['name'] or \
- not self['abbreviated_name'] or \
- not self['login_base']:
- raise KeyError
- except KeyError:
- raise PLCInvalidArgument, "name, abbreviated_name, and login_base must all be specified"
-
- # Fetch a new site_id if necessary
- if 'site_id' not in self:
- rows = self.api.db.selectall("SELECT NEXTVAL('sites_site_id_seq') AS site_id")
- if not rows:
- raise PLCDBError, "Unable to fetch new site_id"
- self['site_id'] = rows[0]['site_id']
- insert = True
- else:
- insert = False
-
- # Filter out fields that cannot be set or updated directly
- sites_fields = self.api.db.fields('sites')
- fields = dict(filter(lambda (key, value): key in sites_fields,
- self.items()))
- for ro_field in 'date_created', 'last_updated':
- if ro_field in fields:
- del fields[ro_field]
-
- # Parameterize for safety
- keys = fields.keys()
- values = [self.api.db.param(key, value) for (key, value) in fields.items()]
-
- if insert:
- # Insert new row in sites table
- sql = "INSERT INTO sites (%s) VALUES (%s)" % \
- (", ".join(keys), ", ".join(values))
- else:
- # Update existing row in sites table
- columns = ["%s = %s" % (key, value) for (key, value) in zip(keys, values)]
- sql = "UPDATE sites SET " + \
- ", ".join(columns) + \
- " WHERE site_id = %(site_id)d"
-
- self.api.db.do(sql, fields)
-
- if commit:
- self.api.db.commit()
+ assert 'site_id' in self
+ assert isinstance(address, Address)
+ assert 'address_id' in address
+
+ site_id = self['site_id']
+ address_id = address['address_id']
+
+ if address_id in self['address_ids']:
+ self.api.db.do("DELETE FROM site_address" \
+ " WHERE address_id = %(address_id)d" \
+ " AND site_id = %(site_id)d",
+ locals())
+
+ if commit:
+ self.api.db.commit()
+
+ self['address_ids'].remove(address_id)
def delete(self, commit = True):
"""
person_sites = Sites(self.api, person['site_ids'])
for person_site_id, person_site in person_sites.iteritems():
- if person_site_id != self['site_id'] and \
- not person_site['deleted']:
+ if person_site_id != self['site_id']:
delete = False
break
slice.delete(commit = False)
# Delete all site PCUs
- # pcus = PCUs(self.api, self['pcu_ids'])
- # for pcu in pcus.values():
- # pcu.delete(commit = False)
+ pcus = PCUs(self.api, self['pcu_ids'])
+ for pcu in pcus.values():
+ pcu.delete(commit = False)
# Delete all site nodes
nodes = Nodes(self.api, self['node_ids'])
fields.
"""
- def __init__(self, api, site_id_or_login_base_list = None, fields = Site.fields):
+ def __init__(self, api, site_id_or_login_base_list = None):
self.api = api
sql = "SELECT %s FROM view_sites WHERE deleted IS False" % \
- ", ".join(fields)
+ ", ".join(Site.fields)
if site_id_or_login_base_list:
# Separate the list into integers and strings