584 self.set_schema(schema) |
584 self.set_schema(schema) |
585 |
585 |
586 def set_schema(self, schema): |
586 def set_schema(self, schema): |
587 self.schema = schema |
587 self.schema = schema |
588 repo = self._repo |
588 repo = self._repo |
589 # rql st and solution cache. Don't bother using a Cache instance: we |
589 # rql st and solution cache. |
590 # should have a limited number of queries in there, since there are no |
590 self._rql_cache = Cache(repo.config['rql-cache-size']) |
591 # entries in this cache for user queries (which have no args) |
591 # rql cache key cache. Don't bother using a Cache instance: we should |
592 self._rql_cache = {} |
592 # have a limited number of queries in there, since there are no entries |
593 # rql cache key cache |
593 # in this cache for user queries (which have no args) |
594 self._rql_ck_cache = Cache(repo.config['rql-cache-size']) |
594 self._rql_ck_cache = {} |
595 # some cache usage stats |
595 # some cache usage stats |
596 self.cache_hit, self.cache_miss = 0, 0 |
596 self.cache_hit, self.cache_miss = 0, 0 |
597 # rql parsing / analysing helper |
597 # rql parsing / analysing helper |
598 self.solutions = repo.vreg.solutions |
598 self.solutions = repo.vreg.solutions |
599 rqlhelper = repo.vreg.rqlhelper |
599 rqlhelper = repo.vreg.rqlhelper |
654 if server.DEBUG & (server.DBG_RQL | server.DBG_SQL): |
654 if server.DEBUG & (server.DBG_RQL | server.DBG_SQL): |
655 if server.DEBUG & (server.DBG_MORE | server.DBG_SQL): |
655 if server.DEBUG & (server.DBG_MORE | server.DBG_SQL): |
656 print '*'*80 |
656 print '*'*80 |
657 print 'querier input', rql, args |
657 print 'querier input', rql, args |
658 # parse the query and binds variables |
658 # parse the query and binds variables |
|
659 cachekey = rql |
659 try: |
660 try: |
660 cachekey = rql |
|
661 if args: |
661 if args: |
|
662 # search for named args in query which are eids (hence |
|
663 # influencing query's solutions) |
662 eidkeys = self._rql_ck_cache[rql] |
664 eidkeys = self._rql_ck_cache[rql] |
663 if eidkeys: |
665 if eidkeys: |
|
666 # if there are some, we need a better cache key, eg (rql + |
|
667 # entity type of each eid) |
664 try: |
668 try: |
665 cachekey = self._repo.querier_cache_key(session, rql, |
669 cachekey = self._repo.querier_cache_key(session, rql, |
666 args, eidkeys) |
670 args, eidkeys) |
667 except UnknownEid: |
671 except UnknownEid: |
668 # we want queries such as "Any X WHERE X eid 9999" |
672 # we want queries such as "Any X WHERE X eid 9999" |
672 self.cache_hit += 1 |
676 self.cache_hit += 1 |
673 except KeyError: |
677 except KeyError: |
674 self.cache_miss += 1 |
678 self.cache_miss += 1 |
675 rqlst = self.parse(rql) |
679 rqlst = self.parse(rql) |
676 try: |
680 try: |
|
681 # compute solutions for rqlst and return named args in query |
|
682 # which are eids. Notice that if you may not need `eidkeys`, we |
|
683 # have to compute solutions anyway (kept as annotation on the |
|
684 # tree) |
677 eidkeys = self.solutions(session, rqlst, args) |
685 eidkeys = self.solutions(session, rqlst, args) |
678 except UnknownEid: |
686 except UnknownEid: |
679 # we want queries such as "Any X WHERE X eid 9999" return an |
687 # we want queries such as "Any X WHERE X eid 9999" return an |
680 # empty result instead of raising UnknownEid |
688 # empty result instead of raising UnknownEid |
681 return empty_rset(rql, args, rqlst) |
689 return empty_rset(rql, args, rqlst) |
682 self._rql_ck_cache[rql] = eidkeys |
690 if args and not rql in self._rql_ck_cache: |
683 if eidkeys: |
691 self._rql_ck_cache[rql] = eidkeys |
684 cachekey = self._repo.querier_cache_key(session, rql, args, |
692 if eidkeys: |
685 eidkeys) |
693 cachekey = self._repo.querier_cache_key(session, rql, args, |
|
694 eidkeys) |
686 self._rql_cache[cachekey] = rqlst |
695 self._rql_cache[cachekey] = rqlst |
687 orig_rqlst = rqlst |
696 orig_rqlst = rqlst |
688 if rqlst.TYPE != 'select': |
697 if rqlst.TYPE != 'select': |
689 if session.read_security: |
698 if session.read_security: |
690 check_no_password_selected(rqlst) |
699 check_no_password_selected(rqlst) |