Back to index

plone3  3.1.7
Public Member Functions | Public Attributes | Private Member Functions | Static Private Attributes
Archetypes.SQLMethod.SQLMethod Class Reference

List of all members.

Public Member Functions

def __init__
def edit
def advanced_edit
def __call__
def abort
def connectionIsValid
def connected

Public Attributes

 context
 id
 title
 connection_id
 arguments_src
 src
 template

Private Member Functions

def _cached_result
def _get_dbc

Static Private Attributes

 _arg = None
 _col = None

Detailed Description

Definition at line 27 of file SQLMethod.py.


Constructor & Destructor Documentation

def Archetypes.SQLMethod.SQLMethod.__init__ (   self,
  context 
)

Definition at line 32 of file SQLMethod.py.

00032 
00033     def __init__(self, context):
00034         self.context = context
00035         self.id = str(context.__class__.__name__)
00036         self.title = ''
00037         for k, v in _defaults.items():
00038             if not hasattr(context, k):
00039                 setattr(context, k, v)

Here is the caller graph for this function:


Member Function Documentation

def Archetypes.SQLMethod.SQLMethod.__call__ (   self,
  src__ = 0,
  test__ = 0,
  kw 
)
Call the database method

The arguments to the method should be passed via keyword
arguments, or in a single mapping object. If no arguments are
given, and if the method was invoked through the Web, then the
method will try to acquire and use the Web REQUEST object as
the argument mapping.

The returned value is a sequence of record objects.

Definition at line 169 of file SQLMethod.py.

00169 
00170     def __call__(self, src__=0, test__=0, **kw):
00171         """Call the database method
00172 
00173         The arguments to the method should be passed via keyword
00174         arguments, or in a single mapping object. If no arguments are
00175         given, and if the method was invoked through the Web, then the
00176         method will try to acquire and use the Web REQUEST object as
00177         the argument mapping.
00178 
00179         The returned value is a sequence of record objects.
00180         """
00181         context = self.context
00182 
00183         dbc, DB__ = self._get_dbc()
00184 
00185         p = None
00186 
00187         argdata = self._argdata(kw)
00188         argdata['sql_delimiter'] = '\0'
00189         argdata['sql_quote__'] = dbc.sql_quote__
00190 
00191         # TODO: Review the argdata dictonary. The line bellow is receiving unicode
00192         # strings, mixed with standard strings. It is insane! Archetypes needs a policy
00193         # about unicode, and lots of tests on this way. I prefer to not correct it now,
00194         # only doing another workarround. We need to correct the cause of this problem,
00195         # not its side effects :-(
00196 
00197         try:
00198             query = apply(self.template, (p,), argdata)
00199         except TypeError, msg:
00200             msg = str(msg)
00201             if 'client' in msg:
00202                 raise NameError("'client' may not be used as an " +
00203                                 "argument name in this context")
00204             else: raise
00205 
00206         __traceback_info__ = query
00207 
00208         if src__: return query
00209 
00210         # Get the encoding arguments
00211         # We have two possible kw arguments:
00212         #   db_encoding:        The encoding used in the external database
00213         #   site_encoding:      The uncoding used for the site
00214         #                       If not specified, we use sys.getdefaultencoding()
00215         db_encoding = kw.get('db_encoding',None)
00216 
00217         try:
00218             site_encoding = kw.get('site_encoding', context.portal_properties.site_properties.default_charset)
00219         except AttributeError, KeyError:
00220             site_encoding = kw.get('site_encoding',sys.getdefaultencoding())
00221 
00222         if type(query) == type(u''):
00223             if db_encoding:
00224                 query = query.encode(db_encoding)
00225             else:
00226                 try:
00227                     query = query.encode(site_encoding)
00228                 except UnicodeEncodeError:
00229                     query = query.encode('UTF-8')
00230 
00231 
00232         if context.cache_time_ > 0 and context.max_cache_ > 0:
00233             result = self._cached_result(DB__, (query, context.max_rows_))
00234         else:
00235             try:
00236                 result = DB__.query(query, context.max_rows_)
00237             except ConflictError:
00238                 raise
00239             except:
00240                 log_exc(msg='Database query failed', reraise=1)
00241 
00242         if hasattr(context, '_v_sql_brain'):
00243             brain = context._v_sql_brain
00244         else:
00245             brain=context._v_sql_brain = getBrain(context.class_file_,
00246                                                 context.class_name_)
00247 
00248         if type(result) is type(''):
00249             f = StringIO()
00250             f.write(result)
00251             f.seek(0)
00252             result = RDB.File(f, brain, p, None)
00253         else:
00254             if db_encoding:
00255                 # Encode result before we wrap it in Result object
00256                 # We will change the encoding from source to either the specified target_encoding
00257                 # or the site default encoding
00258 
00259                 # The data is a list of tuples of column data
00260                 encoded_result = []
00261                 for row in result[1]:
00262                     columns = ()
00263                     for col in row:
00264                         if isinstance(col, types.StringType):
00265                             # coerce column to unicode with database encoding
00266                             newcol = unicode(col,db_encoding)
00267                             # Encode column as string with site_encoding
00268                             newcol = newcol.encode(site_encoding)
00269                         else:
00270                             newcol = col
00271 
00272                         columns += newcol,
00273 
00274                     encoded_result.append(columns)
00275 
00276                 result = (result[0],encoded_result)
00277 
00278             result = Results(result, brain, p, None)
00279 
00280         columns = result._searchable_result_columns()
00281 
00282         if test__ and columns != self._col:
00283             self._col=columns
00284 
00285         # If run in test mode, return both the query and results so
00286         # that the template doesn't have to be rendered twice!
00287         if test__: return query, result
00288 
00289         return result

