1 # -----------------------------------------------------------------------
2 # Copyright (C) 2007 Georgia Public Library Service
3 # Bill Erickson <billserickson@gmail.com>
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 # -----------------------------------------------------------------------
16 from osrf.log import *
17 from osrf.json import *
18 from oils.utils.idl import oilsGetIDLParser
19 from osrf.ses import ClientSession
20 from oils.const import *
23 ACTIONS = ['create', 'retrieve', 'batch_retrieve', 'update', 'delete', 'search']
25 class CSEditor(object):
27 Contains generated methods for accessing fieldmapper objects using the
30 <instance>.<action>_<schema>_<table>(<id>)
32 * <instance> = CSEditor class instance
33 * <action> = one of 'create', 'retrieve', 'batch_retrieve', 'update',
35 * <schema> = the name of the schema that contains the table
36 * <table> = the name of the table
38 Each generated object has accessor methods corresponding to the fieldmapper
39 name attributes for a given field. The following example demonstrates how to
40 instantiate the CSEditor and a given table object, and how to invoke an
41 accessor method on that table object:
43 >>> import oils.utils.csedit
44 >>> import oils.utils.idl
45 >>> import osrf.system
46 >>> osrf.system.connect('/openils/conf/opensrf_core.xml', 'config.opensrf')
47 >>> oils.utils.idl.oilsParseIDL()
48 >>> oils.utils.csedit.oilsLoadCSEditor()
49 >>> editor = oils.utils.csedit.CSEditor()
50 >>> rec = editor.retrieve_biblio_record_entry(-1)
51 >>> print rec.tcn_value()
53 def __init__(self, **args):
55 self.app = args.get('app', OILS_APP_CSTORE)
56 self.authtoken = args.get('authtoken', args.get('auth'))
57 self.requestor = args.get('requestor')
58 self.connect = args.get('connect')
59 self.xact = args.get('xact')
68 # -------------------------------------------------------------------------
69 # Creates a session if one does not already exist. If necessary, connects
70 # to the remote service and starts a transaction
71 # -------------------------------------------------------------------------
72 def session(self, ses=None):
73 if not self.__session:
74 self.__session = ClientSession(self.app)
76 if self.connect or self.xact:
77 self.log(log_debug,'connecting to ' + self.app)
78 self.__session.connect()
81 self.log(log_info, "starting new db transaction")
82 self.request(self.app + '.transaction.begin')
87 # -------------------------------------------------------------------------
88 # Logs string with some meta info
89 # -------------------------------------------------------------------------
90 def log(self, func, string):
92 if self.xact: s += "1|"
94 if self.requestor: s += str(self.requestor.id())
97 func("%s %s" % (s, string))
100 # -------------------------------------------------------------------------
101 # Rolls back the existing db transaction
102 # -------------------------------------------------------------------------
104 if self.__session and self.xact:
105 self.log(log_info, "rolling back db transaction")
106 self.request(self.app + '.transaction.rollback')
109 # -------------------------------------------------------------------------
110 # Commits the existing db transaction
111 # -------------------------------------------------------------------------
113 if self.__session and self.xact:
114 self.log(log_info, "comitting db transaction")
115 self.request(self.app + '.transaction.commit')
119 # -------------------------------------------------------------------------
120 # Disconnects from the remote service
121 # -------------------------------------------------------------------------
122 def disconnect(self):
124 self.__session.disconnect()
125 self.__session = None
128 # -------------------------------------------------------------------------
130 # -------------------------------------------------------------------------
131 def request(self, method, params=[]):
133 # XXX improve param logging here
135 self.log(log_info, "request %s %s" % (method, unicode(params)))
137 if self.xact and self.session().state != OSRF_APP_SESSION_CONNECTED:
138 self.log(log_error, "csedit lost its connection!")
143 req = self.session().request2(method, params)
148 self.log(log_error, "request error: %s" % unicode(e))
154 # -------------------------------------------------------------------------
155 # Returns true if our requestor is allowed to perform the request action
156 # 'org' defaults to the requestors ws_ou
157 # -------------------------------------------------------------------------
158 def allowed(self, perm, org=None):
162 def runMethod(self, action, type, arg, options={}):
164 method = "%s.direct.%s.%s" % (self.app, type, action)
166 if options.get('idlist'):
167 method = method.replace('search', 'id_list')
168 del options['idlist']
170 if action == 'search':
173 if action == 'batch_retrieve':
174 method = method.replace('batch_retrieve', 'search')
179 if len(options.keys()):
180 params.append(options)
182 val = self.request( method, params )
186 def rawSearch(self, args):
187 method = "%s.json_query.atomic" % self.app
188 self.log(log_debug, "rawSearch args: %s" % unicode(args))
189 return self.request(method, [args])
191 def rawSearch2(self, hint, fields, where, from_=None):
193 from_ = {'%s' % hint : {}}
196 'select' : { '%s' % hint : fields },
198 'where' : { "+%s" % hint : where }
200 return self.rawSearch(args)
203 def fieldSearch(self, hint, fields, where):
204 return self.rawSearch2(hint, fields, where)
208 # -------------------------------------------------------------------------
209 # Creates a class method for each action on each type of fieldmapper object
210 # -------------------------------------------------------------------------
211 def oilsLoadCSEditor():
212 obj = oilsGetIDLParser().IDLObject
214 for k, fm in obj.iteritems():
215 for action in ACTIONS:
217 fmname = fm['fieldmapper'].replace('::', '_')
218 type = fm['fieldmapper'].replace('::', '.')
219 name = "%s_%s" % (action, fmname)
221 s = 'def %s(self, arg, **options):\n' % name
222 s += '\treturn self.runMethod("%s", "%s", arg, dict(options))\n' % (action, type)
223 s += 'setattr(CSEditor, "%s", %s)' % (name, name)