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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 806 - (show 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 # Copyright (c) 2001, 2002, 2003 by Intevation GmbH
2 # Authors:
3 # Bernhard Herzog <[email protected]>
4 # Jan-Oliver Wagner <[email protected]>
5 #
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 FIELDTYPE_INT = "int"
19 FIELDTYPE_STRING = "string"
20 FIELDTYPE_DOUBLE = "double"
21
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 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 class DBFTable:
66
67 """
68 Table interface for the data in a DBF file
69 """
70
71 # 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 # well. If that succeeds the read/write DBF file will be used for
78 # all IO afterwards.
79 #
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 def __init__(self, filename):
86 self.filename = filename
87 self.dbf = dbflib.DBFFile(filename)
88
89 # If true, self.dbf is open for writing.
90 self._writable = 0
91
92 def Destroy(self):
93 self.dbf.close()
94 self.dbf = None
95
96 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 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 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 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 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 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
211
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