1 """Routines for saving, retrieving, and creating fields"""
2
3 import struct
4 from dbf.exceptions import DataOverflow
5 from dbf.dates import Date, DateTime, Time
6
7 __docformat__ = 'restructuredtext'
8
9
10 VFPTIME = 1721425
11
13 "Returns a two-bye integer from the value, or raises DbfError"
14
15 if value > 65535:
16 raise DateOverflow("Maximum Integer size exceeded. Possible: 65535. Attempted: %d" % value)
17 if bigendian:
18 return struct.pack('>H', value)
19 else:
20 return struct.pack('<H', value)
22 "Returns a four-bye integer from the value, or raises DbfError"
23
24 if value > 4294967295:
25 raise DateOverflow("Maximum Integer size exceeded. Possible: 4294967295. Attempted: %d" % value)
26 if bigendian:
27 return struct.pack('>L', value)
28 else:
29 return struct.pack('<L', value)
31 "Returns a group of three bytes, in integer form, of the date"
32 return "%c%c%c" % (date.year-1900, date.month, date.day)
34 "Returns an 11 byte, upper-cased, null padded string suitable for field names; raises DbfError if the string is bigger than 10 bytes"
35 if len(string) > 10:
36 raise DbfError("Maximum string size is ten characters -- %s has %d characters" % (string, len(string)))
37 return struct.pack('11s', string.upper())
39 "Returns the value in the two-byte integer passed in"
40 if bigendian:
41 return struct.unpack('>H', bytes)[0]
42 else:
43 return struct.unpack('<H', bytes)[0]
45 "Returns the value in the four-byte integer passed in"
46 if bigendian:
47 return int(struct.unpack('>L', bytes)[0])
48 else:
49 return int(struct.unpack('<L', bytes)[0])
51 "Returns a Date() of the packed three-byte date passed in"
52 year, month, day = struct.unpack('<BBB', bytestr)
53 year += 1900
54 return Date(year, month, day)
56 "Returns a normal, lower-cased string from a null-padded byte string"
57 return struct.unpack('%ds' % len(chars), chars)[0].replace('\x00','').lower()
59 """Returns boolean true or false; normal rules apply to non-string values; string values
60 must be 'y','t', 'yes', or 'true' (case insensitive) to be True"""
61 if type(value) == str:
62 return bool(value.lower() in ['t', 'y', 'true', 'yes'])
63 else:
64 return bool(value)
66 "called if a data type is not supported for that style of table"
67 raise DbfError('field type is not supported.')
69 "Returns the string in bytes with trailing white space removed"
70 return bytes.tostring().rstrip()
72 "returns the string, truncating if string is longer than it's field"
73 if type(string) != str:
74 raise DbfError("incompatible type: %s" % type(string))
75 return string.rstrip()
77 value = struct.unpack('<q', bytes)[0]
78 return Decimal("%de-4" % value)
80 currency = int(value * 10000)
81 if not -9223372036854775808 < currency < 9223372036854775808:
82 raise DataOverflow("value %s is out of bounds" % value)
83 return struct.pack('<q', currency)
85 "Returns the ascii coded date as a Date object"
86 return Date.fromymd(bytes.tostring())
88 "returns the Date or datetime.date object ascii-encoded (yyyymmdd)"
89 if moment:
90 return "%04d%02d%02d" % moment.timetuple()[:3]
91 return ' '
110 """sets the date/time stored in moment
111 moment must have fields year, month, day, hour, minute, second, microsecond"""
112 bytes = [0] * 8
113 hour = moment.hour
114 minute = moment.minute
115 second = moment.second
116 millisecond = moment.microsecond // 1000
117 time = ((hour * 3600) + (minute * 60) + second) * 1000 + millisecond
118 bytes[4:] = updateInteger(time)
119 bytes[:4] = updateInteger(moment.toordinal() + VFPTIME)
120 return ''.join(bytes)
122 return struct.unpack('<d', bytes)[0]
124 if not (type(value) in (int, long, float)):
125 raise DbfError("incompatible type: %s" % type(value))
126 return struct.pack('<d', value)
128 "Returns the binary number stored in bytes in little-endian format"
129 return struct.unpack('<i', bytes)[0]
131 "returns value in little-endian binary format"
132 if not (type(value) in (int, long)):
133 raise DbfError("incompatible type: %s" % type(value))
134 if not -2147483648 < value < 2147483647:
135 raise DataOverflow("Integer size exceeded. Possible: -2,147,483,648..+2,147,483,647. Attempted: %d" % value)
136 return struct.pack('<i', value)
138 "Returns True if bytes is 't', 'T', 'y', or 'Y', and False otherwise"
139 return bytes.tostring() in ['t','T','y','Y']
141 "Returs 'T' if logical is True, 'F' otherwise"
142 if type(logical) != bool:
143 logical = convertToBool(logical)
144 if type(logical) <> bool:
145 raise DbfError('Value %s is not logical.' % logical)
146 return logical and 'T' or 'F'
148 "Returns the block of data from a memo file"
149 stringval = bytes.tostring()
150 if stringval.strip():
151 block = int(stringval.strip())
152 else:
153 block = 0
154 return memo.getMemo(block, fielddef)
156 "Writes string as a memo, returns the block number it was saved into"
157 block = memo.putMemo(string)
158 if block == 0:
159 block = ''
160 return "%*s" % (fielddef['length'], block)
162 "Returns the number stored in bytes as integer if field spec for decimals is 0, float otherwise"
163 string = bytes.tostring()
164 if not string.strip():
165 string = '0'
166 if fielddef['decimals'] == 0:
167 return int(string)
168 else:
169 return float(string)
171 "returns value as ascii representation, rounding decimal portion as necessary"
172 if not (type(value) in (int, long, float)):
173 raise DbfError("incompatible type: %s" % type(value))
174 decimalsize = fielddef['decimals']
175 if decimalsize:
176 decimalsize += 1
177 maxintegersize = fielddef['length']-decimalsize
178 integersize = len("%.0f" % value)
179 if integersize > maxintegersize:
180 raise DataOverflow('Integer portion too big')
181 return "%*.*f" % (fielddef['length'], fielddef['decimals'], value)
183 "Returns the block of data from a memo file"
184 block = struct.unpack('<i', bytes)[0]
185 return memo.getMemo(block, fielddef)
187 "Writes string as a memo, returns the block number it was saved into"
188 block = memo.putMemo(string)
189 return struct.pack('<i', block)
191 if format[1] != '(' or format[-1] != ')':
192 raise DbfError("Format for Character field creation is C(n), not %s" % format)
193 length = int(format[2:-1])
194 if not 0 < length < 255:
195 raise ValueError
196 decimals = 0
197 return length, decimals
199 length = 8
200 decimals = 0
201 return length, decimals
203 length = 1
204 decimals = 0
205 return length, decimals
207 length = 10
208 decimals = 0
209 return length, decimals
211 if format[1] != '(' or format[-1] != ')':
212 raise DbfError("Format for Numeric field creation is N(n,n), not %s" % format)
213 length, decimals = format[2:-1].split(',')
214 length = int(length)
215 decimals = int(decimals)
216 if not (0 < length < 18 and 0 <= decimals <= length - 2):
217 raise ValueError
218 return length, decimals
220 length = 8
221 decimals = 0
222 return length, decimals
224 length = 8
225 decimals = 8
226 return length, decimals
228 length = 8
229 decimals = 0
230 return length, decimals
232 length = 4
233 decimals = 0
234 return length, decimals
236 length = 4
237 decimals = 0
238 return length, decimals
240 if format[1] != '(' or format[-1] != ')':
241 raise DbfError("Format for Numeric field creation is N(n,n), not %s" % format)
242 length, decimals = format[2:-1].split(',')
243 length = int(length)
244 decimals = int(decimals)
245 if not (0 < length < 21 and 0 <= decimals <= length - 2):
246 raise ValueError
247 return length, decimals
248