steps towards computing wsdl files at build-time:
[sfa.git] / sfa / util / genitable.py
1 # genitable.py
2 #
3 # implements support for geni records stored in db tables
4 #
5 # TODO: Use existing PLC database methods? or keep this separate?
6
7 ### $Id$
8 ### $URL$
9
10 import report
11
12 from pg import DB, ProgrammingError
13
14 from sfa.trust.gid import *
15 from sfa.util.record import *
16 from sfa.util.debug import *
17
18 GENI_TABLE_PREFIX = "geni$"
19
20 class GeniTable:
21     def __init__(self, create=False, hrn="unspecified.default.registry", cninfo=None):
22         global GENI_TABLE_PREFIX
23
24         self.hrn = hrn
25
26         # pgsql doesn't like table names with "." in them, to replace it with "$"
27         self.tablename = GENI_TABLE_PREFIX + self.hrn.replace(".", "$")
28
29         # establish a connection to the pgsql server
30         self.cnx = DB(cninfo['dbname'], cninfo['address'], port=cninfo['port'], user=cninfo['user'], passwd=cninfo['password'])
31
32         # if asked to create the table, then create it
33         if create:
34             self.create()
35
36     def exists(self):
37         tableList = self.cnx.get_tables()
38         if 'public.' + self.tablename in tableList:
39             return True
40         if 'public."' + self.tablename + '"' in tableList:
41             return True
42         return False
43
44     def create(self):
45         
46         querystr = "CREATE TABLE " + self.tablename + " ( \
47                 key text, \
48                 name text, \
49                 gid text, \
50                 type text, \
51                 pointer integer);"
52         template = "CREATE INDEX %s_%s_idx ON %s (%s);"
53         indexes = [template % ( self.tablename, field, self.tablename, field) \
54                    for field in ['name', 'type' ]]
55         # IF EXISTS doenst exist in postgres < 8.2
56         try:
57             self.cnx.query('DROP TABLE IF EXISTS ' + self.tablename)
58         except ProgrammingError:
59             try:
60                 self.cnx.query('DROP TABLE ' + self.tablename)
61             except ProgrammingError:
62                 pass
63         
64         self.cnx.query(querystr)
65         for index in indexes:
66             self.cnx.query(index)
67
68     def remove(self, record):
69         query_str = "DELETE FROM " + self.tablename + " WHERE key = '" + record.get_key() + "'"
70         self.cnx.query(query_str)
71
72     def insert(self, record):
73         fieldnames = ["key"] + record.get_field_names()
74         fieldvals = record.get_field_value_strings(fieldnames)
75         query_str = "INSERT INTO " + self.tablename + \
76                        "(" + ",".join(fieldnames) + ") " + \
77                        "VALUES(" + ",".join(fieldvals) + ")"
78         #print query_str
79         self.cnx.query(query_str)
80
81     def update(self, record):
82         names = record.get_field_names()
83         pairs = []
84         for name in names:
85            val = record.get_field_value_string(name)
86            pairs.append(name + " = " + val)
87         update = ", ".join(pairs)
88
89         query_str = "UPDATE " + self.tablename+ " SET " + update + " WHERE key = '" + record.get_key() + "'"
90         #print query_str
91         self.cnx.query(query_str)
92
93     def find_dict(self, type, value, searchfield):
94         query_str = "SELECT * FROM " + self.tablename + " WHERE " + searchfield + " = '" + str(value) + "'"
95         dict_list = self.cnx.query(query_str).dictresult()
96         result_dict_list = []
97         for dict in dict_list:
98            if (type=="*") or (dict['type'] == type):
99                dict['hrn'] = dict['name'] 
100                result_dict_list.append(dict)
101         return result_dict_list
102
103     def find(self, type, value, searchfield):
104         result_dict_list = self.find_dict(type, value, searchfield)
105         result_rec_list = []
106         for result in result_dict_list:
107             if result['type'] in ['authority']:
108                 result_rec_list.append(AuthorityRecord(dict=result))
109             elif result['type'] in ['node']:
110                 result_rec_list.append(NodeRecord(dict=result))
111             elif result['type'] in ['slice']:
112                 result_rec_list.append(SliceRecord(dict=result))
113             elif result['type'] in ['user']:
114                 result_rec_list.append(UserRecord(dict=result))
115             else:
116                 result_rec_list.append(GeniRecord(dict=result))
117         return result_rec_list
118
119     def resolve_dict(self, type, hrn):
120         return self.find_dict(type, hrn, "name")
121
122     def resolve(self, type, hrn):
123         return self.find(type, hrn, "name")
124
125     def list_dict(self):
126         query_str = "SELECT * FROM " + self.tablename
127         result_dict_list = self.cnx.query(query_str).dictresult()
128         return result_dict_list
129
130     def list(self):
131         result_dict_list = self.list_dict()
132         result_rec_list = []
133         for dict in result_dict_list:
134             result_rec_list.append(GeniRecord(dict=dict).as_dict())
135         return result_rec_list
136
137 def set_geni_table_prefix(x):
138     global GENI_TABLE_PREFIX
139
140     GENI_TABLE_PREFIX = x
141
142 def geni_records_purge(cninfo):
143     global GENI_TABLE_PREFIX
144
145     cnx = DB(cninfo['dbname'], cninfo['address'], port=cninfo['port'], user=cninfo['user'], passwd=cninfo['password'])
146     tableList = cnx.get_tables()
147     for table in tableList:
148         if table.startswith(GENI_TABLE_PREFIX) or \
149            table.startswith('public.' + GENI_TABLE_PREFIX) or \
150            table.startswith('public."' + GENI_TABLE_PREFIX):
151                report.trace("dropping table " + table)
152                cnx.query("DROP TABLE " + table)