Beispiel #1
0
    def setUp(self):
        # These defaults only make sense if the default encoding
        # prevents s from being promoted to Unicode.
        self.assertRaises(UnicodeError, unicode, self.s)

        # An object needs to be added to the database to
        self.db = DB(MappingStorage())
        root = self.db.open().root()
        self.bucket = root["bucket"] = Bucket()
        self.set = root["set"] = Set()
        transaction.commit()
Beispiel #2
0
 def PUT(self, REQUEST, RESPONSE):
     """Handle put requests"""
     self.dav__init(REQUEST, RESPONSE)
     self.dav__simpleifhandler(REQUEST, RESPONSE, refresh=1)
     body = REQUEST.get('BODY', '')
     m = re.match(r'\s*<params>(.*)</params>\s*\n', body, re.I | re.S)
     if m:
         self.arguments_src = m.group(1)
         self._arg = parse(self.arguments_src)
         body = body[m.end():]
     template = body
     self.src = template
     self.template = t = self.template_class(template)
     t.cook()
     self._v_cache = ({}, Bucket())
     RESPONSE.setStatus(204)
     return RESPONSE
Beispiel #3
0
    def manage_edit(self,
                    title,
                    connection_id,
                    arguments,
                    template,
                    SUBMIT='Change',
                    dtpref_cols='100%',
                    dtpref_rows='20',
                    REQUEST=None):
        """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.
        """

        if SUBMIT in self._size_changes:
            return self._er(title, connection_id, arguments, template, SUBMIT,
                            dtpref_cols, dtpref_rows, REQUEST)

        if self.wl_isLocked():
            raise ResourceLockedError('SQL Method is locked via WebDAV')

        self.title = str(title)
        self.connection_id = str(connection_id)
        arguments = str(arguments)
        self.arguments_src = arguments
        self._arg = parse(arguments)
        template = str(template)
        self.src = template
        self.template = t = self.template_class(template)
        t.cook()
        self._v_cache = ({}, Bucket())
        if REQUEST:
            if SUBMIT == 'Change and Test':
                return self.manage_testForm(REQUEST)
            message = 'ZSQL Method content changed'
            return self.manage_main(self, REQUEST, manage_tabs_message=message)
        return ''
Beispiel #4
0
    def _cached_result(self, DB__, query, max_rows, conn_id):
        # Try to fetch a result from the cache.
        # Compute and cache the result otherwise.
        # Also maintains the cache and ensures stale entries
        # are never returned and that the cache never gets too large.

        # NB: Correct cache behavior is predicated on Bucket.keys()
        #     returning a sequence ordered from smalled number
        #     (ie: the oldest cache entry) to largest number
        #     (ie: the newest cache entry). Please be careful if you
        #     change the class instantied below!

        # get hold of a cache
        caches = getattr(self, '_v_cache', None)
        if caches is None:
            caches = self._v_cache = {}, Bucket()
        cache, tcache = caches

        # the key for caching
        cache_key = query, max_rows, conn_id
        # the maximum number of result sets to cache
        max_cache = self.max_cache_
        # the current time
        now = time()
        # the oldest time which is not stale
        t = now - self.cache_time_

        # if the cache is too big, we purge entries from it
        if len(cache) >= max_cache:
            keys = tcache.keys()
            # We also hoover out any stale entries, as we're
            # already doing cache minimisation.
            # 'keys' is ordered, so we purge the oldest results
            # until the cache is small enough and there are no
            # stale entries in it
            while keys and (len(keys) >= max_cache or keys[0] < t):
                key = keys[0]
                q = tcache[key]
                del tcache[key]
                del cache[q]
                del keys[0]

        # okay, now see if we have a cached result
        if cache_key in cache:
            k, r = cache[cache_key]
            # the result may still be stale, as we only hoover out
            # stale results above if the cache gets too large.
            if k > t:
                # yay! a cached result returned!
                return r
            else:
                # delete stale cache entries
                del cache[cache_key]
                try:
                    del tcache[k]
                except KeyError:
                    # If there were two querys at the same timestamp, the
                    # entry in `tcache` might have been already deleted when
                    # purging the other query, so do not complain:
                    pass

        # call the pure query
        result = DB__.query(query, max_rows)

        # When a ZSQL method is handled by one ZPublisher thread twice in
        # less time than it takes for time.time() to return a different
        # value, the SQL generated is different, then this code will leak
        # an entry in 'cache' for each time the ZSQL method generates
        # different SQL until time.time() returns a different value.
        #
        # On Linux, you would need an extremely fast machine under extremely
        # high load, making this extremely unlikely. On Windows, this is a
        # little more likely, but still unlikely to be a problem.
        #
        # If it does become a problem, the values of the tcache mapping
        # need to be turned into sets of cache keys rather than a single
        # cache key.
        tcache[now] = cache_key
        cache[cache_key] = now, result

        return result
Beispiel #5
0
    def manage_advanced(self,
                        max_rows,
                        max_cache,
                        cache_time,
                        class_name,
                        class_file,
                        direct=None,
                        REQUEST=None,
                        connection_hook=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.

        """
        # paranoid type checking
        if not isinstance(max_rows, int):
            max_rows = int(max_rows)
        if not isinstance(max_cache, int):
            max_cache = int(max_cache)
        if not isinstance(cache_time, int):
            cache_time = int(cache_time)
        class_name = str(class_name)
        class_file = str(class_file)

        self.max_rows_ = max_rows
        self.max_cache_, self.cache_time_ = max_cache, cache_time
        self._v_cache = {}, Bucket()
        self.class_name_, self.class_file_ = class_name, class_file
        self._v_brain = getBrain(self.class_file_, self.class_name_, 1)
        self.allow_simple_one_argument_traversal = direct

        self.connection_hook = connection_hook

        if REQUEST is not None:
            m = 'ZSQL Method advanced settings have been set'
            return self.manage_advancedForm(self,
                                            REQUEST,
                                            manage_tabs_message=m)