Here is the call graph for this function:

Here is the caller graph for this function:

def Archetypes.SQLMethod.SQLMethod._cached_result (   self,
  DB__,
  query 
) [private]

Definition at line 115 of file SQLMethod.py.

00115 
00116     def _cached_result(self, DB__, query):
00117         context = self.context
00118         # Try to fetch from cache
00119         if hasattr(context,'_v_sql_cache'):
00120             cache = context._v_sql_cache
00121         else:
00122             cache = context._v_sql_cache={}, Bucket()
00123         cache, tcache = cache
00124         max_cache = context.max_cache_
00125         now = time()
00126         t = now - context.cache_time_
00127         if len(cache) > max_cache / 2:
00128             keys = tcache.keys()
00129             keys.reverse()
00130             while keys and (len(keys) > max_cache or keys[-1] < t):
00131                 key = keys[-1]
00132                 q = tcache[key]
00133                 del tcache[key]
00134                 if int(cache[q][0]) == key:
00135                     del cache[q]
00136                 del keys[-1]
00137 
00138         if cache.has_key(query):
00139             k, r = cache[query]
00140             if k > t: return r
00141 
00142         result = apply(DB__.query, query)
00143         if context.cache_time_ > 0:
00144             tcache[int(now)] = query
00145             cache[query] = now, result
00146 
00147         return result

Here is the caller graph for this function:

def Archetypes.SQLMethod.SQLMethod._get_dbc (   self) [private]
Get the database connection

Definition at line 148 of file SQLMethod.py.

00148 
00149     def _get_dbc(self):
00150         """Get the database connection"""
00151         context = self.context
00152 
00153         try:
00154             dbc = getattr(context, self.connection_id)
00155         except AttributeError:
00156             raise AttributeError, (
00157                 "The database connection <em>%s</em> cannot be found." % (
00158                 self.connection_id))
00159 
00160         try:
00161             DB__ = dbc()
00162         except ConflictError:
00163             raise
00164         except:
00165             raise 'Database Error', (
00166             '%s is not connected to a database' % self.id)
00167 
00168         return dbc, DB__

Here is the caller graph for this function:

Definition at line 290 of file SQLMethod.py.

00290 
00291     def abort(self):
00292         dbc, DB__ = self._get_dbc()
00293         try:
00294             DB__.tpc_abort()
00295         except ConflictError:
00296             raise
00297         except:
00298             log_exc(msg = 'Database abort failed')

Here is the call graph for this function:

def Archetypes.SQLMethod.SQLMethod.advanced_edit (   self,
  max_rows = 1000,
  max_cache = 100,
  cache_time = 0,
  class_name = '',
  class_file = '',
  REQUEST = None 
)
Change advanced properties

The arguments are:

max_rows -- The maximum number of rows to be returned from a query.

max_cache -- The maximum number of results to cache

cache_time -- The maximum amound of time to use a cached result.

class_name -- The name of a class that provides additional
  attributes for result record objects. This class will be a
  base class of the result record class.

class_file -- The name of the file containing the class
  definition.

The class file normally resides in the 'Extensions'
directory, however, the file name may have a prefix of
'product.', indicating that it should be found in a product
directory.

