1105 return self._threaddata._rewriter |
1105 return self._threaddata._rewriter |
1106 except AttributeError: |
1106 except AttributeError: |
1107 self._threaddata._rewriter = RQLRewriter(self) |
1107 self._threaddata._rewriter = RQLRewriter(self) |
1108 return self._threaddata._rewriter |
1108 return self._threaddata._rewriter |
1109 |
1109 |
1110 def build_description(self, rqlst, args, result): |
|
1111 """build a description for a given result""" |
|
1112 if len(rqlst.children) == 1 and len(rqlst.children[0].solutions) == 1: |
|
1113 # easy, all lines are identical |
|
1114 selected = rqlst.children[0].selection |
|
1115 solution = rqlst.children[0].solutions[0] |
|
1116 description = _make_description(selected, args, solution) |
|
1117 return RepeatList(len(result), tuple(description)) |
|
1118 # hard, delegate the work :o) |
|
1119 return self.manual_build_descr(rqlst, args, result) |
|
1120 |
|
1121 def manual_build_descr(self, rqlst, args, result): |
|
1122 """build a description for a given result by analysing each row |
|
1123 |
|
1124 XXX could probably be done more efficiently during execution of query |
|
1125 """ |
|
1126 # not so easy, looks for variable which changes from one solution |
|
1127 # to another |
|
1128 unstables = rqlst.get_variable_indices() |
|
1129 basedescr = [] |
|
1130 todetermine = [] |
|
1131 for i in xrange(len(rqlst.children[0].selection)): |
|
1132 ttype = selection_idx_type(i, rqlst, args) |
|
1133 if ttype is None or ttype == 'Any': |
|
1134 ttype = None |
|
1135 isfinal = True |
|
1136 else: |
|
1137 isfinal = ttype in BASE_TYPES |
|
1138 if ttype is None or i in unstables: |
|
1139 basedescr.append(None) |
|
1140 todetermine.append( (i, isfinal) ) |
|
1141 else: |
|
1142 basedescr.append(ttype) |
|
1143 if not todetermine: |
|
1144 return RepeatList(len(result), tuple(basedescr)) |
|
1145 return self._build_descr(result, basedescr, todetermine) |
|
1146 |
|
1147 def _build_descr(self, result, basedescription, todetermine): |
|
1148 description = [] |
|
1149 etype_from_eid = self.describe |
|
1150 todel = [] |
|
1151 for i, row in enumerate(result): |
|
1152 row_descr = basedescription[:] |
|
1153 for index, isfinal in todetermine: |
|
1154 value = row[index] |
|
1155 if value is None: |
|
1156 # None value inserted by an outer join, no type |
|
1157 row_descr[index] = None |
|
1158 continue |
|
1159 if isfinal: |
|
1160 row_descr[index] = etype_from_pyobj(value) |
|
1161 else: |
|
1162 try: |
|
1163 row_descr[index] = etype_from_eid(value)[0] |
|
1164 except UnknownEid: |
|
1165 self.error('wrong eid %s in repository, you should ' |
|
1166 'db-check the database' % value) |
|
1167 todel.append(i) |
|
1168 break |
|
1169 else: |
|
1170 description.append(tuple(row_descr)) |
|
1171 for i in reversed(todel): |
|
1172 del result[i] |
|
1173 return description |
|
1174 |
|
1175 # deprecated ############################################################### |
1110 # deprecated ############################################################### |
1176 |
1111 |
1177 @deprecated('[3.13] use getattr(session.rtype_eids_rdef(rtype, eidfrom, eidto), prop)') |
1112 @deprecated('[3.13] use getattr(session.rtype_eids_rdef(rtype, eidfrom, eidto), prop)') |
1178 def schema_rproperty(self, rtype, eidfrom, eidto, rprop): |
1113 def schema_rproperty(self, rtype, eidfrom, eidto, rprop): |
1179 return getattr(self.rtype_eids_rdef(rtype, eidfrom, eidto), rprop) |
1114 return getattr(self.rtype_eids_rdef(rtype, eidfrom, eidto), rprop) |