- remove optional sub-parameter; we use these fields in both Add() and
[plcapi.git] / PLC / Slices.py
index cc5cfce..fe72863 100644 (file)
@@ -21,7 +21,7 @@ class Slice(Row):
     table_name = 'slices'
     primary_key = 'slice_id'
     fields = {
-        'slice_id': Parameter(int, "Slice type"),
+        'slice_id': Parameter(int, "Slice identifier"),
         'site_id': Parameter(int, "Identifier of the site to which this slice belongs"),
         'name': Parameter(str, "Slice name", max = 32),
         'instantiation': Parameter(str, "Slice instantiation state"),
@@ -36,10 +36,6 @@ class Slice(Row):
         'slice_attribute_ids': Parameter([int], "List of slice attributes", ro = True),
         }
 
-    def __init__(self, api, fields = {}):
-        Row.__init__(self, fields)
-        self.api = api
-
     def validate_name(self, name):
         # N.B.: Responsibility of the caller to ensure that login_base
         # portion of the slice name corresponds to a valid site, if
@@ -94,17 +90,18 @@ class Slice(Row):
 
         slice_id = self['slice_id']
         person_id = person['person_id']
-        self.api.db.do("INSERT INTO slice_person (person_id, slice_id)" \
-                       " VALUES(%(person_id)d, %(slice_id)d)",
-                       locals())
 
-        if commit:
-            self.api.db.commit()
+        if person_id not in self['person_ids']:
+            assert slice_id not in person['slice_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 slice_person (person_id, slice_id)" \
+                           " VALUES(%(person_id)d, %(slice_id)d)",
+                           locals())
 
-        if 'slice_ids' in person and slice_id not in person['slice_ids']:
+            if commit:
+                self.api.db.commit()
+
+            self['person_ids'].append(person_id)
             person['slice_ids'].append(slice_id)
 
     def remove_person(self, person, commit = True):
@@ -118,18 +115,19 @@ class Slice(Row):
 
         slice_id = self['slice_id']
         person_id = person['person_id']
-        self.api.db.do("DELETE FROM slice_person" \
-                       " WHERE person_id = %(person_id)d" \
-                       " AND slice_id = %(slice_id)d",
-                       locals())
 
-        if commit:
-            self.api.db.commit()
+        if person_id in self['person_ids']:
+            assert slice_id in person['slice_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 slice_person" \
+                           " WHERE person_id = %(person_id)d" \
+                           " AND slice_id = %(slice_id)d",
+                           locals())
+
+            if commit:
+                self.api.db.commit()
 
-        if 'slice_ids' in person and slice_id in person['slice_ids']:
+            self['person_ids'].remove(person_id)
             person['slice_ids'].remove(slice_id)
 
     def add_node(self, node, commit = True):
@@ -143,17 +141,18 @@ class Slice(Row):
 
         slice_id = self['slice_id']
         node_id = node['node_id']
-        self.api.db.do("INSERT INTO slice_node (node_id, slice_id)" \
-                       " VALUES(%(node_id)d, %(slice_id)d)",
-                       locals())
 
-        if commit:
-            self.api.db.commit()
+        if node_id not in self['node_ids']:
+            assert slice_id not in node['slice_ids']
 
-        if 'node_ids' in self and node_id not in self['node_ids']:
-            self['node_ids'].append(node_id)
+            self.api.db.do("INSERT INTO slice_node (node_id, slice_id)" \
+                           " VALUES(%(node_id)d, %(slice_id)d)",
+                           locals())
+
+            if commit:
+                self.api.db.commit()
 
-        if 'slice_ids' in node and slice_id not in node['slice_ids']:
+            self['node_ids'].append(node_id)
             node['slice_ids'].append(slice_id)
 
     def remove_node(self, node, commit = True):
@@ -167,20 +166,34 @@ class Slice(Row):
 
         slice_id = self['slice_id']
         node_id = node['node_id']
-        self.api.db.do("DELETE FROM slice_node" \
-                       " WHERE node_id = %(node_id)d" \
-                       " AND slice_id = %(slice_id)d",
-                       locals())
 
-        if commit:
-            self.api.db.commit()
+        if node_id in self['node_ids']:
+            assert slice_id in node['slice_ids']
 
-        if 'node_ids' in self and node_id in self['node_ids']:
-            self['node_ids'].remove(node_id)
+            self.api.db.do("DELETE FROM slice_node" \
+                           " WHERE node_id = %(node_id)d" \
+                           " AND slice_id = %(slice_id)d",
+                           locals())
+
+            if commit:
+                self.api.db.commit()
 
-        if 'slice_ids' in node and slice_id in node['slice_ids']:
+            self['node_ids'].remove(node_id)
             node['slice_ids'].remove(slice_id)
 
+    def sync(self, commit = True):
+        """
+        Add or update a slice.
+        """
+
+        # Before a new slice is added, delete expired slices
+        if 'slice_id' not in self:
+            expired = Slices(self.api, expires = -int(time.time())).values()
+            for slice in expired:
+                slice.delete(commit)
+
+        Row.sync(self, commit)
+
     def delete(self, commit = True):
         """
         Delete existing slice.
@@ -204,12 +217,19 @@ class Slices(Table):
     database.
     """
 
-    def __init__(self, api, slice_id_or_name_list = None):
+    def __init__(self, api, slice_id_or_name_list = None, expires = int(time.time())):
         self.api = api
 
         sql = "SELECT %s FROM view_slices WHERE is_deleted IS False" % \
               ", ".join(Slice.fields)
 
+        if expires is not None:
+            if expires >= 0:
+                sql += " AND expires > %(expires)d"
+            else:
+                expires = -expires
+                sql += " AND expires < %(expires)d"
+
         if slice_id_or_name_list:
             # Separate the list into integers and strings
             slice_ids = filter(lambda slice_id: isinstance(slice_id, (int, long)),
@@ -223,7 +243,7 @@ class Slices(Table):
                 sql += " OR name IN (%s)" % ", ".join(api.db.quote(names))
             sql += ")"
 
-        rows = self.api.db.selectall(sql)
+        rows = self.api.db.selectall(sql, locals())
 
         for row in rows:
             self[row['slice_id']] = slice = Slice(api, row)