Author: phd
Date: 2005-10-18 15:06:59 +0000 (Tue, 18 Oct 2005)
New Revision: 1124
Modified:
home/phd/SQLObject/paramstyles/docs/Authors.txt
home/phd/SQLObject/paramstyles/docs/News.txt
home/phd/SQLObject/paramstyles/docs/SQLObject.txt
home/phd/SQLObject/paramstyles/sqlobject/col.py
home/phd/SQLObject/paramstyles/sqlobject/converters.py
home/phd/SQLObject/paramstyles/sqlobject/tests/test_datetime.py
Log:
Merged patches from the revisions 1115:1123 from the trunk: added TimeCol.
Modified: home/phd/SQLObject/paramstyles/docs/Authors.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/Authors.txt 2005-10-18 15:04:45 UTC (rev 1123)
+++ home/phd/SQLObject/paramstyles/docs/Authors.txt 2005-10-18 15:06:59 UTC (rev 1124)
@@ -18,4 +18,5 @@
* Yaroslav Samchuk <yarcat at ank-sia.com>
* Runar Petursson <grunar at gmail.com>
* J Paulo Fernandes Farias <jpaulofarias at gmail.com>
+* Shahms King <shahms at shahms.com>
* Oleg Broytmann <ph...@ph...>
Modified: home/phd/SQLObject/paramstyles/docs/News.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/News.txt 2005-10-18 15:04:45 UTC (rev 1123)
+++ home/phd/SQLObject/paramstyles/docs/News.txt 2005-10-18 15:06:59 UTC (rev 1124)
@@ -21,6 +21,8 @@
Constraints (in the DBMSes that support constraints) are added after the
tables have been created.
+* Added ``TimeCol``.
+
SQLObject 0.7.0
===============
Modified: home/phd/SQLObject/paramstyles/docs/SQLObject.txt
===================================================================
--- home/phd/SQLObject/paramstyles/docs/SQLObject.txt 2005-10-18 15:04:45 UTC (rev 1123)
+++ home/phd/SQLObject/paramstyles/docs/SQLObject.txt 2005-10-18 15:06:59 UTC (rev 1124)
@@ -1025,11 +1025,14 @@
`CurrencyCol`:
Equivalent to ``DecimalCol(size=10, precision=2)``.
+`DateTimeCol`:
+ A date and time (usually returned as an datetime or mxDateTime object).
+
`DateCol`:
A date (usually returned as an datetime or mxDateTime object).
-`DateTimeCol`:
- A date and time (usually returned as an datetime or mxDateTime object).
+`TimeCol`:
+ A time (usually returned as an datetime or mxDateTime object).
`DecimalCol`:
Base-10, precise number. Uses the keyword arguments `size` for
@@ -1535,6 +1538,8 @@
* `ForeignKey`
* `EnumCol`
* `DateTimeCol`
+* `DateCol`
+* `TimeCol`
* `DecimalCol`
* `CurrencyCol`
Modified: home/phd/SQLObject/paramstyles/sqlobject/col.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/col.py 2005-10-18 15:04:45 UTC (rev 1123)
+++ home/phd/SQLObject/paramstyles/sqlobject/col.py 2005-10-18 15:06:59 UTC (rev 1124)
@@ -60,6 +60,7 @@
if mxdatetime_available:
DateTimeType = type(DateTime.now())
+ TimeType = type(DateTime.Time())
if datetime_available:
default_datetime_implementation = DATETIME_IMPLEMENTATION
@@ -333,7 +334,7 @@
def mssqlCreateSQL(self):
return ' '.join([self.dbName, self._mssqlType()] + self._extraSQL())
-
+
def firebirdCreateSQL(self):
# Ian Sparks pointed out that fb is picky about the order
# of the NOT NULL clause in a create statement. So, we handle
@@ -566,15 +567,15 @@
except OverflowError: # for Python 2.2
return long(value)
except:
- raise validators.Invalid("expected an int in the IntCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected an int in the IntCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
def from_python(self, value, state):
if value is None:
return None
if not isinstance(value, (int, long, sqlbuilder.SQLExpression)):
- raise validators.Invalid("expected an int in the IntCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected an int in the IntCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
return value
class SOIntCol(SOCol):
@@ -654,15 +655,15 @@
try:
return float(value)
except:
- raise validators.Invalid("expected a float in the FloatCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected a float in the FloatCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
def from_python(self, value, state):
if value is None:
return None
if not isinstance(value, (int, long, float, sqlbuilder.SQLExpression)):
- raise validators.Invalid("expected a float in the FloatCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected a float in the FloatCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
return value
class SOFloatCol(SOCol):
@@ -701,7 +702,7 @@
def _sybaseType(self):
return 'NUMERIC(18,0) NULL'
-
+
def _mssqlType(self):
return 'INT NULL'
@@ -870,39 +871,45 @@
def to_python(self, value, state):
if value is None:
return None
- if isinstance(value, (datetime.date, datetime.datetime, sqlbuilder.SQLExpression)):
+ if isinstance(value, (datetime.datetime, datetime.date, datetime.time, sqlbuilder.SQLExpression)):
return value
- if mxdatetime_available and isinstance(value, DateTimeType):
- # convert mxDateTime instance to datetime
- if (self.format.find("%H") >= 0) or (self.format.find("%T")) >= 0:
- return datetime.datetime(value.year, value.month, value.day,
- value.hour, value.minute, int(value.second))
- else:
- return datetime.date(value.year, value.month, value.day)
+ if mxdatetime_available:
+ if isinstance(value, DateTimeType):
+ # convert mxDateTime instance to datetime
+ if (self.format.find("%H") >= 0) or (self.format.find("%T")) >= 0:
+ return datetime.datetime(value.year, value.month, value.day,
+ value.hour, value.minute, int(value.second))
+ else:
+ return datetime.date(value.year, value.month, value.day)
+ elif isinstance(value, TimeType):
+ # convert mxTime instance to time
+ if self.format.find("%d") >= 0:
+ return datetime.timedelta(seconds=value.seconds)
+ else:
+ return datetime.time(value.hour, value.minute, int(value.second))
try:
stime = time.strptime(value, self.format)
except:
- raise validators.Invalid("expected an date/time string of the '%s' format in the DateTimeCol '%s', got %s instead" % \
- (self.format, self.name, type(value)), value, state)
- secs = time.mktime(stime)
- return datetime.datetime.fromtimestamp(secs)
+ raise validators.Invalid("expected an date/time string of the '%s' format in the DateTimeCol '%s', got %s %r instead" % \
+ (self.format, self.name, type(value), value), value, state)
+ return datetime.datetime(*stime[:7])
def from_python(self, value, state):
if value is None:
return None
- if isinstance(value, (datetime.date, datetime.datetime, sqlbuilder.SQLExpression)):
+ if isinstance(value, (datetime.datetime, datetime.date, datetime.time, sqlbuilder.SQLExpression)):
return value
if hasattr(value, "strftime"):
return value.strftime(self.format)
- raise validators.Invalid("expected a datetime in the DateTimeCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected a datetime in the DateTimeCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
if mxdatetime_available:
class MXDateTimeValidator(validators.DateValidator):
def to_python(self, value, state):
if value is None:
return None
- if isinstance(value, (DateTimeType, sqlbuilder.SQLExpression)):
+ if isinstance(value, (DateTimeType, TimeType, sqlbuilder.SQLExpression)):
return value
if datetime_available: # convert datetime instance to mxDateTime
if isinstance(value, datetime.datetime):
@@ -910,22 +917,24 @@
value.hour, value.minute, value.second)
elif isinstance(value, datetime.date):
return DateTime.Date(value.year, value.month, value.day)
+ elif isinstance(value, datetime.time):
+ return DateTime.Time(value.hour, value.minute, value.second)
try:
stime = time.strptime(value, self.format)
except:
- raise validators.Invalid("expected an date/time string of the '%s' format in the DateTimeCol '%s', got %s instead" % \
- (self.format, self.name, type(value)), value, state)
+ raise validators.Invalid("expected an date/time string of the '%s' format in the DateTimeCol '%s', got %s %r instead" % \
+ (self.format, self.name, type(value), value), value, state)
return DateTime.mktime(stime)
def from_python(self, value, state):
if value is None:
return None
- if isinstance(value, (DateTimeType, sqlbuilder.SQLExpression)):
+ if isinstance(value, (DateTimeType, TimeType, sqlbuilder.SQLExpression)):
return value
if hasattr(value, "strftime"):
return value.strftime(self.format)
- raise validators.Invalid("expected a mxDateTime in the DateTimeCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected a mxDateTime in the DateTimeCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
class SODateTimeCol(SOCol):
datetimeFormat = '%Y-%m-%d %H:%M:%S'
@@ -984,9 +993,11 @@
if datetime_available:
class DateValidator(DateTimeValidator):
def to_python(self, value, state):
+ if isinstance(value, datetime.date):
+ return value
value = super(DateValidator, self).to_python(value, state)
if isinstance(value, datetime.datetime):
- value = datetime.date(value.year, value.month, value.day)
+ value = value.date()
return value
from_python = to_python
@@ -1018,7 +1029,7 @@
def _sybaseType(self):
return self._postgresType()
-
+
def _mssqlType(self):
"""
SQL Server doesn't have a DATE data type, to emulate we use a vc(10)
@@ -1038,6 +1049,57 @@
baseClass = SODateCol
+if datetime_available:
+ class TimeValidator(DateTimeValidator):
+ def to_python(self, value, state):
+ if isinstance(value, datetime.time):
+ return value
+ value = super(TimeValidator, self).to_python(value, state)
+ if isinstance(value, datetime.datetime):
+ value = value.time()
+ return value
+
+class SOTimeCol(SOCol):
+ timeFormat = '%H:%M:%S'
+
+ def __init__(self, **kw):
+ timeFormat = popKey(kw, 'timeFormat')
+ if timeFormat:
+ self.timeFormat = timeFormat
+ SOCol.__init__(self, **kw)
+
+ def createValidators(self):
+ _validators = super(SOTimeCol, self).createValidators()
+ if default_datetime_implementation == DATETIME_IMPLEMENTATION:
+ validatorClass = TimeValidator
+ elif default_datetime_implementation == MXDATETIME_IMPLEMENTATION:
+ validatorClass = MXDateTimeValidator
+ if default_datetime_implementation:
+ _validators.insert(0, validatorClass(name=self.name, format=self.timeFormat))
+ return _validators
+
+ def _mysqlType(self):
+ return 'TIME'
+
+ def _postgresType(self):
+ return 'TIME'
+
+ def _sybaseType(self):
+ return 'TIME'
+
+ def _sqliteType(self):
+ return 'TIME'
+
+ def _firebirdType(self):
+ return 'TIME'
+
+ def _maxdbType(self):
+ return 'TIME'
+
+class TimeCol(Col):
+ baseClass = SOTimeCol
+
+
class SODecimalCol(SOCol):
def __init__(self, **kw):
@@ -1091,8 +1153,8 @@
if isinstance(value, array_type): # MySQL
return value.tostring()
return str(value) # buffer => string
- raise validators.Invalid("expected a string in the BLOBCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected a string in the BLOBCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
def from_python(self, value, state):
if value is None:
@@ -1144,8 +1206,8 @@
value = value.encode("ascii")
if isinstance(value, str):
return pickle.loads(value)
- raise validators.Invalid("expected a pickle string in the PickleCol '%s', got %s instead" % \
- (self.name, type(value)), value, state)
+ raise validators.Invalid("expected a pickle string in the PickleCol '%s', got %s %r instead" % \
+ (self.name, type(value), value), value, state)
def from_python(self, value, state):
if value is None:
Modified: home/phd/SQLObject/paramstyles/sqlobject/converters.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/converters.py 2005-10-18 15:04:45 UTC (rev 1123)
+++ home/phd/SQLObject/paramstyles/sqlobject/converters.py 2005-10-18 15:06:59 UTC (rev 1124)
@@ -3,15 +3,17 @@
try:
import mx.DateTime.ISO
origISOStr = mx.DateTime.ISO.strGMT
- from mx.DateTime import DateTimeType
+ from mx.DateTime import DateTimeType, DateTimeDeltaType
except ImportError:
try:
import DateTime.ISO
origISOStr = DateTime.ISO.strGMT
- from DateTime import DateTimeType
+ from DateTime import DateTimeType, DateTimeDeltaType
except ImportError:
origISOStr = None
DateTimeType = None
+ DateTimeDeltaType = None
+
import time
try:
import datetime
@@ -163,6 +165,11 @@
registerConverter(DateTimeType, DateTimeConverter)
+ def TimeConverter(value, db):
+ return "'%s'" % value.strftime("%T")
+
+ registerConverter(DateTimeDeltaType, TimeConverter)
+
def NoneConverter(value, db):
return "NULL"
Modified: home/phd/SQLObject/paramstyles/sqlobject/tests/test_datetime.py
===================================================================
--- home/phd/SQLObject/paramstyles/sqlobject/tests/test_datetime.py 2005-10-18 15:04:45 UTC (rev 1123)
+++ home/phd/SQLObject/paramstyles/sqlobject/tests/test_datetime.py 2005-10-18 15:06:59 UTC (rev 1124)
@@ -1,11 +1,6 @@
from sqlobject import *
from sqlobject.tests.dbtest import *
from sqlobject import col
-if default_datetime_implementation == DATETIME_IMPLEMENTATION:
- from datetime import datetime
- now = datetime.now
-elif default_datetime_implementation == MXDATETIME_IMPLEMENTATION:
- from mx.DateTime import now
########################################
## Date/time columns
@@ -13,40 +8,69 @@
if datetime_available:
col.default_datetime_implementation = DATETIME_IMPLEMENTATION
- from datetime import date, datetime
+ from datetime import datetime, date, time
class DateTime1(SQLObject):
- col1 = DateCol()
- col2 = DateTimeCol()
+ col1 = DateTimeCol()
+ col2 = DateCol()
+ col3 = TimeCol()
def test_dateTime():
setupClass(DateTime1)
- _now = now()
- dt1 = DateTime1(col1=_now, col2=_now)
- assert isinstance(dt1.col1, date)
- assert isinstance(dt1.col2, datetime)
+ _now = datetime.now()
+ _today = date.today()
+ dt1 = DateTime1(col1=_now, col2=_today, col3=_now.time())
- today_str = _now.strftime("%Y-%m-%d")
- now_str = _now.strftime("%Y-%m-%d %T")
- assert str(dt1.col1) == today_str
- assert str(dt1.col2) == now_str
+ assert isinstance(dt1.col1, datetime)
+ assert dt1.col1.year == _now.year
+ assert dt1.col1.month == _now.month
+ assert dt1.col1.day == _now.day
+ assert dt1.col1.hour == _now.hour
+ assert dt1.col1.minute == _now.minute
+ assert dt1.col1.second == int(_now.second)
+ assert isinstance(dt1.col2, date)
+ assert dt1.col2.year == _today.year
+ assert dt1.col2.month == _today.month
+ assert dt1.col2.day == _today.day
+
+ assert isinstance(dt1.col3, time)
+ assert dt1.col3.hour == _now.hour
+ assert dt1.col3.minute == _now.minute
+ assert dt1.col3.second == int(_now.second)
+
if mxdatetime_available:
col.default_datetime_implementation = MXDATETIME_IMPLEMENTATION
+ from mx.DateTime import now, Time
class DateTime2(SQLObject):
- col1 = DateCol()
- col2 = DateTimeCol()
+ col1 = DateTimeCol()
+ col2 = DateCol(dateFormat="%Y-%m-%d %H:%M:%S")
+ # mxDateTime does not have a separate date type
+ col3 = TimeCol()
def test_mxDateTime():
setupClass(DateTime2)
_now = now()
- dt2 = DateTime2(col1=_now, col2=_now)
+ dt2 = DateTime2(col1=_now, col2=_now, col3=Time(_now.hour, _now.minute, int(_now.second)))
+
assert isinstance(dt2.col1, col.DateTimeType)
+ assert dt2.col1.year == _now.year
+ assert dt2.col1.month == _now.month
+ assert dt2.col1.day == _now.day
+ assert dt2.col1.hour == _now.hour
+ assert dt2.col1.minute == _now.minute
+ assert dt2.col1.second == int(_now.second)
+
assert isinstance(dt2.col2, col.DateTimeType)
+ assert dt2.col2.year == _now.year
+ assert dt2.col2.month == _now.month
+ assert dt2.col2.day == _now.day
+ assert dt2.col1.hour == _now.hour
+ assert dt2.col1.minute == _now.minute
+ assert dt2.col1.second == int(_now.second)
- today_str = _now.strftime("%Y-%m-%d 00:00:00.00")
- now_str = _now.strftime("%Y-%m-%d %T.00")
- assert str(dt2.col1) == today_str
- assert str(dt2.col2) == now_str
-
+ assert isinstance(dt2.col3, (col.DateTimeType, col.TimeType))
+ assert dt2.col3.hour == _now.hour
+ assert dt2.col3.minute == _now.minute
+ assert dt2.col3.second == int(_now.second)
|