Package camelot :: Package camelot :: Package view :: Package proxy :: Module queryproxy
[hide private]
[frames] | no frames]

Source Code for Module camelot.camelot.view.proxy.queryproxy

  1  #  ============================================================================ 
  2  # 
  3  #  Copyright (C) 2007-2008 Conceptive Engineering bvba. All rights reserved. 
  4  #  www.conceptive.be / project-camelot@conceptive.be 
  5  # 
  6  #  This file is part of the Camelot Library. 
  7  # 
  8  #  This file may be used under the terms of the GNU General Public 
  9  #  License version 2.0 as published by the Free Software Foundation 
 10  #  and appearing in the file LICENSE.GPL included in the packaging of 
 11  #  this file.  Please review the following information to ensure GNU 
 12  #  General Public Licensing requirements will be met: 
 13  #  http://www.trolltech.com/products/qt/opensource.html 
 14  # 
 15  #  If you are unsure which license is appropriate for your use, please 
 16  #  review the following information: 
 17  #  http://www.trolltech.com/products/qt/licensing.html or contact 
 18  #  project-camelot@conceptive.be. 
 19  # 
 20  #  This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 
 21  #  WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 
 22  # 
 23  #  For use of this library in commercial applications, please contact 
 24  #  project-camelot@conceptive.be 
 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 
39 40 41 -class QueryTableProxy(CollectionProxy):
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 #rows appended to the table which have not yet been flushed to the 53 #database, and as such cannot be a result of the query 54 self._appended_rows = [] 55 CollectionProxy.__init__(self, admin, lambda: [], 56 columns_getter, max_number_of_rows=10, edits=None)
57 58 @model_function
59 - def _clean_appended_rows(self):
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
69 - def getRowCount(self):
70 self._clean_appended_rows() 71 return self._query_getter().count() + len(self._appended_rows)
72
73 - def setQuery(self, query_getter):
74 """Set the query and refresh the view""" 75 self._query_getter = query_getter 76 self.refresh()
77
78 - def append(self, o):
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
85 - def remove(self, o):
86 if o in self._appended_rows: 87 self._appended_rows.remove(o) 88 self.rows = self.rows - 1
89 90 @model_function
91 - def getData(self):
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
97 - def _extend_cache(self, offset, limit):
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 # Verify if rows that have not yet been flushed have been requested 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
116 - def _get_object(self, row):
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 # first try to get the primary key out of the cache, if it's not 124 # there, query the collection_getter 125 try: 126 return self.cache[Qt.EditRole].get_entity_at_row(row) 127 except KeyError: 128 pass 129 # momentary hack for list error that prevents forms to be closed 130 res = self._query_getter().offset(row) 131 if isinstance(res, list): 132 res = res[0] 133 return res.limit(1).first()
134