implement AddressAddressTypes, BootStates, ConfFiles, Ilinks, InitScripts
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Sat, 29 Sep 2012 15:35:58 +0000 (11:35 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Sat, 29 Sep 2012 15:35:58 +0000 (11:35 -0400)
PLC/AddressAddressTypes.py
PLC/BootStates.py
PLC/ConfFiles.py
PLC/Ilinks.py
PLC/InitScripts.py
PLC/Slices.py

index 7f51fff..0b297cc 100644 (file)
@@ -8,9 +8,7 @@
 from types import StringTypes
 from PLC.Faults import *
 from PLC.Parameter import Parameter
-from PLC.Filter import Filter
 from PLC.Storage.AlchemyObj import AlchemyObj
-from PLC.Table import Row, Table
 
 class AddressAddressType(AlchemyObj):
     """
index 11cd3b7..4ce45ca 100644 (file)
@@ -7,19 +7,17 @@
 
 from PLC.Faults import *
 from PLC.Parameter import Parameter
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
 
-class BootState(Row):
+class BootState(AlchemyObj):
     """
     Representation of a row in the boot_states table. To use,
     instantiate with a dict of values.
     """
 
-    table_name = 'boot_states'
-    primary_key = 'boot_state'
-    join_tables = ['nodes']
+    tablename = 'boot_states'
     fields = {
-        'boot_state': Parameter(str, "Boot state", max = 20),
+        'boot_state': Parameter(str, "Boot state", max = 20, primary_key=True),
         }
 
     def validate_boot_state(self, name):
@@ -28,24 +26,32 @@ class BootState(Row):
             raise PLCInvalidArgument, "Boot state must be specified"
 
         # Make sure boot state does not alredy exist
-        conflicts = BootStates(self.api, [name])
+        conflicts = BootStates(self.api, name)
         if conflicts:
             raise PLCInvalidArgument, "Boot state name already in use"
 
         return name
 
-class BootStates(Table):
+    def sync(self, commit=True, validate=True):
+        AlchemyObj.sync(self, commit, validate)
+        AlchemyObj.insert(self, dict(self))
+
+    def delete(self, commit=True):
+        assert 'boot_state' in self
+        AlchemyObj.delete(self, dict(self))                
+
+class BootStates(list):
     """
     Representation of the boot_states table in the database.
     """
 
-    def __init__(self, api, boot_states = None):
-        Table.__init__(self, api, BootState)
-
-        sql = "SELECT %s FROM boot_states" % \
-              ", ".join(BootState.fields)
-
-        if boot_states:
-            sql += " WHERE boot_state IN (%s)" % ", ".join( [ api.db.quote (s) for s in boot_states ] )
+    def __init__(self, api, filter = None):
+        if not filter:
+            boot_states = BootState().select()
+        elif isinstance(filter, StringTypes) or isinstance(filter, (list, tuple, set)):
+            boot_states = BootState().select(filter={'boot_state': filter})
+        else:
+            raise PLCInvalidArgument, "Wrong boot state filter %r" filter
 
-        self.selectall(sql)
+        for boot_state in boot_states:
+            self.append(boot_state)
index 32a1b54..c753fbf 100644 (file)
@@ -7,22 +7,20 @@
 
 from PLC.Faults import *
 from PLC.Parameter import Parameter
-from PLC.Filter import Filter
-from PLC.Table import Row, Table
 from PLC.Nodes import Node, Nodes
 from PLC.NodeGroups import NodeGroup, NodeGroups
+from PLC.Storage.AlchemyObject import AlchemyObj
 
-class ConfFile(Row):
+class ConfFile(AlchemyObj):
     """
     Representation of a row in the conf_files table. To use,
     instantiate with a dict of values.
     """
 
-    table_name = 'conf_files'
-    primary_key = 'conf_file_id'
+    tablename = 'conf_files'
     join_tables = ['conf_file_node', 'conf_file_nodegroup']
     fields = {
-        'conf_file_id': Parameter(int, "Configuration file identifier"),
+        'conf_file_id': Parameter(int, "Configuration file identifier", primary_key=True),
         'enabled': Parameter(bool, "Configuration file is active"),
         'source': Parameter(str, "Relative path on the boot server where file can be downloaded", max = 255),
         'dest': Parameter(str, "Absolute path where file should be installed", max = 255),
@@ -34,8 +32,8 @@ class ConfFile(Row):
         'error_cmd': Parameter(str, "Shell command to execute if any error occurs", max = 1024, nullok = True),
         'ignore_cmd_errors': Parameter(bool, "Install file anyway even if an error occurs"),
         'always_update': Parameter(bool, "Always attempt to install file even if unchanged"),
-        'node_ids': Parameter(int, "List of nodes linked to this file"),
-        'nodegroup_ids': Parameter(int, "List of node groups linked to this file"),
+        'node_ids': Parameter(int, "List of nodes linked to this file", joined=True),
+        'nodegroup_ids': Parameter(int, "List of node groups linked to this file", joined=True),
         }
 
     def add_node(self, node, commit = True):
@@ -132,22 +130,29 @@ class ConfFile(Row):
             self['nodegroup_ids'].remove(nodegroup_id)
             nodegroup['conf_file_ids'].remove(conf_file_id)
 
-class ConfFiles(Table):
+    def sync(self, commit=True, validate=True):
+        AlchemyObj.sync(self, commit, validate)
+        if 'conf_file_id' not in self:
+            AlchemyObj.insert(self, dict(self))
+        else:
+            AlchemyObj.update(self, self['conf_file_id'], dict(self))
+
+    def delete(self, commit=True):
+        assert 'conf_file_id' in self
+        AlchemyObj.delete(self, dict(self))
+
+class ConfFiles(list):
     """
     Representation of the conf_files table in the database.
     """
 
     def __init__(self, api, conf_file_filter = None, columns = None):
-        Table.__init__(self, api, ConfFile, columns)
-
-        sql = "SELECT %s FROM view_conf_files WHERE True" % \
-              ", ".join(self.columns)
-
-        if conf_file_filter is not None:
-            if isinstance(conf_file_filter, (list, tuple, set, int, long)):
-                conf_file_filter = Filter(ConfFile.fields, {'conf_file_id': conf_file_filter})
-            elif isinstance(conf_file_filter, dict):
-                conf_file_filter = Filter(ConfFile.fields, conf_file_filter)
-            sql += " AND (%s) %s" % conf_file_filter.sql(api)
-
-        self.selectall(sql)
+        if not conf_file_filter:
+            conf_files = ConfFile().select()
+        elif isinstance(conf_file_filter, (list, tuple, set, int, long)):
+            conf_files = ConfFile().select(filter={'conf_file_id': conf_file_filter})
+        elif isinstance(conf_file_filter, dict):
+            conf_files = ConfFile().select(filter=conf_file_filter)
+
+        for conf_file in conf_files:
+            self.append(conf_file)
index d99f13c..35b1dbd 100644 (file)
@@ -3,47 +3,51 @@
 #
 from PLC.Faults import *
 from PLC.Parameter import Parameter
-from PLC.Filter import Filter
-from PLC.Table import Row, Table
 from PLC.Interfaces import Interface, Interfaces
 from PLC.TagTypes import TagType, TagTypes
+from PLC.Storage.AlchemyObject import AlchemyObj
 
-class Ilink(Row):
+class Ilink(AlchemyObj):
     """
     Representation of a row in the ilink table.
     To use, instantiate with a dict of values.
     """
 
-    table_name = 'ilink'
-    primary_key = 'ilink_id'
+    tablename = 'ilink'
     fields = {
-        'ilink_id': Parameter(int, "ilink identifier"),
+        'ilink_id': Parameter(int, "ilink identifier", primary_key=True),
         'tag_type_id': TagType.fields['tag_type_id'],
         'src_interface_id': Parameter(int, "source interface identifier"),
         'dst_interface_id': Parameter(int, "destination interface identifier"),
         'value': Parameter( str, "optional ilink value"),
         }
 
-class Ilinks(Table):
+    def sync(self, insert=False, validate=True):
+        AlchemyObj.sync(self, commit, validate)
+        if 'ilink_id' in self:
+            AlchemyObj.insert(self, dict(self))
+        else:
+            AlchemyObj.update(self, self['ilink_id'], dict(self))
+
+    def delete(self, commit=True):
+        assert 'ilink_id' in self
+        AlchemyObj.delete(self, dict(self))
+
+class Ilinks(list):
     """
     Representation of row(s) from the ilink table in the
     database.
     """
 
     def __init__(self, api, ilink_filter = None, columns = None):
-        Table.__init__(self, api, Ilink, columns)
-
-        sql = "SELECT %s FROM view_ilinks WHERE True" % \
-              ", ".join(self.columns)
-
-        if ilink_filter is not None:
-            if isinstance(ilink_filter, (list, tuple, set, int, long)):
-                ilink_filter = Filter(Ilink.fields, {'ilink_id': ilink_filter})
-            elif isinstance(ilink_filter, dict):
-                ilink_filter = Filter(Ilink.fields, ilink_filter)
-            else:
-                raise PLCInvalidArgument, "Wrong ilink filter %r"%ilink_filter
-            sql += " AND (%s) %s" % ilink_filter.sql(api)
-
-
-        self.selectall(sql)
+        if not ilink_filter:
+            ilinks = Ilink().select()
+        elif isinstance(ilink_filter, (list, tuple, set, int, long)):
+            ilinks = Ilink().select(filter={'ilink_id': ilink_filter})
+        elif isinstance(ilink_filter, dict):
+            ilink_filter = Ilink().select(filter=ilink_filter)
+        else:
+            raise PLCInvalidArgument, "Wrong ilink filter %r"%ilink_filter
+
+        for ilink in ilinks:
+            self.append(ilink)
index c248c83..29a5818 100644 (file)
@@ -8,20 +8,18 @@
 from types import StringTypes
 from PLC.Faults import *
 from PLC.Parameter import Parameter
-from PLC.Filter import Filter
-from PLC.Table import Row, Table
+from PLC.Storage.AlchemyObject import AlchemyObj
 
-class InitScript(Row):
+class InitScript(AlchemyObj):
     """
     Representation of a row in the initscripts table. To use,
     instantiate with a dict of values.
     """
 
-    table_name = 'initscripts'
-    primary_key = 'initscript_id'
+    tablename = 'initscripts'
     join_tables = []
     fields = {
-        'initscript_id': Parameter(int, "Initscript identifier"),
+        'initscript_id': Parameter(int, "Initscript identifier", primary_key=True),
         'name': Parameter(str, "Initscript name", max = 254),
         'enabled': Parameter(bool, "Initscript is active"),
         'script': Parameter(str, "Initscript"),
@@ -32,42 +30,46 @@ class InitScript(Row):
         validates the script name
         """
 
-        conflicts = InitScripts(self.api, [name])
+        conflicts = InitScripts(self.api, name)
         for initscript in conflicts:
             if 'initscript_id' not in self or self['initscript_id'] != initscript['initscript_id']:
                 raise PLCInvalidArgument, "Initscript name already in use"
 
         return name
 
+    def sync(self, commit=True, validate=True):
+        AlchemyObj.sync(self, commit, validate)
+        if 'initscript_id' not in self:
+            AlchemyObj.insert(self, dict(self))
+        else:
+            AlchemyObj.update(self, self['initscript_id'], dict(self))
 
-class InitScripts(Table):
+    def delete(self, commit=True):
+        assert 'initscript_id' in self
+        AlchemyObj.delete(self, dict(self))
+
+
+class InitScripts(list):
     """
     Representation of the initscripts table in the database.
     """
 
     def __init__(self, api, initscript_filter = None, columns = None):
-        Table.__init__(self, api, InitScript, columns)
-
-        sql = "SELECT %s FROM initscripts WHERE True" % \
-              ", ".join(self.columns)
-
-        if initscript_filter is not None:
-            if isinstance(initscript_filter, (list, tuple, set)):
-                # Separate the list into integers and strings
-                ints = filter(lambda x: isinstance(x, (int, long)), initscript_filter)
-                strs = filter(lambda x: isinstance(x, StringTypes), initscript_filter)
-                initscript_filter = Filter(InitScript.fields, {'initscript_id': ints, 'name': strs })
-                sql += " AND (%s) %s" % initscript_filter.sql(api, "OR")
-            elif isinstance(initscript_filter, dict):
-                initscript_filter = Filter(InitScript.fields, initscript_filter)
-                sql += " AND (%s) %s" % initscript_filter.sql(api, "AND")
-            elif isinstance(initscript_filter, (int, long)):
-                initscript_filter = Filter(InitScript.fields, {'initscript_id': initscript_filter})
-                sql += " AND (%s) %s" % initscript_filter.sql(api, "AND")
-            elif isinstance(initscript_filter, StringTypes):
-                initscript_filter = Filter(InitScript.fields, {'name': initscript_filter})
-                sql += " AND (%s) %s" % initscript_filter.sql(api, "AND")
-            else:
-                raise PLCInvalidArgument, "Wrong initscript filter %r"%initscript_filter
+        if not initscript_filter:
+            initscripts = InitScript().select()
+        elif isinstance(initscript_filter, (list, tuple, set)):
+            # Separate the list into integers and strings
+            ints = filter(lambda x: isinstance(x, (int, long)), initscript_filter)
+            strs = filter(lambda x: isinstance(x, StringTypes), initscript_filter)
+            initscripts = InitScript().select(filter={'initscript_id': ints, 'name': strs })
+        elif isinstance(initscript_filter, dict):
+            initscripts = InitScript().select(filter=initscript_filter)
+        elif isinstance(initscript_filter, (int, long)):
+            initscripts = InitScript().select(filter={'initscript_id': initscript_filter })
+        elif isinstance(initscript_filter, StringTypes):
+            initscripts = InitScript().select(filter={'name': initscript_filter })
+        else:
+            raise PLCInvalidArgument, "Wrong initscript filter %r"%initscript_filter
 
-        self.selectall(sql)
+        for initscript in initscripts:
+            self.append(initscript)
index b30ec37..eb8cc7b 100644 (file)
@@ -5,7 +5,6 @@ import datetime
 
 from PLC.Faults import *
 from PLC.Parameter import Parameter, Mixed
-from PLC.Filter import Filter
 from PLC.Debug import profile
 from PLC.Nodes import Node
 from PLC.Persons import Person, Persons