Fix version output when missing.
[plcapi.git] / PLC / PCUTypes.py
1 #
2 # Functions for interacting with the pcu_types table in the database
3 #
4 # Mark Huang <mlhuang@cs.princeton.edu>
5 # Copyright (C) 2006 The Trustees of Princeton University
6 #
7 # $Id$
8 # $URL$
9 #
10 from types import StringTypes
11
12 from PLC.Faults import *
13 from PLC.Parameter import Parameter
14 from PLC.Table import Row, Table
15 from PLC.Filter import Filter
16
17 class PCUType(Row):
18     """
19     Representation of a row in the pcu_types table. To use,
20     instantiate with a dict of values.
21     """
22
23     table_name = 'pcu_types'
24     primary_key = 'pcu_type_id'
25     join_tables = ['pcu_protocol_type']
26     fields = {
27         'pcu_type_id': Parameter(int, "PCU Type Identifier"),
28         'model': Parameter(str, "PCU model", max = 254),
29         'name': Parameter(str, "PCU full name", max = 254),
30         'pcu_protocol_type_ids': Parameter([int], "PCU Protocol Type Identifiers"),
31         'pcu_protocol_types': Parameter([dict], "PCU Protocol Type List")
32         }
33
34     def validate_model(self, model):
35         # Make sure name is not blank
36         if not len(model):
37             raise PLCInvalidArgument, "Model must be specified"
38
39         # Make sure boot state does not alredy exist
40         conflicts = PCUTypes(self.api, [model])
41         for pcu_type in conflicts:
42             if 'pcu_type_id' not in self or self['pcu_type_id'] != pcu_type['pcu_type_id']:
43                 raise PLCInvalidArgument, "Model already in use"
44
45         return model
46
47 class PCUTypes(Table):
48     """
49     Representation of the pcu_types table in the database.
50     """
51
52     def __init__(self, api, pcu_type_filter = None, columns = None):
53
54         # Remove pcu_protocol_types from query since its not really a field
55         # in the db. We will add it later
56         if columns == None:
57             columns = PCUType.fields.keys()
58         if 'pcu_protocol_types' in columns:
59             removed_fields = ['pcu_protocol_types']
60             columns.remove('pcu_protocol_types')
61         else:
62             removed_fields = []
63
64         Table.__init__(self, api, PCUType, columns)
65
66         sql = "SELECT %s FROM view_pcu_types WHERE True" % \
67               ", ".join(self.columns)
68
69         if pcu_type_filter is not None:
70             if isinstance(pcu_type_filter, (list, tuple, set)):
71                 # Separate the list into integers and strings
72                 ints = filter(lambda x: isinstance(x, (int, long)), pcu_type_filter)
73                 strs = filter(lambda x: isinstance(x, StringTypes), pcu_type_filter)
74                 pcu_type_filter = Filter(PCUType.fields, {'pcu_type_id': ints, 'model': strs})
75                 sql += " AND (%s) %s" % pcu_type_filter.sql(api, "OR")
76             elif isinstance(pcu_type_filter, dict):
77                 pcu_type_filter = Filter(PCUType.fields, pcu_type_filter)
78                 sql += " AND (%s) %s" % pcu_type_filter.sql(api, "AND")
79             elif isinstance (pcu_type_filter, StringTypes):
80                 pcu_type_filter = Filter(PCUType.fields, {'model':pcu_type_filter})
81                 sql += " AND (%s) %s" % pcu_type_filter.sql(api, "AND")
82             elif isinstance (pcu_type_filter, int):
83                 pcu_type_filter = Filter(PCUType.fields, {'pcu_type_id':pcu_type_filter})
84                 sql += " AND (%s) %s" % pcu_type_filter.sql(api, "AND")
85             else:
86                 raise PLCInvalidArgument, "Wrong pcu_type filter %r"%pcu_type_filter
87
88
89         self.selectall(sql)
90
91          # return a list of protocol type objects for each port type
92         if 'pcu_protocol_types' in removed_fields:
93             from PLC.PCUProtocolTypes import PCUProtocolTypes
94             protocol_type_ids = set()
95             for pcu_type in self:
96                 protocol_type_ids.update(pcu_type['pcu_protocol_type_ids'])
97
98             protocol_return_fields = ['pcu_protocol_type_id', 'port', 'protocol', 'supported']
99             all_protocol_types = PCUProtocolTypes(self.api, list(protocol_type_ids), \
100                                                   protocol_return_fields).dict('pcu_protocol_type_id')
101
102             for pcu_type in self:
103                 pcu_type['pcu_protocol_types'] = []
104                 for protocol_type_id in pcu_type['pcu_protocol_type_ids']:
105                     pcu_type['pcu_protocol_types'].append(all_protocol_types[protocol_type_id])