From: Mark Huang Date: Wed, 8 Nov 2006 23:02:39 +0000 (+0000) Subject: - use Filter to select rows X-Git-Tag: pycurl-7_13_1~352 X-Git-Url: http://git.onelab.eu/?p=plcapi.git;a=commitdiff_plain;h=99a5ef4577d6addbc08a5e04ddab65d3c3f4198f - use Filter to select rows - psycopg2 obviates the need for manual aggregation --- diff --git a/PLC/ConfFiles.py b/PLC/ConfFiles.py index ef0e301..2244bcf 100644 --- a/PLC/ConfFiles.py +++ b/PLC/ConfFiles.py @@ -4,11 +4,12 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: ConfFiles.py,v 1.6 2006/11/02 18:32:55 mlhuang Exp $ +# $Id: ConfFiles.py,v 1.7 2006/11/06 20:48:33 mlhuang Exp $ # 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 @@ -35,8 +36,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", ro = True), - 'nodegroup_ids': Parameter(int, "List of node groups linked to this file", ro = True), + 'node_ids': Parameter(int, "List of nodes linked to this file"), + 'nodegroup_ids': Parameter(int, "List of node groups linked to this file"), } def add_node(self, node, commit = True): @@ -138,27 +139,17 @@ class ConfFiles(Table): Representation of the conf_files table in the database. """ - def __init__(self, api, conf_file_ids = None, enabled = None): + def __init__(self, api, conf_file_filter = None): + Table.__init__(self, api, ConfFile) + sql = "SELECT %s FROM view_conf_files WHERE True" % \ ", ".join(ConfFile.fields) - - if conf_file_ids: - # Separate the list into integers and strings - sql += " AND conf_file_id IN (%s)" % ", ".join(map(str, api.db.quote(conf_file_ids))) - - if enabled is not None: - sql += " AND enabled = %(enabled)s" - - rows = api.db.selectall(sql, locals()) - - for row in rows: - self[row['conf_file_id']] = ConfFile(api, row) + if conf_file_filter is not None: + if isinstance(conf_file_filter, list): + 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)" % conf_file_filter.sql(api) - for row in rows: - self[row['conf_file_id']] = conf_file = ConfFile(api, row) - for aggregate in ['node_ids', 'nodegroup_ids']: - if not conf_file.has_key(aggregate) or conf_file[aggregate] is None: - conf_file[aggregate] = [] - else: - conf_file[aggregate] = map(int, conf_file[aggregate].split(',')) + self.selectall(sql) diff --git a/PLC/ForeignNodes.py b/PLC/ForeignNodes.py index 9bc0c63..ba482e4 100644 --- a/PLC/ForeignNodes.py +++ b/PLC/ForeignNodes.py @@ -6,6 +6,7 @@ from types import StringTypes from PLC.Table import Row, Table from PLC.Parameter import Parameter +from PLC.Filter import Filter class ForeignNode (Row) : """ @@ -42,31 +43,21 @@ class ForeignNode (Row) : class ForeignNodes (Table): - def __init__ (self, api, foreign_node_id_or_hostname_list=None): + def __init__ (self, api, foreign_node_filter = None): + Table.__init__(self, api, ForeignNode) - self.api=api + sql = "SELECT %s FROM view_foreign_nodes WHERE deleted IS False" % \ + ", ".join(ForeignNode.fields) - sql ="" - sql += "SELECT %s FROM view_foreign_nodes " % ", ".join(ForeignNode.fields) - sql += "WHERE view_foreign_nodes.deleted IS False " + if foreign_node_filter is not None: + if isinstance(foreign_node_filter, list): + # Separate the list into integers and strings + ints = filter(lambda x: isinstance(x, (int, long)), foreign_node_filter) + strs = filter(lambda x: isinstance(x, StringTypes), foreign_node_filter) + foreign_node_filter = Filter(ForeignNode.fields, {'node_id': ints, 'hostname': strs}) + sql += " AND (%s)" % foreign_node_filter.sql(api, "OR") + elif isinstance(foreign_node_filter, dict): + foreign_node_filter = Filter(ForeignNode.fields, foreign_node_filter) + sql += " AND (%s)" % foreign_node_filter.sql(api, "AND") - if foreign_node_id_or_hostname_list: - foreign_node_id_list = [ str(x) for x in foreign_node_id_or_hostname_list - if isinstance(x, (int,long))] - hostname_list = [ x for x in foreign_node_id_or_hostname_list - if isinstance(x, StringTypes)] - sql += " AND (False" - if foreign_node_id_list: - sql += " OR node_id in (%s)" % ", ".join(foreign_node_id_list) - if hostname_list: - ## figure how to retrieve peer_id from the hostname(s) - sql += " OR hostname IN (%s)" % ", ".join(api.db.quote(hostname_list)) - sql += ")" - - rows = self.api.db.selectall (sql) - - for row in rows: - self[row['hostname']] = ForeignNode (api,row) - - - + self.selectall(sql) diff --git a/PLC/NodeGroups.py b/PLC/NodeGroups.py index b27c3a0..34d73b0 100644 --- a/PLC/NodeGroups.py +++ b/PLC/NodeGroups.py @@ -4,13 +4,14 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: NodeGroups.py,v 1.15 2006/10/25 14:29:13 mlhuang Exp $ +# $Id: NodeGroups.py,v 1.16 2006/11/02 18:32:55 mlhuang Exp $ # from types import StringTypes from PLC.Faults import * from PLC.Parameter import Parameter +from PLC.Filter import Filter from PLC.Debug import profile from PLC.Table import Row, Table from PLC.Nodes import Node, Nodes @@ -103,31 +104,21 @@ class NodeGroups(Table): database. """ - def __init__(self, api, nodegroup_id_or_name_list = None): - self.api = api + def __init__(self, api, nodegroup_filter = None): + Table.__init__(self, api, NodeGroup) - sql = "SELECT %s FROM view_nodegroups" % \ + sql = "SELECT %s FROM view_nodegroups WHERE True" % \ ", ".join(NodeGroup.fields) - if nodegroup_id_or_name_list: - # Separate the list into integers and strings - nodegroup_ids = filter(lambda nodegroup_id: isinstance(nodegroup_id, (int, long)), - nodegroup_id_or_name_list) - names = filter(lambda name: isinstance(name, StringTypes), - nodegroup_id_or_name_list) - sql += " WHERE (False" - if nodegroup_ids: - sql += " OR nodegroup_id IN (%s)" % ", ".join(map(str, nodegroup_ids)) - if names: - sql += " OR name IN (%s)" % ", ".join(api.db.quote(names)) - sql += ")" - - rows = self.api.db.selectall(sql) - - for row in rows: - self[row['nodegroup_id']] = nodegroup = NodeGroup(api, row) - for aggregate in ['node_ids', 'conf_file_ids']: - if not nodegroup.has_key(aggregate) or nodegroup[aggregate] is None: - nodegroup[aggregate] = [] - else: - nodegroup[aggregate] = map(int, nodegroup[aggregate].split(',')) + if nodegroup_filter is not None: + if isinstance(nodegroup_filter, list): + # Separate the list into integers and strings + ints = filter(lambda x: isinstance(x, (int, long)), nodegroup_filter) + strs = filter(lambda x: isinstance(x, StringTypes), nodegroup_filter) + nodegroup_filter = Filter(NodeGroup.fields, {'nodegroup_id': ints, 'name': strs}) + sql += " AND (%s)" % nodegroup_filter.sql(api, "OR") + elif isinstance(nodegroup_filter, dict): + nodegroup_filter = Filter(NodeGroup.fields, nodegroup_filter) + sql += " AND (%s)" % nodegroup_filter.sql(api, "AND") + + self.selectall(sql) diff --git a/PLC/PCUs.py b/PLC/PCUs.py index aa047c0..e3d9292 100644 --- a/PLC/PCUs.py +++ b/PLC/PCUs.py @@ -4,11 +4,12 @@ # Mark Huang # Copyright (C) 2006 The Trustees of Princeton University # -# $Id: PCUs.py,v 1.6 2006/10/25 14:29:13 mlhuang Exp $ +# $Id: PCUs.py,v 1.7 2006/11/02 18:32:55 mlhuang Exp $ # from PLC.Faults import * from PLC.Parameter import Parameter +from PLC.Filter import Filter from PLC.Debug import profile from PLC.Table import Row, Table from PLC.NodeNetworks import valid_ip, NodeNetwork, NodeNetworks @@ -33,8 +34,8 @@ class PCU(Row): 'password': Parameter(str, "PCU username", max = 254, nullok = True), 'notes': Parameter(str, "Miscellaneous notes", max = 254, nullok = True), 'model': Parameter(str, "PCU model string", max = 32, nullok = True), - 'node_ids': Parameter([int], "List of nodes that this PCU controls", ro = True), - 'ports': Parameter([int], "List of the port numbers that each node is connected to", ro = True), + 'node_ids': Parameter([int], "List of nodes that this PCU controls"), + 'ports': Parameter([int], "List of the port numbers that each node is connected to"), } def validate_ip(self, ip): @@ -99,22 +100,17 @@ class PCUs(Table): database. """ - def __init__(self, api, pcu_ids = None): - self.api = api + def __init__(self, api, pcu_filter = None): + Table.__init__(self, api, PCU) - # N.B.: Node IDs returned may be deleted. - sql = "SELECT %s FROM view_pcus" % \ + sql = "SELECT %s FROM view_pcus WHERE True" % \ ", ".join(PCU.fields) - if pcu_ids: - sql += " WHERE pcu_id IN (%s)" % ", ".join(map(str, pcu_ids)) + if pcu_filter is not None: + if isinstance(pcu_filter, list): + pcu_filter = Filter(PCU.fields, {'pcu_id': pcu_filter}) + elif isinstance(pcu_filter, dict): + pcu_filter = Filter(PCU.fields, pcu_filter) + sql += " AND (%s)" % pcu_filter.sql(api) - rows = self.api.db.selectall(sql) - - for row in rows: - self[row['pcu_id']] = pcu = PCU(api, row) - for aggregate in ['node_ids', 'ports']: - if not pcu.has_key(aggregate) or pcu[aggregate] is None: - pcu[aggregate] = [] - else: - pcu[aggregate] = map(int, pcu[aggregate].split(',')) + self.selectall(sql) diff --git a/PLC/Peers.py b/PLC/Peers.py index c887702..d4fed75 100644 --- a/PLC/Peers.py +++ b/PLC/Peers.py @@ -8,6 +8,7 @@ from types import StringTypes from PLC.Faults import * from PLC.Parameter import Parameter +from PLC.Filter import Filter from PLC.Table import Row, Table class Peer (Row): @@ -50,29 +51,21 @@ class Peers (Table): Maps to the peers table in the database """ - def __init__ (self, api, peer_id_or_peername_list = None): - self.api = api + def __init__ (self, api, peer_filter = None): + Table.__init__(self, api, Peer) - sql="SELECT %s FROM view_peers WHERE deleted IS False" % \ - ", ".join(Peer.fields) - if peer_id_or_peername_list: - peer_ids = [x for x in peer_id_or_peername_list if isinstance(x, (int, long))] - peernames = [x for x in peer_id_or_peername_list if isinstance(x, StringTypes)] - sql += " AND (False" - if peer_ids: - sql += " OR peer_id in (%s)"% ", ".join([str(i) for i in peer_ids]) - if peernames: - sql += " OR peername in (%s)"% ". ".join(api.db.quote(peernames)).lower() - sql += ")" - - rows = self.api.db.selectall(sql) - - for row in rows: - self[row['peer_id']] = peer = Peer(api,row) - for aggregate in ['node_ids']: - if not peer.has_key(aggregate) or peer[aggregate] is None: - peer[aggregate] = [] - else: - peer[aggregate] = map(int, peer[aggregate].split(',')) + sql = "SELECT %s FROM view_peers WHERE deleted IS False" % \ + ", ".join(Peer.fields) + if peer_filter is not None: + if isinstance(peer_filter, list): + # Separate the list into integers and strings + ints = filter(lambda x: isinstance(x, (int, long)), peer_filter) + strs = filter(lambda x: isinstance(x, StringTypes), peer_filter) + peer_filter = Filter(Peer.fields, {'peer_id': ints, 'peername': strs}) + sql += " AND (%s)" % peer_filter.sql(api, "OR") + elif isinstance(peer_filter, dict): + peer_filter = Filter(Peer.fields, peer_filter) + sql += " AND (%s)" % peer_filter.sql(api, "AND") + self.selectall(sql) diff --git a/PLC/Sites.py b/PLC/Sites.py index 00fc964..05f480e 100644 --- a/PLC/Sites.py +++ b/PLC/Sites.py @@ -3,6 +3,7 @@ import string from PLC.Faults import * from PLC.Parameter import Parameter +from PLC.Filter import Filter from PLC.Debug import profile from PLC.Table import Row, Table from PLC.Slices import Slice, Slices @@ -34,11 +35,11 @@ class Site(Row): '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", 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), + '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"), } def validate_name(self, name): @@ -228,36 +229,24 @@ class Site(Row): class Sites(Table): """ Representation of row(s) from the sites table in the - database. Specify fields to limit columns to just the specified - fields. + database. """ - def __init__(self, api, site_id_or_login_base_list = None): - self.api = api + def __init__(self, api, site_filter = None): + Table.__init__(self, api, Site) sql = "SELECT %s FROM view_sites WHERE deleted IS False" % \ ", ".join(Site.fields) - if site_id_or_login_base_list: - # Separate the list into integers and strings - site_ids = filter(lambda site_id: isinstance(site_id, (int, long)), - site_id_or_login_base_list) - login_bases = filter(lambda login_base: isinstance(login_base, StringTypes), - site_id_or_login_base_list) - sql += " AND (False" - if site_ids: - sql += " OR site_id IN (%s)" % ", ".join(map(str, site_ids)) - if login_bases: - sql += " OR login_base IN (%s)" % ", ".join(api.db.quote(login_bases)) - sql += ")" - - rows = self.api.db.selectall(sql) - - for row in rows: - self[row['site_id']] = site = Site(api, row) - for aggregate in ['person_ids', 'slice_ids', 'address_ids', - 'pcu_ids', 'node_ids']: - if not site.has_key(aggregate) or site[aggregate] is None: - site[aggregate] = [] - else: - site[aggregate] = map(int, site[aggregate].split(',')) + if site_filter is not None: + if isinstance(site_filter, list): + # Separate the list into integers and strings + ints = filter(lambda x: isinstance(x, (int, long)), site_filter) + strs = filter(lambda x: isinstance(x, StringTypes), site_filter) + site_filter = Filter(Site.fields, {'site_id': ints, 'login_base': strs}) + sql += " AND (%s)" % site_filter.sql(api, "OR") + elif isinstance(site_filter, dict): + site_filter = Filter(Site.fields, site_filter) + sql += " AND (%s)" % site_filter.sql(api, "AND") + + self.selectall(sql)