summaryrefslogtreecommitdiff
path: root/tablib/packages/dbfpy/dbfnew.py
diff options
context:
space:
mode:
authorKenneth Reitz <me@kennethreitz.org>2016-02-07 07:00:55 -0500
committerKenneth Reitz <me@kennethreitz.org>2016-02-07 07:00:55 -0500
commit8debeb26aca7cc9ef427c70ee9d577eb169f9560 (patch)
tree58316fe5669e86cbea9a1044e4978ffd3b4cc308 /tablib/packages/dbfpy/dbfnew.py
parent66d9e50984e7c66fd36fd86f2b469c2dae3636ba (diff)
parenta774789252d41522d4ec8b0e2c212aff4a33904d (diff)
downloadtablib-8debeb26aca7cc9ef427c70ee9d577eb169f9560.tar.gz
Merge branch 'develop' into import_export
# Conflicts: # tablib/core.py # tablib/formats/_csv.py # tablib/formats/_xlsx.py
Diffstat (limited to 'tablib/packages/dbfpy/dbfnew.py')
-rw-r--r--tablib/packages/dbfpy/dbfnew.py188
1 files changed, 188 insertions, 0 deletions
diff --git a/tablib/packages/dbfpy/dbfnew.py b/tablib/packages/dbfpy/dbfnew.py
new file mode 100644
index 0000000..dea7e52
--- /dev/null
+++ b/tablib/packages/dbfpy/dbfnew.py
@@ -0,0 +1,188 @@
+#!/usr/bin/python
+""".DBF creation helpers.
+
+Note: this is a legacy interface. New code should use Dbf class
+ for table creation (see examples in dbf.py)
+
+TODO:
+ - handle Memo fields.
+ - check length of the fields accoring to the
+ `http://www.clicketyclick.dk/databases/xbase/format/data_types.html`
+
+"""
+"""History (most recent first)
+04-jul-2006 [als] added export declaration;
+ updated for dbfpy 2.0
+15-dec-2005 [yc] define dbf_new.__slots__
+14-dec-2005 [yc] added vim modeline; retab'd; added doc-strings;
+ dbf_new now is a new class (inherited from object)
+??-jun-2000 [--] added by Hans Fiby
+"""
+
+__version__ = "$Revision: 1.4 $"[11:-2]
+__date__ = "$Date: 2006/07/04 08:18:18 $"[7:-2]
+
+__all__ = ["dbf_new"]
+
+from dbf import *
+from fields import *
+from header import *
+from record import *
+
+class _FieldDefinition(object):
+ """Field definition.
+
+ This is a simple structure, which contains ``name``, ``type``,
+ ``len``, ``dec`` and ``cls`` fields.
+
+ Objects also implement get/setitem magic functions, so fields
+ could be accessed via sequence iterface, where 'name' has
+ index 0, 'type' index 1, 'len' index 2, 'dec' index 3 and
+ 'cls' could be located at index 4.
+
+ """
+
+ __slots__ = "name", "type", "len", "dec", "cls"
+
+ # WARNING: be attentive - dictionaries are mutable!
+ FLD_TYPES = {
+ # type: (cls, len)
+ "C": (DbfCharacterFieldDef, None),
+ "N": (DbfNumericFieldDef, None),
+ "L": (DbfLogicalFieldDef, 1),
+ # FIXME: support memos
+ # "M": (DbfMemoFieldDef),
+ "D": (DbfDateFieldDef, 8),
+ # FIXME: I'm not sure length should be 14 characters!
+ # but temporary I use it, cuz date is 8 characters
+ # and time 6 (hhmmss)
+ "T": (DbfDateTimeFieldDef, 14),
+ }
+
+ def __init__(self, name, type, len=None, dec=0):
+ _cls, _len = self.FLD_TYPES[type]
+ if _len is None:
+ if len is None:
+ raise ValueError("Field length must be defined")
+ _len = len
+ self.name = name
+ self.type = type
+ self.len = _len
+ self.dec = dec
+ self.cls = _cls
+
+ def getDbfField(self):
+ "Return `DbfFieldDef` instance from the current definition."
+ return self.cls(self.name, self.len, self.dec)
+
+ def appendToHeader(self, dbfh):
+ """Create a `DbfFieldDef` instance and append it to the dbf header.
+
+ Arguments:
+ dbfh: `DbfHeader` instance.
+
+ """
+ _dbff = self.getDbfField()
+ dbfh.addField(_dbff)
+
+
+class dbf_new(object):
+ """New .DBF creation helper.
+
+ Example Usage:
+
+ dbfn = dbf_new()
+ dbfn.add_field("name",'C',80)
+ dbfn.add_field("price",'N',10,2)
+ dbfn.add_field("date",'D',8)
+ dbfn.write("tst.dbf")
+
+ Note:
+ This module cannot handle Memo-fields,
+ they are special.
+
+ """
+
+ __slots__ = ("fields",)
+
+ FieldDefinitionClass = _FieldDefinition
+
+ def __init__(self):
+ self.fields = []
+
+ def add_field(self, name, typ, len, dec=0):
+ """Add field definition.
+
+ Arguments:
+ name:
+ field name (str object). field name must not
+ contain ASCII NULs and it's length shouldn't
+ exceed 10 characters.
+ typ:
+ type of the field. this must be a single character
+ from the "CNLMDT" set meaning character, numeric,
+ logical, memo, date and date/time respectively.
+ len:
+ length of the field. this argument is used only for
+ the character and numeric fields. all other fields
+ have fixed length.
+ FIXME: use None as a default for this argument?
+ dec:
+ decimal precision. used only for the numric fields.
+
+ """
+ self.fields.append(self.FieldDefinitionClass(name, typ, len, dec))
+
+ def write(self, filename):
+ """Create empty .DBF file using current structure."""
+ _dbfh = DbfHeader()
+ _dbfh.setCurrentDate()
+ for _fldDef in self.fields:
+ _fldDef.appendToHeader(_dbfh)
+ _dbfStream = file(filename, "wb")
+ _dbfh.write(_dbfStream)
+ _dbfStream.close()
+
+ def write_stream(self, stream):
+ _dbfh = DbfHeader()
+ _dbfh.setCurrentDate()
+ for _fldDef in self.fields:
+ _fldDef.appendToHeader(_dbfh)
+ _dbfh.write(stream)
+
+
+if (__name__=='__main__'):
+ # create a new DBF-File
+ dbfn=dbf_new()
+ dbfn.add_field("name",'C',80)
+ dbfn.add_field("price",'N',10,2)
+ dbfn.add_field("date",'D',8)
+ dbfn.write("tst.dbf")
+ # test new dbf
+ print "*** created tst.dbf: ***"
+ dbft = Dbf('tst.dbf', readOnly=0)
+ print repr(dbft)
+ # add a record
+ rec=DbfRecord(dbft)
+ rec['name']='something'
+ rec['price']=10.5
+ rec['date']=(2000,1,12)
+ rec.store()
+ # add another record
+ rec=DbfRecord(dbft)
+ rec['name']='foo and bar'
+ rec['price']=12234
+ rec['date']=(1992,7,15)
+ rec.store()
+
+ # show the records
+ print "*** inserted 2 records into tst.dbf: ***"
+ print repr(dbft)
+ for i1 in range(len(dbft)):
+ rec = dbft[i1]
+ for fldName in dbft.fieldNames:
+ print '%s:\t %s'%(fldName, rec[fldName])
+ print
+ dbft.close()
+
+# vim: set et sts=4 sw=4 :