1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 """Proxies representing the results of a query"""
29
30 from PyQt4.QtCore import Qt
31
32 import logging
33 logger = logging.getLogger('camelot.view.proxy.queryproxy')
34
35 from collection_proxy import CollectionProxy
36 from collection_proxy import RowDataAsUnicode
37 from collection_proxy import RowDataFromObject
38 from camelot.view.model_thread import model_function
42 """The QueryTableProxy contains a limited copy of the data in the Elixir
43 model, which is fetched from the database to be used as the model for a
44 QTableView
45 """
46
47 - def __init__(self, admin, query_getter, columns_getter,
48 max_number_of_rows=10, edits=None):
49 """@param query_getter: a model_thread function that returns a query"""
50 logger.debug('initialize query table')
51 self._query_getter = query_getter
52
53
54 self._appended_rows = []
55 CollectionProxy.__init__(self, admin, lambda: [],
56 columns_getter, max_number_of_rows=10, edits=None)
57
58 @model_function
60 """Remove those rows from appended rows that have been flushed"""
61 flushed_rows = []
62 for o in self._appended_rows:
63 if o.id:
64 flushed_rows.append(o)
65 for o in flushed_rows:
66 self._appended_rows.remove(o)
67
68 @model_function
72
74 """Set the query and refresh the view"""
75 self._query_getter = query_getter
76 self.refresh()
77
79 """Add an object to this collection, used when inserting a new
80 row, overwrite this method for specific behaviour in subclasses"""
81 if not o.id:
82 self._appended_rows.append(o)
83 self.rows = self.rows + 1
84
86 if o in self._appended_rows:
87 self._appended_rows.remove(o)
88 self.rows = self.rows - 1
89
90 @model_function
92 """Generator for all the data queried by this proxy"""
93 for i,o in enumerate(self._query_getter().all()):
94 yield RowDataFromObject(o, self.getColumns())
95
96 @model_function
98 """Extend the cache around row"""
99 q = self._query_getter().offset(offset).limit(limit)
100 columns = self.getColumns()
101 for i, o in enumerate(q.all()):
102 row_data = RowDataFromObject(o, columns)
103 self.cache[Qt.EditRole].add_data(i+offset, o, row_data)
104 self.cache[Qt.DisplayRole].add_data(i+offset, o, RowDataAsUnicode(row_data))
105 rows_in_query = (self.rows - len(self._appended_rows))
106
107 if offset+limit>=rows_in_query:
108 for row in range(max(rows_in_query,offset), min(offset+limit, self.rows)):
109 o = self._get_object(row)
110 row_data = RowDataFromObject(o, columns)
111 self.cache[Qt.EditRole].add_data(row, o, row_data)
112 self.cache[Qt.DisplayRole].add_data(row, o, RowDataAsUnicode(row_data))
113 return (offset, limit)
114
115 @model_function
117 """Get the object corresponding to row"""
118 if self.rows > 0:
119 self._clean_appended_rows()
120 rows_in_query = (self.rows - len(self._appended_rows))
121 if row >= rows_in_query:
122 return self._appended_rows[row - rows_in_query]
123
124
125 try:
126 return self.cache[Qt.EditRole].get_entity_at_row(row)
127 except KeyError:
128 pass
129
130 res = self._query_getter().offset(row)
131 if isinstance(res, list):
132 res = res[0]
133 return res.limit(1).first()
134