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