1 |
# GNU Enterprise Application Server - Session Object |
# GNU Enterprise Application Server - Session Object |
2 |
# |
# |
3 |
# Copyright 2001 Free Software Foundation |
# Copyright 2001-2003 Free Software Foundation |
4 |
# |
# |
5 |
# This file is part of GNU Enterprise. |
# This file is part of GNU Enterprise. |
6 |
# |
# |
24 |
import geasList |
import geasList |
25 |
import geasTrigger |
import geasTrigger |
26 |
import geasAuthentification |
import geasAuthentification |
27 |
|
import whrandom |
28 |
|
|
29 |
|
# ============================================================================= |
30 |
|
# Helper functions |
31 |
|
# ============================================================================= |
32 |
|
|
33 |
|
# ----------------------------------------------------------------------------- |
34 |
|
# Generate a new object_id |
35 |
|
# ----------------------------------------------------------------------------- |
36 |
|
|
37 |
|
def new_object_id (): |
38 |
|
# FIXME: need a better algorithm here |
39 |
|
result = "" |
40 |
|
for i in range (0, 32): |
41 |
|
result = result + str (int (whrandom.random () * 10)) |
42 |
|
return result |
43 |
|
|
44 |
# ============================================================================= |
# ============================================================================= |
45 |
# Session class |
# Session class |
56 |
self._user = "" |
self._user = "" |
57 |
self._connections = connections |
self._connections = connections |
58 |
self._database = "gnue" |
self._database = "gnue" |
59 |
self._activelists = [] |
self._lists = {} |
60 |
|
self._classes = {} |
61 |
|
self._listcount=0 |
62 |
self._authAdapter = geasAuthentification.geasAuthAgent() |
self._authAdapter = geasAuthentification.geasAuthAgent() |
63 |
self._triggerMg = geasTrigger.geasPythonDBTriggerMg(self) |
self._triggerMg = geasTrigger.geasPythonDBTriggerMg(self) |
64 |
|
|
65 |
# --------------------------------------------------------------------------- |
# --------------------------------------------------------------------------- |
66 |
# Log into the application server |
# Log into the application server |
67 |
# --------------------------------------------------------------------------- |
# --------------------------------------------------------------------------- |
94 |
tr=self._triggerMg.getTriggerByEvent('%s:pre_new_list' % classname) |
tr=self._triggerMg.getTriggerByEvent('%s:pre_new_list' % classname) |
95 |
if tr!=None: |
if tr!=None: |
96 |
tr() |
tr() |
97 |
|
|
98 |
# create new List |
# create new List |
99 |
newlist=geasList.geasList (self, classname) |
newlist=geasList.geasList (self, classname) |
100 |
# every new list will be added to the _activelists list |
# every new list will be added to the _lists list |
101 |
# which will be parsed for commit and rollback actions |
# which will be parsed for commit and rollback actions |
102 |
self._activelists.append(newlist) |
self._listcount+=1 |
103 |
|
self._lists[self._listcount]=newlist |
104 |
return newlist; |
return newlist; |
105 |
|
|
106 |
else: # no access |
else: # no access |
111 |
# --------------------------------------------------------------------------- |
# --------------------------------------------------------------------------- |
112 |
|
|
113 |
def commit (self): |
def commit (self): |
114 |
for l in self._activelists: |
for l in self._lists.keys(): |
115 |
l._resultset.post() |
if hasattr(self._lists[l],"_datasource"): |
116 |
l._datasource.commit() |
self._lists[l]._resultset.post() |
117 |
|
self._lists[l]._datasource.commit() |
118 |
|
|
119 |
# --------------------------------------------------------------------------- |
# --------------------------------------------------------------------------- |
120 |
# Rollback the active transaction |
# Rollback the active transaction |
121 |
# --------------------------------------------------------------------------- |
# --------------------------------------------------------------------------- |
122 |
|
|
123 |
def rollback (self): |
def rollback (self): |
124 |
for l in self._activelists: |
for l in self._lists.keys(): |
125 |
if hasattr(l,"_datasource"): |
if hasattr(self._lists[l],"_datasource"): |
126 |
l._datasource.rollback() |
self._lists[l]._datasource.rollback() |
127 |
|
|
128 |
|
|
129 |
|
# --------------------------------------- |
130 |
|
# functions of the new RPC API |
131 |
|
# not well documented and still a subject of change |
132 |
|
# --------------------------------------- |
133 |
|
|
134 |
|
# --------------------------------------------------------------------------- |
135 |
|
# Get the BClass object for the given classname |
136 |
|
# --------------------------------------------------------------------------- |
137 |
|
|
138 |
|
def _getClass(self, classname): |
139 |
|
|
140 |
|
# if bclass already used, then continue to use the old one |
141 |
|
if self._bclasses.has_key(classname): |
142 |
|
return self._bclasses[classname] |
143 |
|
|
144 |
|
|
145 |
|
# build new bclass (Buisness Object Class Manager) |
146 |
|
|
147 |
|
# Authentification |
148 |
|
# TODO: use getRole (n.i.y.) function instead |
149 |
|
if not self._authAdapter.hasAccess (self, self._user, classname): |
150 |
|
raise Error,'Class "%s": No Access Granted or Not Existent' % classname |
151 |
|
|
152 |
|
# build bclass object |
153 |
|
# TODO: replace it with a call to the class repository, like: |
154 |
|
# classrepository.buildBClassManager(classname, self._user, role) |
155 |
|
newbclass=geasBClass.geasBClass (self, classname) |
156 |
|
|
157 |
|
# cache the bclass object |
158 |
|
self._bclasses[classname]=newbclass |
159 |
|
|
160 |
|
return newbclass; |
161 |
|
|
162 |
|
# --------------------------------------------------------------------------- |
163 |
|
# Create a new list of business objects of a given class |
164 |
|
# --------------------------------------------------------------------------- |
165 |
|
|
166 |
|
def request (self, classname, conditions, sortorder, propertylist): |
167 |
|
# FIXME: this list needn't be considered by commit and rollback |
168 |
|
list = self.createList (classname) |
169 |
|
list_id = self._listcount |
170 |
|
list.setPrefetch (["gnue_id"] + propertylist) |
171 |
|
list.setConditions (conditions) |
172 |
|
list.setSort (sortorder) |
173 |
|
list.populate () |
174 |
|
|
175 |
|
return list_id; |
176 |
|
|
177 |
|
# --------------------------------------------------------------------------- |
178 |
|
# Count the number of objects in the list |
179 |
|
# --------------------------------------------------------------------------- |
180 |
|
|
181 |
|
def count (self, list_id): |
182 |
|
list = self._lists [list_id] |
183 |
|
return list.count (); |
184 |
|
|
185 |
|
# --------------------------------------------------------------------------- |
186 |
|
# Fetch data from the database backend |
187 |
|
# --------------------------------------------------------------------------- |
188 |
|
|
189 |
|
def fetch (self, list_id, start, count): |
190 |
|
list = self._lists [list_id] |
191 |
|
return list.fetch (start, count) |
192 |
|
|
193 |
|
# --------------------------------------------------------------------------- |
194 |
|
# Load data from the database backend |
195 |
|
# --------------------------------------------------------------------------- |
196 |
|
|
197 |
|
def load (self, classname, obj_id_list, propertylist): |
198 |
|
# create a temporary geasList |
199 |
|
list = geasList.geasList (self, classname) |
200 |
|
list.setPrefetch (["gnue_id"] + propertylist) |
201 |
|
list.setSort (["gnue_id"]) |
202 |
|
# Accessing the database for every single object_id is not very elegant, |
203 |
|
# but for now it works. -- Reinhard |
204 |
|
result = [] |
205 |
|
for object_id in obj_id_list: |
206 |
|
list.setConditions ([['eq', ''], ['field', 'gnue_id'], |
207 |
|
['const', object_id]]) |
208 |
|
list.populate () |
209 |
|
object = list.firstInstance () |
210 |
|
row = {} |
211 |
|
for property in propertylist: |
212 |
|
row [property] = object.get (property) |
213 |
|
result.append (row) |
214 |
|
return result |
215 |
|
|
216 |
|
# --------------------------------------------------------------------------- |
217 |
|
# Store data in the database backend |
218 |
|
# --------------------------------------------------------------------------- |
219 |
|
|
220 |
|
def store (self, classname, obj_id_list, propertylist, data): |
221 |
|
result = [] |
222 |
|
i = 0 |
223 |
|
for object_id in obj_id_list: |
224 |
|
# FIXME: if we already have (in this session) a geasInstance that holds |
225 |
|
# exactly this object, then we _must_ reuse it, or the existing |
226 |
|
# geasInstance won't reflect our change! |
227 |
|
|
228 |
|
# FIXME: when new geasInstance is inserted, and we have (in this session) |
229 |
|
# a geasList that this geasInstance would belong into, then insert it |
230 |
|
# into that geasList. |
231 |
|
|
232 |
|
# We have to create a geasList for each object, because commit only |
233 |
|
# operates on lists. We should change that. -- Reinhard |
234 |
|
list = self.createList (classname) |
235 |
|
# We need to "reference" all properties so they become updated. This |
236 |
|
# also should be changed. -- Reinhard |
237 |
|
list.setPrefetch (["gnue_id"] + propertylist) |
238 |
|
list.setSort (["gnue_id"]) |
239 |
|
# Even for an empty object_id, we need to popluate the list. |
240 |
|
list.setConditions ([['eq', ''], ['field', 'gnue_id'], |
241 |
|
['const', object_id]]) |
242 |
|
list.populate () |
243 |
|
if object_id: |
244 |
|
object = list.firstInstance () |
245 |
|
result.append (object_id) |
246 |
|
else: |
247 |
|
object = list.insertNewInstance () |
248 |
|
object.put ("gnue_id", new_object_id ()) |
249 |
|
result.append (object.get ("gnue_id")) |
250 |
|
row = data [i] |
251 |
|
j = 0 |
252 |
|
for property in propertylist: |
253 |
|
object.put (property, row [j]) |
254 |
|
j += 1 |
255 |
|
i += 1 |
256 |
|
return result |
257 |
|
|
258 |
|
# --------------------------------------------------------------------------- |
259 |
|
# Delete business objects |
260 |
|
# --------------------------------------------------------------------------- |
261 |
|
|
262 |
|
def delete (self, classname, obj_id_list): |
263 |
|
for object_id in obj_id_list: |
264 |
|
# create a temporary geasList |
265 |
|
list = self.createList (classname) |
266 |
|
list.setPrefetch (["gnue_id"]) |
267 |
|
list.setSort (["gnue_id"]) |
268 |
|
list.setConditions ([['eq', ''], ['field', 'gnue_id'], |
269 |
|
['const', object_id]]) |
270 |
|
list.populate () |
271 |
|
object = list.firstInstance () |
272 |
|
object.delete () |
273 |
|
# FIXME: remove this instance from all lists of this session it was |
274 |
|
# a member of. |
275 |
|
|
276 |
|
# --------------------------------------------------------------------------- |
277 |
|
# Call a procedure of business objects |
278 |
|
# --------------------------------------------------------------------------- |
279 |
|
|
280 |
|
def call(self,classname,obj_id_list,methodname,parameters): |
281 |
|
# create a temporary geasList |
282 |
|
list = geasList.geasList (self, classname) |
283 |
|
list.setPrefetch (["gnue_id"] + propertylist) |
284 |
|
list.setSort (["gnue_id"]) |
285 |
|
# Accessing the database for every single object_id is not very elegant, |
286 |
|
# but for now it works. -- Reinhard |
287 |
|
result = [] |
288 |
|
for object_id in obj_id_list: |
289 |
|
list.setConditions ([['eq', ''], ['field', 'gnue_id'], |
290 |
|
['const', object_id]]) |
291 |
|
list.populate () |
292 |
|
object = list.firstInstance () |
293 |
|
result.append (object.call(methodname,parameters)) |
294 |
|
# FIXME: at the moment the method itself has to care for data which has to |
295 |
|
# be stored back into the database -- Siesel |
296 |
|
return result |
297 |
|
# FIXME: This function should be moved to the geasBClass object, once |
298 |
|
# it is working -- Siesel |
299 |
|
# return self._getClass(classname).call(obj_id_list,methodname,parameters) |
300 |
|
|