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