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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 806 - (hide annotations)
Fri May 2 16:43:59 2003 UTC (21 years, 10 months ago) by jan
Original Path: trunk/thuban/Thuban/Model/table.py
File MIME type: text/x-python
File size: 6324 byte(s)
(MemoryTable): New. Quite simple table implementation that operates on a
list of tuples. All of the data are kept in the memory.

1 bh 590 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 bh 6 # Authors:
3     # Bernhard Herzog <[email protected]>
4 jan 806 # Jan-Oliver Wagner <[email protected]>
5 bh 6 #
6     # This program is free software under the GPL (>=v2)
7     # Read the file COPYING coming with Thuban for details.
8    
9     """
10     Classes for handling tables of data.
11     """
12    
13     __version__ = "$Revision$"
14    
15     import dbflib
16    
17     # the field types supported by a Table instance.
18 jonathan 474 FIELDTYPE_INT = "int"
19     FIELDTYPE_STRING = "string"
20     FIELDTYPE_DOUBLE = "double"
21 bh 6
22    
23     # map the dbflib constants for the field types to our constants
24     dbflib_fieldtypes = {dbflib.FTString: FIELDTYPE_STRING,
25     dbflib.FTInteger: FIELDTYPE_INT,
26     dbflib.FTDouble: FIELDTYPE_DOUBLE}
27    
28 jan 806 class MemoryTable:
29    
30     """Quite simple table implementation that operates on a list of tuples.
31     All of the data are kept in the memory."""
32    
33     def __init__(self, fields, data):
34     """Initialize the MemoryTable
35    
36     Parameters:
37     fields -- List of (name, field_type) pairs
38     data -- List of tuples, one for each row of data
39     """
40     self.fields = fields
41     self.data = data
42    
43     def field_count(self):
44     return len(self.fields)
45    
46     def field_info(self, index):
47     name, type = self.fields[index]
48     return (type, name)
49    
50     def record_count(self):
51     return len(self.data)
52    
53     def read_record(self, index):
54     return dict([(self.fields[i][0], self.data[index][i])
55     for i in range(len(self.fields))])
56    
57     def write_record(self, record, values):
58     # TODO: Check for correct lenght and perhaps also
59     # for correct types in case values is a tuple. How to report problems?
60     # TODO: Allow values to be a dictionary and write the single
61     # fields that are specified.
62     self.data[record] = values
63    
64    
65 bh 765 class DBFTable:
66 bh 6
67     """
68 bh 765 Table interface for the data in a DBF file
69 bh 6 """
70    
71 bh 286 # Implementation strategy regarding writing to a DBF file:
72     #
73     # Most of the time Thuban only needs to read from a table and it is
74     # important that Thuban can work with read-only files. Therefore the
75     # DBF file is opened only for reading initially. Only when
76     # write_record is called we try to open the DBF file for writing as
77 bh 590 # well. If that succeeds the read/write DBF file will be used for
78     # all IO afterwards.
79 bh 286 #
80     # It's important to use the same DBF file object for both reading
81     # and writing to make sure that reading a records after writing
82     # returns the new values. With two separate objects this wouldn't
83     # work because a DBF file object buffers some data
84    
85 bh 6 def __init__(self, filename):
86     self.filename = filename
87 bh 284 self.dbf = dbflib.DBFFile(filename)
88 bh 6
89 bh 286 # If true, self.dbf is open for writing.
90     self._writable = 0
91    
92 bh 257 def Destroy(self):
93     self.dbf.close()
94     self.dbf = None
95    
96 bh 6 def record_count(self):
97     """Return the number of records"""
98     return self.dbf.record_count()
99    
100     def field_count(self):
101     """Return the number of fields in a record"""
102     return self.dbf.field_count()
103    
104     def field_info(self, field):
105     """Return a tuple (type, name, width, prec) for the field no. field
106    
107     type is the data type of the field, name the name, width the
108     field width in characters and prec the decimal precision.
109     """
110     type, name, width, prec = self.dbf.field_info(field)
111     type = dbflib_fieldtypes[type]
112     return type, name, width, prec
113    
114 jonathan 467 def field_info_by_name(self, fieldName):
115     count = self.field_count()
116    
117     for i in range(count):
118     info = self.field_info(i)
119     if info[1] == fieldName:
120     return info
121    
122     return None
123    
124 jonathan 628 def field_range(self, fieldName):
125     """Finds the first occurences of the minimum and maximum values
126     in the table for the given field.
127    
128     This assumes that the standard comparison operators (<, >, etc.)
129     will work for the given data.
130    
131     Returns a tuple ((min, rec), (max, rec)) where:
132     min is the minimum value
133     max is the maximum value
134     rec is the record number where the value was found. One
135     should check that the record number of min is not
136     the same as the record number of max.
137    
138     Returns None if there are no records
139    
140     """
141    
142    
143     count = self.record_count()
144    
145     if count == 0:
146     return None
147    
148     rec = self.read_record(0)
149    
150     min = rec[fieldName]
151     min_rec = 0
152    
153     max = rec[fieldName]
154     max_rec = 0
155    
156     for i in range(1, count):
157     rec = self.read_record(i)
158     data = rec[fieldName]
159    
160     if data < min:
161     min = data
162     min_rec = rec
163     elif data > max:
164     max = data
165     max_rec = rec
166    
167     return ((min, min_rec), (max, max_rec))
168    
169     def GetUniqueValues(self, fieldName):
170     """Return a list of all unique entries in the table for the given
171     field name.
172     """
173    
174     dict = {}
175    
176     for i in range(0, self.record_count()):
177     rec = self.read_record(i)
178     data = rec[fieldName]
179    
180     if not dict.has_key(data):
181     dict[data] = 0
182    
183     return dict.keys()
184    
185 bh 6 def read_record(self, record):
186     """Return the record no. record as a dict mapping field names to values
187     """
188     return self.dbf.read_record(record)
189    
190 bh 274 def write_record(self, record, values):
191     """Write the values into the record
192    
193     The values parameter may either be a dictionary or a sequence.
194    
195     If it's a dictionary the keys must be the names of the fields
196     and their value must have a suitable type. Only the fields
197     actually contained in the dictionary are written. Fields for
198     which there's no item in the dict are not modified.
199    
200     If it's a sequence, all fields must be present in the right
201     order.
202     """
203 bh 286 if not self._writable:
204     new_dbf = dbflib.DBFFile(self.filename, "r+b")
205     self.dbf.close()
206     self.dbf = new_dbf
207     self._writable = 1
208     self.dbf.write_record(record, values)
209     self.dbf.commit()
210 jonathan 467
211 bh 765
212    
213     # Temporary backwards compatibility
214     Table = DBFTable

Properties

Name Value
svn:eol-style native
svn:keywords Author Date Id Revision

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26