/[thuban]/branches/WIP-pyshapelib-bramz/Thuban/Model/table.py
ViewVC logotype

Diff of /branches/WIP-pyshapelib-bramz/Thuban/Model/table.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 817 by jan, Fri May 2 16:43:59 2003 UTC revision 818 by bh, Mon May 5 17:18:31 2003 UTC
# Line 25  dbflib_fieldtypes = {dbflib.FTString: FI Line 25  dbflib_fieldtypes = {dbflib.FTString: FI
25                       dbflib.FTInteger: FIELDTYPE_INT,                       dbflib.FTInteger: FIELDTYPE_INT,
26                       dbflib.FTDouble: FIELDTYPE_DOUBLE}                       dbflib.FTDouble: FIELDTYPE_DOUBLE}
27    
 class MemoryTable:  
28    
29      """Quite simple table implementation that operates on a list of tuples.  class OldTableInterfaceMixin:
     All of the data are kept in the memory."""  
30    
31      def __init__(self, fields, data):      """Mixin to implement the old table interface using the new one"""
         """Initialize the MemoryTable  
32    
33          Parameters:      def record_count(self):
34          fields -- List of (name, field_type) pairs          return self.NumRows()
         data -- List of tuples, one for each row of data  
         """  
         self.fields = fields  
         self.data = data  
35    
36      def field_count(self):      def field_count(self):
37          return len(self.fields)          return self.NumColumns()
38    
39      def field_info(self, index):      def field_info(self, field):
40          name, type = self.fields[index]          """Return a tuple (type, name, width, prec) for the field no. field
         return (type, name)  
41    
42      def record_count(self):          type is the data type of the field, name the name, width the
43          return len(self.data)          field width in characters and prec the decimal precision. width
44            and prec will be zero if the information returned by the Column
45            method doesn't provide values for them.
46            """
47            col = self.Column(field)
48            return (col.type, col.name,
49                   getattr(col, "width", 0), getattr(col, "prec", 0))
50    
51        def field_info_by_name(self, col):
52            try:
53                return self.field_info(col)
54            except KeyError:
55                # FIXME: It may be that field_info raises other exceptions
56                # when the name is not a valid column name.
57                return None
58    
59        def field_range(self, fieldName):
60            min, max = self.ValueRange(fieldName)
61            return ((min, None), (max, None))
62    
63        def GetUniqueValues(self, field):
64            return self.UniqueValues(field)
65    
66        def read_record(self, r):
67            return self.ReadRowAsDict(r)
68    
     def read_record(self, index):  
         return dict([(self.fields[i][0], self.data[index][i])  
                       for i in range(len(self.fields))])  
69    
     def write_record(self, record, values):  
         # TODO: Check for correct lenght and perhaps also  
         # for correct types in case values is a tuple. How to report problems?  
         # TODO: Allow values to be a dictionary and write the single  
         # fields that are specified.  
         self.data[record] = values  
70    
71    class DBFColumn:
72    
73  class DBFTable:      """Description of a column in a DBFTable
74    
75        Instances have the following public attributes:
76    
77        name -- Name of the column
78        type -- Type of the column (one of FIELDTYPE_STRING, FIELDTYPE_INT or\
79                FIELDTYPE_DOUBLE)
80        index -- The index of the column
81        width -- the width of the data in the column
82        prec -- The precision of the data (only valid for type == FIELDTYPE_DOUBLE)
83        """
84    
85        def __init__(self, name, type, width, prec, index):
86            self.name = name
87            self.type = type
88            self.width = width
89            self.prec = prec
90            self.index = index
91    
92    
93    class DBFTable(OldTableInterfaceMixin):
94    
95      """      """
96      Table interface for the data in a DBF file      Table interface for the data in a DBF file
# Line 89  class DBFTable: Line 117  class DBFTable:
117          # If true, self.dbf is open for writing.          # If true, self.dbf is open for writing.
118          self._writable = 0          self._writable = 0
119    
120      def Destroy(self):          # Create the column information objects
121          self.dbf.close()          self.columns = []
122          self.dbf = None          self.column_map = {}
123            for i in range(self.NumColumns()):
124                ftype, name, width, prec = self.dbf.field_info(i)
125                ftype = dbflib_fieldtypes[ftype]
126                index = len(self.columns)
127                col = DBFColumn(name, ftype, width, prec, index)
128                self.columns.append(col)
129                self.column_map[name] = col
130                self.column_map[index] = col
131    
132      def record_count(self):      def NumRows(self):
133          """Return the number of records"""          """Return the number of rows in the table"""
134          return self.dbf.record_count()          return self.dbf.record_count()
135    
136      def field_count(self):      def NumColumns(self):
137          """Return the number of fields in a record"""          """Return the number of columns in the table"""
138          return self.dbf.field_count()          return self.dbf.field_count()
139    
140      def field_info(self, field):      def Columns(self):
141          """Return a tuple (type, name, width, prec) for the field no. field          """Return the table's colum definitions
142    
143          type is the data type of the field, name the name, width the          The return value is a sequence of DBFColumn instances, one for
144          field width in characters and prec the decimal precision.          each column.
145          """          """
146          type, name, width, prec = self.dbf.field_info(field)          return self.columns
         type = dbflib_fieldtypes[type]  
         return type, name, width, prec  
   
     def field_info_by_name(self, fieldName):  
         count = self.field_count()  
   
         for i in range(count):  
             info = self.field_info(i)  
             if info[1] == fieldName:  
                 return info  
147    
148          return None      def Column(self, col):
149            """Return information about the column given by its name or index
150    
151      def field_range(self, fieldName):          The returned object is an instance of DBFColumn
152          """Finds the first occurences of the minimum and maximum values          """
153          in the table for the given field.          return self.column_map[col]
   
         This assumes that the standard comparison operators (<, >, etc.)  
         will work for the given data.  
154    
155          Returns a tuple ((min, rec), (max, rec)) where:      def ReadRowAsDict(self, row):
156              min is the minimum value          """Return the entire row as a dictionary with column names as keys"""
157              max is the maximum value          return self.dbf.read_record(row)
             rec is the record number where the value was found. One  
                 should check that the record number of min is not  
                 the same as the record number of max.  
158    
159          Returns None if there are no records      def ReadValue(self, row, col):
160            """Return the value of the specified row and column
161    
162            The col parameter may be the index of the column or its name.
163          """          """
164            return self.dbf.read_record(row)[self.column_map[col].name]
165    
166        def ValueRange(self, col):
167            """Return the minimum and maximum values of the values in the column
168    
169          count = self.record_count()          The return value is a tuple (min, max) unless the table is empty
170            in which case the return value is None.
171            """
172            count = self.NumRows()
173    
174          if count == 0:          if count == 0:
175              return None              return None
176    
177          rec = self.read_record(0)          min = max = self.ReadValue(0, col)
   
         min = rec[fieldName]  
         min_rec = 0  
   
         max = rec[fieldName]  
         max_rec = 0  
   
178          for i in range(1, count):          for i in range(1, count):
179              rec = self.read_record(i)              value = self.ReadValue(i, col)
180              data = rec[fieldName]              if value < min:
181                    min = value
182                elif value > max:
183                    max = value
184    
185              if data < min:          return (min, max)
                 min = data  
                 min_rec = rec  
             elif data > max:  
                 max = data  
                 max_rec = rec  
   
         return ((min, min_rec), (max, max_rec))  
   
     def GetUniqueValues(self, fieldName):  
         """Return a list of all unique entries in the table for the given  
         field name.  
         """  
186    
187        def UniqueValues(self, col):
188            """Return a sorted list of all unique values in the column col"""
189          dict = {}          dict = {}
190    
191          for i in range(0, self.record_count()):          for i in range(self.NumRows()):
192              rec = self.read_record(i)              value = self.ReadValue(i, col)
193              data = rec[fieldName]              dict[value] = 0
194    
195              if not dict.has_key(data):          values = dict.keys()
196                  dict[data] = 0          values.sort()
197            return values
198    
         return dict.keys()  
199    
200      def read_record(self, record):      # DBF specific interface parts.
201          """Return the record no. record as a dict mapping field names to values  
202          """      def Destroy(self):
203          return self.dbf.read_record(record)          self.dbf.close()
204            self.dbf = None
205    
206      def write_record(self, record, values):      def write_record(self, record, values):
207          """Write the values into the record          """Write the values into the record
# Line 212  class DBFTable: Line 228  class DBFTable:
228    
229  # Temporary backwards compatibility  # Temporary backwards compatibility
230  Table = DBFTable  Table = DBFTable
231    
232    
233    
234    class MemoryColumn:
235    
236        def __init__(self, name, type, index):
237            self.name = name
238            self.type = type
239            self.index = index
240    
241    class MemoryTable(OldTableInterfaceMixin):
242    
243        """Very simple table implementation that operates on a list of tuples"""
244    
245        def __init__(self, fields, data):
246            """Initialize the MemoryTable
247    
248            Parameters:
249            fields -- List of (name, field_type) pairs
250            data -- List of tuples, one for each row of data
251            """
252            self.data = data
253    
254            # Create the column information objects
255            self.columns = []
256            self.column_map = {}
257            for name, ftype in fields:
258                index = len(self.columns)
259                col = MemoryColumn(name, ftype, index)
260                self.columns.append(col)
261                self.column_map[name] = col
262                self.column_map[index] = col
263    
264        def NumColumns(self):
265            """Return the number of columns in the table"""
266            return len(self.columns)
267    
268        def Column(self, col):
269            """Return information about the column given by its name or index
270    
271            The returned object is an instance of MemoryColumn.
272            """
273            return self.column_map[col]
274    
275        def Columns(self):
276            """Return the table's colum definitions
277    
278            The return value is a sequence of MemoryColumn instances, one
279            for each column.
280            """
281            return self.columns
282    
283        def NumRows(self):
284            """Return the number of rows in the table"""
285            return len(self.data)
286    
287        def ReadValue(self, row, col):
288            """Return the value of the specified row and column
289    
290            The col parameter may be the index of the column or its name.
291            """
292            return self.data[row][self.column_map[col].index]
293    
294        def ReadRowAsDict(self, index):
295            """Return the entire row as a dictionary with column names as keys"""
296            return dict([(col.name, self.data[index][col.index])
297                          for col in self.columns])
298    
299        def ValueRange(self, col):
300            """Return the minimum and maximum values of the values in the column
301    
302            The return value is a tuple (min, max) unless the table is empty
303            in which case the return value is None.
304            """
305    
306            index = self.column_map[col].index
307            values = [row[index] for row in self.data]
308            if not values:
309                return None
310    
311            return min(values), max(values)
312    
313        def UniqueValues(self, col):
314            """Return a sorted list of all unique values in the column col"""
315            dict = {}
316    
317            for i in range(self.NumRows()):
318                value = self.ReadValue(i, col)
319                dict[value] = 0
320    
321            values = dict.keys()
322            values.sort()
323            return values
324    
325    
326        def write_record(self, record, values):
327            # TODO: Check for correct lenght and perhaps also
328            # for correct types in case values is a tuple. How to report problems?
329            # TODO: Allow values to be a dictionary and write the single
330            # fields that are specified.
331            self.data[record] = values

Legend:
Removed from v.817  
changed lines
  Added in v.818

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26