16 |
# write to the Free Software Foundation, Inc., 59 Temple Place |
# write to the Free Software Foundation, Inc., 59 Temple Place |
17 |
# - Suite 330, Boston, MA 02111-1307, USA. |
# - Suite 330, Boston, MA 02111-1307, USA. |
18 |
# |
# |
19 |
# Copyright 2002 Free Software Foundation |
# Copyright 2002-2003 Free Software Foundation |
20 |
# |
# |
21 |
# FILE: |
# FILE: |
22 |
# GIObjects.py |
# GIObjects.py |
27 |
# NOTES: |
# NOTES: |
28 |
# |
# |
29 |
|
|
30 |
import sys, string, os, os.path |
import sys, string, os, os.path, re |
31 |
from gnue.common import GObjects, GDebug, GConfig, GRootObj |
from gnue.common import GObjects, GDebug, GConfig, GDataSource |
32 |
|
from gnue.common.GRootObj import GRootObj |
33 |
from gnue.reports import GREngine,GRExceptions |
from gnue.reports import GREngine,GRExceptions |
34 |
import GIParser |
import GIParser |
35 |
|
from gnue.common.GTrigger import GTriggerExtension |
36 |
|
|
37 |
# Base class for all Navigator objects |
# Base class for all Integrator objects |
38 |
class GIObject(GObjects.GObj): |
class GIObject(GObjects.GObj): |
39 |
pass |
pass |
40 |
|
|
41 |
|
|
42 |
class GIMappings(GRootObj, GIObject): |
class GIMappings(GRootObj,GIObject,GTriggerExtension): |
|
|
|
43 |
def __init__(self, parent=None): |
def __init__(self, parent=None): |
44 |
GRootObj.GRootObj.__init__(self, 'mappings', GIParser.getXMLelements,GIParser) |
GTriggerExtension.__init__(self) |
45 |
GNObject.__init__(self, parent, type="GIMappings") |
GRootObj.__init__(self, 'mappings', GIParser.getXMLelements,GIParser) |
46 |
|
GIObject.__init__(self, parent, type="GIMappings") |
47 |
|
self._datasourceDictionary={} |
48 |
|
self._inits = (None,self.initialize) |
49 |
|
|
50 |
|
self.name="" |
51 |
|
# |
52 |
|
# New trigger support |
53 |
|
# |
54 |
|
self._triggerDictionary = {} |
55 |
|
self._triggerns={} |
56 |
|
|
57 |
|
self._validTriggers = { 'ON-STARTUP': 'On-Startup', |
58 |
|
'ON-EXIT': 'On-Exit' } |
59 |
|
|
60 |
|
#self._triggerGlobal = 1 |
61 |
|
self._triggerFunctions = {} |
62 |
|
|
63 |
|
def initialize(self): |
64 |
|
self.initTriggerSystem() |
65 |
|
self._triggerns.update(self._triggerNamespaceTree._globalNamespace) |
66 |
|
|
67 |
|
|
68 |
|
|
69 |
|
def run(self): |
70 |
|
self.processTrigger('On-Startup') |
71 |
|
|
72 |
|
for child in self._children: |
73 |
|
if child._type=="GIMapping": |
74 |
|
child.run() |
75 |
|
|
76 |
|
self.processTrigger('On-Exit') |
77 |
|
|
78 |
|
|
79 |
|
class GIMapping(GIObject,GTriggerExtension): |
80 |
|
def __init__(self, parent): |
81 |
|
GTriggerExtension.__init__(self) |
82 |
|
GIObject.__init__(self, parent, type="GIMapping") |
83 |
|
self._inits = [self.initialize] |
84 |
|
self._validTriggers = {'POST-ROW':'Post-Row', |
85 |
|
'PRE-ROW':'Pre-Row', |
86 |
|
'POST-PROCESS':'Post-Process', |
87 |
|
'PRE-PROCESS':'Pre-Process'} |
88 |
|
|
89 |
|
self._triggerDictionary = {} |
90 |
|
self._triggerns={} |
91 |
|
|
92 |
|
# |
93 |
|
# temporariy hack: remove this functions if trigger namespace is |
94 |
|
# populated correctly |
95 |
|
# self._triggerGlobal = 1 |
96 |
|
self._triggerFunctions={'setField':{'function':self.triggerSetValue, |
97 |
|
'global':1}, |
98 |
|
'getField':{'function':self.triggerGetValue, |
99 |
|
'global':1} |
100 |
|
} |
101 |
|
|
102 |
|
def triggerSetValue(self,field,value): |
103 |
|
if not hasattr(self._parent,'_testonly'): |
104 |
|
self._outputRset.current.setField(field,value) |
105 |
|
|
106 |
|
def triggerGetValue(self,field): |
107 |
|
return self._inputRset.current.getField(field) |
108 |
|
|
109 |
|
# end hack |
110 |
|
|
111 |
|
def initialize(self): |
112 |
|
self._sourceFields=[] |
113 |
|
self._destinationFields=[] |
114 |
|
self._inputSource = \ |
115 |
|
self._parent._datasourceDictionary[string.lower(self.source)] |
116 |
|
self._outputSource = \ |
117 |
|
self._parent._datasourceDictionary[string.lower(self.destination)] |
118 |
|
|
119 |
|
|
120 |
|
def addSourceField(self,name): |
121 |
|
self._sourceFields.append(name) |
122 |
|
self._inputSource.referenceField(name, None) |
123 |
|
|
124 |
|
def addDestinationField(self,name): |
125 |
|
self._destinationFields.append(name) |
126 |
|
self._outputSource.referenceField(name, None) |
127 |
|
|
128 |
|
|
129 |
|
def run(self): |
130 |
|
GDebug.printMesg(5,"Start Mapping %s." % self.name) |
131 |
|
|
132 |
|
# Prepare Input datasource |
133 |
|
if self._inputSource.hasMaster(): |
134 |
|
raise Exception,'InputSources in a Mapping should not have a master' |
135 |
|
print "HALLO" |
136 |
|
self._inputRset=self._inputSource.createResultSet({}) |
137 |
|
|
138 |
|
# Prepare Output datasource |
139 |
|
if self._outputSource.hasMaster(): |
140 |
|
raise Exception,'OutputSources in a Mapping should not have a master' |
141 |
|
|
142 |
|
if not self.append: |
143 |
|
GDebug.printMesg(5,"Append not set: All records in Source %s will be " \ |
144 |
|
% self.destination + 'removed !!!') |
145 |
|
# TODO: add code to remove records |
146 |
|
# like self._outputSource.sql('delete from %s;' % tablename) |
147 |
|
|
148 |
|
|
149 |
|
self._outputRset=self._outputSource.createResultSet() |
150 |
|
|
151 |
|
self.processTrigger('Pre-Process') |
152 |
|
|
153 |
|
record=self._inputRset.firstRecord() |
154 |
|
while record: |
155 |
|
|
156 |
|
if not hasattr(self._parent,'_testonly'): |
157 |
|
self._outputRset.insertRecord () |
158 |
|
|
159 |
|
output={} |
160 |
|
|
161 |
|
self.processTrigger('Pre-Row') |
162 |
|
|
163 |
|
for child in self._children: |
164 |
|
if child._type=="GIAction": |
165 |
|
|
166 |
|
out=child.process(self._inputRset.current) |
167 |
|
|
168 |
|
if out!=None: |
169 |
|
output.update(out) |
170 |
|
|
171 |
|
self.processTrigger('Post-Row') |
172 |
|
|
173 |
|
for field in output.keys(): |
174 |
|
# TODO: add some basic output field processing here |
175 |
|
|
176 |
|
if not hasattr(self._parent,'_testonly'): |
177 |
|
self._outputRset.current.setField(field,output[field]) |
178 |
|
|
179 |
|
|
180 |
|
if hasattr(self._parent,'_testonly'): |
181 |
|
print output |
182 |
|
|
183 |
|
record=self._inputRset.nextRecord() |
184 |
|
|
185 |
|
self.processTrigger('Post-Process') |
186 |
|
|
187 |
|
self._outputRset.post() |
188 |
|
self._outputSource.commit() |
189 |
|
|
190 |
|
# self._inputRset.close() |
191 |
|
# self._outputRset.close() |
192 |
|
|
193 |
|
# def run(self): |
194 |
|
# for child in self._children: |
195 |
|
# if child._type=="GIProcess": |
196 |
|
# child.run() |
197 |
|
|
198 |
|
class GISubMapping(GIObject): |
199 |
|
def __init__(self, parent): |
200 |
|
GIObject.__init__(self, parent, type="GISubMapping") |
201 |
|
|
202 |
|
class GISources(GIObject): |
203 |
|
def __init__(self, parent): |
204 |
|
GIObject.__init__(self, parent, type="GISources") |
205 |
|
|
206 |
|
class GIProcess(GIObject): |
207 |
|
def __init__(self, parent): |
208 |
|
GIObject.__init__(self, parent, type="GIProcess") |
209 |
|
self.inputSource=None |
210 |
|
self.outputSource=None |
211 |
|
self.InputRset={} |
212 |
|
self.OutputRset={} |
213 |
|
|
214 |
|
|
215 |
|
|
216 |
|
class GIAction(GIObject,GTriggerExtension): |
217 |
|
def __init__(self, parent): |
218 |
|
GTriggerExtension.__init__(self) |
219 |
|
GIObject.__init__(self, parent, type="GIAction") |
220 |
|
self._inits = [self.initialize] |
221 |
|
self._validTriggers = {'POST-ACTION':'Post-Action', |
222 |
|
'PRE-ACTION':'Pre-Action', |
223 |
|
'ON-FAIL':'On-Fail'} |
224 |
|
def initialize(self): |
225 |
|
inpCount=0 |
226 |
|
outCount=0 |
227 |
|
for child in self._children: |
228 |
|
if child.type=="src": |
229 |
|
inpCount+=1 |
230 |
|
if child.type=="dest": |
231 |
|
outCount+=1 |
232 |
|
|
233 |
|
if hasattr(self,"mergemask") and self.mergemask!="": |
234 |
|
# should use regex instead |
235 |
|
self.mergecount=string.count(self.mergemask,'@') |
236 |
|
if self.mergecount!=inpCount: |
237 |
|
raise Error,"Merge mask parameter not equal to number of fields" |
238 |
|
|
239 |
|
else: |
240 |
|
self.mergemask='@1' |
241 |
|
|
242 |
|
if hasattr(self,"splitmask") and self.splitmask!="": |
243 |
|
self.splitre=re.compile(self.splitmask) |
244 |
|
|
245 |
|
|
246 |
|
|
247 |
|
def process(self, row): |
248 |
|
self.processTrigger('Pre-Action') |
249 |
|
# merge first |
250 |
|
inpCount=1 |
251 |
|
out=self.mergemask |
252 |
|
for child in self._children: |
253 |
|
if child.type=="src": |
254 |
|
value=row.getField(child.name) |
255 |
|
if child.trim: |
256 |
|
value=string.strip(value) |
257 |
|
out=string.replace(out,'@%s' % inpCount, '%s' % value) |
258 |
|
inpCount+=1 |
259 |
|
# print row.getField(child.name),' ', |
260 |
|
|
261 |
|
if hasattr(self,"splitre"): |
262 |
|
mymatch=self.splitre.match(out) |
263 |
|
if mymatch==None: |
264 |
|
self.processTrigger('On-Fail') |
265 |
|
return |
266 |
|
|
267 |
|
out=mymatch.groups() |
268 |
|
else: |
269 |
|
out = [out] |
270 |
|
|
271 |
|
outpFields={} |
272 |
|
outpCount=1 |
273 |
|
for child in self._children: |
274 |
|
if child.type=="dest": |
275 |
|
outpFields[child.name]=out[outpCount-1] |
276 |
|
outpCount+=1 |
277 |
|
|
278 |
|
self.processTrigger('Post-Action') |
279 |
|
return outpFields |
280 |
|
|
281 |
|
|
282 |
|
|
283 |
|
class GIField(GIObject): |
284 |
|
def __init__(self, parent): |
285 |
|
GIObject.__init__(self, parent, type="GIField") |
286 |
|
self._inits = [self.initialize] |
287 |
|
|
288 |
|
def initialize(self): |
289 |
|
self._mappings = self.findParentOfType('GIMappings') |
290 |
|
self._mapping = self.findParentOfType('GIMapping') |
291 |
|
|
292 |
|
if self.type=="src": |
293 |
|
self._mapping.addSourceField(self.name) |
294 |
|
|
295 |
|
if self.type=="dest": |
296 |
|
self._mapping.addDestinationField(self.name) |
297 |
|
|
298 |
class GIMapping(GIObject): |
class GITrigger(GIObject): |
299 |
def __init__(self, parent): |
def __init__(self, parent): |
300 |
GNObject.__init__(self, parent, type="GIMapping") |
GIObject.__init__(self, parent, type="GITrigger") |
301 |
|
|
302 |
|
|
303 |
|
|