For example, if the class file is: 'ACMEWidgets.foo', then an
attempt will first be made to use the file
'lib/python/Products/ACMEWidgets/Extensions/foo.py'. If this
failes, then the file 'Extensions/ACMEWidgets.foo.py' will be
used.

Definition at line 67 of file SQLMethod.py.

00067 
00068                         REQUEST=None):
00069         """Change advanced properties
00070 
00071         The arguments are:
00072 
00073         max_rows -- The maximum number of rows to be returned from a query.
00074 
00075         max_cache -- The maximum number of results to cache
00076 
00077         cache_time -- The maximum amound of time to use a cached result.
00078 
00079         class_name -- The name of a class that provides additional
00080           attributes for result record objects. This class will be a
00081           base class of the result record class.
00082 
00083         class_file -- The name of the file containing the class
00084           definition.
00085 
00086         The class file normally resides in the 'Extensions'
00087         directory, however, the file name may have a prefix of
00088         'product.', indicating that it should be found in a product
00089         directory.
00090 
00091         For example, if the class file is: 'ACMEWidgets.foo', then an
00092         attempt will first be made to use the file
00093         'lib/python/Products/ACMEWidgets/Extensions/foo.py'. If this
00094         failes, then the file 'Extensions/ACMEWidgets.foo.py' will be
00095         used.
00096 
00097         """
00098         context = self.context
00099         # paranoid type checking
00100         if type(max_rows) is not type(1):
00101             max_rows = atoi(max_rows)
00102         if type(max_cache) is not type(1):
00103             max_cache = atoi(max_cache)
00104         if type(cache_time) is not type(1):
00105             cache_time = atoi(cache_time)
00106         class_name = str(class_name)
00107         class_file = str(class_file)
00108 
00109         context.max_rows_ = max_rows
00110         context.max_cache_, context.cache_time_ = max_cache, cache_time
00111         context._v_sql_cache = {}, Bucket()
00112         context.class_name_, context.class_file_ = class_name, class_file
00113         context._v_sql_brain = getBrain(context.class_file_,
00114                                         context.class_name_, 1)

Definition at line 304 of file SQLMethod.py.

00304 
00305     def connected(self):
00306         context = self.context
00307         return getattr(getattr(context, self.connection_id), 'connected')()

Definition at line 299 of file SQLMethod.py.

00299 
00300     def connectionIsValid(self):
00301         context = self.context
00302         return (hasattr(context, self.connection_id) and
00303                 hasattr(getattr(context, self.connection_id), 'connected'))

def Archetypes.SQLMethod.SQLMethod.edit (   self,
  connection_id,
  arguments,
  template 
)
Change database method  properties

The 'connection_id' argument is the id of a database connection
that resides in the current folder or in a folder above the
current folder.  The database should understand SQL.

The 'arguments' argument is a string containing an arguments
specification, as would be given in the SQL method cration form.

The 'template' argument is a string containing the source for the
SQL Template.

Definition at line 40 of file SQLMethod.py.

00040 
00041     def edit(self, connection_id, arguments, template):
00042         """Change database method  properties
00043 
00044         The 'connection_id' argument is the id of a database connection
00045         that resides in the current folder or in a folder above the
00046         current folder.  The database should understand SQL.
00047 
00048         The 'arguments' argument is a string containing an arguments
00049         specification, as would be given in the SQL method cration form.
00050 
00051         The 'template' argument is a string containing the source for the
00052         SQL Template.
00053         """
00054         context = self.context
00055         self.connection_id = str(connection_id)
00056         arguments = str(arguments)
00057         self.arguments_src = arguments
00058         self._arg = Aqueduct.parse(arguments)
00059         if not isinstance(template, (str, unicode)):
00060             template = str(template)
00061         self.src = template
00062         self.template = t = context.template_class(template)
00063         t.cook()
00064         context._v_query_cache={}, Bucket()

Here is the caller graph for this function:


Member Data Documentation

Archetypes.SQLMethod.SQLMethod._arg = None [static, private]

Definition at line 29 of file SQLMethod.py.

Archetypes.SQLMethod.SQLMethod._col = None [static, private]

Definition at line 30 of file SQLMethod.py.

Definition at line 56 of file SQLMethod.py.

Definition at line 54 of file SQLMethod.py.

Definition at line 33 of file SQLMethod.py.

Definition at line 34 of file SQLMethod.py.

Definition at line 60 of file SQLMethod.py.

Definition at line 61 of file SQLMethod.py.

Definition at line 35 of file SQLMethod.py.


The documentation for this class was generated from the following file: