9149deb235086e716392eb773dacd67126ba8350
[sfa.git] / util / record.py
1 # record.py
2 #
3 # implements support for geni records
4 #
5 # TODO: Use existing PLC database methods? or keep this separate?
6
7 from pg import DB
8
9 GENI_TABLE_PREFIX = "geni$"
10
11 # Record is a tuple (Name, GID, Type, Info)
12 #    info is comprised of the following sub-fields
13 #        pointer = a pointer to the record in the PL database
14 #        pl_info = planetlab-specific info (when talking to client)
15 #        geni_info = geni-specific info (when talking to client)
16
17 class GeniRecord():
18     def __init__(self, name=None, gid=None, type=None, pointer=None, dict=None):
19         self.dirty = True
20         self.pl_info = None
21         self.geni_info = None
22         if name:
23             self.set_name(name)
24         if gid:
25             self.set_gid(gid)
26         if type:
27             self.set_type(type)
28         if pointer:
29             self.set_pointer(pointer)
30         if dict:
31             self.set_name(dict['name'])
32             self.set_gid(dict['gid'])
33             self.set_type(dict['type'])
34             self.set_pointer(dict['pointer'])
35             if "pl_info" in dict:
36                self.set_pl_info(dict["pl_info"])
37             if "geni_info" in dict:
38                self.set_geni_info(dict["geni_info"])
39
40     def set_name(self, name):
41         self.name = name
42         self.dirty = True
43
44     def set_gid(self, gid):
45         self.gid = gid
46         self.dirty = True
47
48     def set_type(self, type):
49         self.type = type
50         self.dirty = True
51
52     def set_pointer(self, pointer):
53         self.pointer = pointer
54         self.dirty = True
55
56     def set_pl_info(self, pl_info):
57         self.pl_info = pl_info
58         self.dirty = True
59
60     def set_geni_info(self, geni_info):
61         self.geni_info = geni_info
62         self.dirty = True
63
64     def get_pl_info(self):
65         if self.pl_info:
66             return self.pl_info
67         else:
68             return {}
69
70     def get_geni_info(self):
71         if self.geni_info:
72             return self.geni_info
73         else:
74             return {}
75
76     def get_pointer(self):
77         return pointer
78
79     def get_key(self):
80         return self.name + "#" + self.type
81
82     def get_field_names(self):
83         return ["name", "gid", "type", "pointer"]
84
85     def get_field_value_string(self, fieldname):
86         if fieldname == "key":
87             val = self.get_key()
88         else:
89             val = getattr(self, fieldname)
90         if isinstance(val, str):
91             return "'" + str(val) + "'"
92         else:
93             return str(val)
94
95     def get_field_value_strings(self, fieldnames):
96         strs = []
97         for fieldname in fieldnames:
98             strs.append(self.get_field_value_string(fieldname))
99         return strs
100
101     def as_dict(self):
102         dict = {}
103         names = self.get_field_names()
104         for name in names:
105             dict[name] = self.getattr(name)
106
107         if self.pl_info:
108             dict['pl_info'] = self.pl_info
109
110         if self.geni_info:
111             dict['geni_info'] = self.geni_info
112
113         return dict
114
115 # GeniTable
116 #
117 # Represents a single table on a registry for a single authority.
118
119 class GeniTable():
120     def __init__(self, create=False, hrn="unspecified.default.registry", cninfo=None):
121         global GENI_TABLE_PREFIX
122
123         self.hrn = hrn
124
125         # pgsql doesn't like table names with "." in them, to replace it with "$"
126         self.tablename = GENI_TABLE_PREFIX + self.hrn.replace(".", "$")
127
128         # establish a connection to the pgsql server
129         self.cnx = DB(cninfo['dbname'], cninfo['address'], port=cninfo['port'], user=cninfo['user'], passwd=cninfo['password'])
130
131         # if asked to create the table, then create it
132         if create:
133             self.create()
134
135     def exists(self):
136         tableList = self.cnx.get_tables()
137         return (self.tablename in tableList)
138
139     def create(self):
140         querystr = "CREATE TABLE " + self.tablename + " ( \
141                 key text, \
142                 name text, \
143                 gid text, \
144                 type text, \
145                 pointer integer);"
146
147         self.cnx.query('DROP TABLE IF EXISTS ' + self.tablename)
148         self.cnx.query(querystr)
149
150     def remove(self, record):
151         query_str = "DELETE FROM " + self.tablename + " WHERE key = '" + record.get_key() + "'"
152         self.cnx.quert(query_str)
153
154     def insert(self, record):
155         fieldnames = ["key"] + record.get_field_names()
156         fieldvals = record.get_field_value_strings(fieldnames)
157         query_str = "INSERT INTO " + self.tablename + \
158                        "(" + ",".join(fieldnames) + ") " + \
159                        "VALUES(" + ",".join(fieldvals) + ")"
160         #print query_str
161         self.cnx.query(query_str)
162
163     def update(self, record):
164         names = record.get_field_names()
165         pairs = []
166         for name in names:
167            val = record.get_field_value_string(name)
168            pairs.append(name + " = " + val)
169         update = ", ".join(pairs)
170
171         query_str = "UPDATE " + self.tablename+ " SET " + update + " WHERE key = '" + record.get_key() + "'"
172         #print query_str
173         self.cnx.query(query_str)
174
175     def resolve_dict(self, type, hrn):
176         query_str = "SELECT * FROM " + self.tablename + " WHERE name = '" + hrn + "'"
177         dict_list = self.cnx.query(query_str).dictresult()
178         result_dict_list = []
179         for dict in dict_list:
180            if (type=="*") or (dict['type'] == type):
181                result_dict_list.append(dict)
182         return result_dict_list
183
184     def resolve(self, type, hrn):
185         result_dict_list = self.resolve_dict(type, hrn)
186         result_rec_list = []
187         for dict in result_dict_list:
188             result_rec_list.append(GeniRecord(dict=dict))
189         return result_rec_list
190
191     def list_dict(self):
192         query_str = "SELECT * FROM " + self.tablename
193         result_dict_list = self.cnx.query(query_str).dictresult()
194         return result_dict_list
195
196     def list(self):
197         result_dict_list = self.list_dict()
198         result_rec_list = []
199         for dict in result_dict_list:
200             result_rec_list.append(GeniRecord(dict=dict))
201         return result_rec_list
202
203 def set_geni_table_prefix(x):
204     global GENI_TABLE_PREFIX
205
206     GENI_TABLE_PREFIX = x
207
208 def geni_records_purge(cninfo):
209     global GENI_TABLE_PREFIX
210
211     cnx = DB(cninfo['dbname'], cninfo['address'], port=cninfo['port'], user=cninfo['user'], passwd=cninfo['password'])
212     tableList = cnx.get_tables()
213     for table in tableList:
214         if table.startswith(GENI_TABLE_PREFIX):
215             cnx.query("DROP TABLE " + table)