aboutsummaryrefslogtreecommitdiff
path: root/rpkid/rpki
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2012-10-26 15:15:48 +0000
committerRob Austein <sra@hactrn.net>2012-10-26 15:15:48 +0000
commit0382c2893986cbe187f8435bccd8e1ba6e4b76fc (patch)
treeacebbea6b9788832170a7d1b1e68f11a26d428dc /rpkid/rpki
parentc0bf5482815e73d65490b8fc60753f18f233ee11 (diff)
Teach MySQLdb converter interface about rpki.sundial.datetime.
svn path=/branches/tk274/; revision=4794
Diffstat (limited to 'rpkid/rpki')
-rw-r--r--rpkid/rpki/gui/app/views.py2
-rw-r--r--rpkid/rpki/irdb/models.py7
-rw-r--r--rpkid/rpki/mysql_import.py2
-rw-r--r--rpkid/rpki/sql.py10
-rw-r--r--rpkid/rpki/sundial.py46
5 files changed, 48 insertions, 19 deletions
diff --git a/rpkid/rpki/gui/app/views.py b/rpkid/rpki/gui/app/views.py
index 6ba6f1c4..cd4a58f7 100644
--- a/rpkid/rpki/gui/app/views.py
+++ b/rpkid/rpki/gui/app/views.py
@@ -414,7 +414,7 @@ def child_edit(request, pk):
if request.method == 'POST':
form = form_class(request.POST, request.FILES)
if form.is_valid():
- child.valid_until = sundial.datetime.fromdatetime(form.cleaned_data.get('valid_until'))
+ child.valid_until = sundial.datetime.from_datetime(form.cleaned_data.get('valid_until'))
child.save()
# remove AS & prefixes that are not selected in the form
models.ChildASN.objects.filter(child=child).exclude(pk__in=form.cleaned_data.get('as_ranges')).delete()
diff --git a/rpkid/rpki/irdb/models.py b/rpkid/rpki/irdb/models.py
index e408612e..5c6d7701 100644
--- a/rpkid/rpki/irdb/models.py
+++ b/rpkid/rpki/irdb/models.py
@@ -98,14 +98,14 @@ class SundialField(django.db.models.DateTimeField):
def to_python(self, value):
if isinstance(value, rpki.sundial.pydatetime.datetime):
- return rpki.sundial.datetime.fromdatetime(
+ return rpki.sundial.datetime.from_datetime(
django.db.models.DateTimeField.to_python(self, value))
else:
return value
def get_prep_value(self, value):
if isinstance(value, rpki.sundial.datetime):
- return value.to_sql()
+ return value.to_datetime()
else:
return value
@@ -307,8 +307,7 @@ class CA(django.db.models.Model):
def generate_crl(self):
now = rpki.sundial.now()
self.revocations.filter(expires__lt = now).delete()
- revoked = [(r.serial, rpki.sundial.datetime.fromdatetime(r.revoked))
- for r in self.revocations.all()]
+ revoked = [(r.serial, r.revoked) for r in self.revocations.all()]
self.latest_crl = rpki.x509.CRL.generate(
keypair = self.private_key,
issuer = self.certificate,
diff --git a/rpkid/rpki/mysql_import.py b/rpkid/rpki/mysql_import.py
index 40ccc348..e7b54dde 100644
--- a/rpkid/rpki/mysql_import.py
+++ b/rpkid/rpki/mysql_import.py
@@ -61,3 +61,5 @@ else:
import _mysql_exceptions
warnings.simplefilter("error", _mysql_exceptions.Warning)
+
+import MySQLdb.converters
diff --git a/rpkid/rpki/sql.py b/rpkid/rpki/sql.py
index c4c9a7ae..d4426680 100644
--- a/rpkid/rpki/sql.py
+++ b/rpkid/rpki/sql.py
@@ -59,13 +59,21 @@ class session(object):
self.database = cfg.get("sql-database")
self.password = cfg.get("sql-password")
+ self.conv = MySQLdb.converters.conversions.copy()
+ self.conv.update({
+ rpki.sundial.datetime : MySQLdb.converters.DateTime2literal,
+ MySQLdb.converters.FIELD_TYPE.DATETIME : rpki.sundial.datetime.DateTime_or_None })
+
self.cache = weakref.WeakValueDictionary()
self.dirty = set()
self.connect()
def connect(self):
- self.db = MySQLdb.connect(user = self.username, db = self.database, passwd = self.password)
+ self.db = MySQLdb.connect(user = self.username,
+ db = self.database,
+ passwd = self.password,
+ conv = self.conv)
self.cur = self.db.cursor()
self.db.autocommit(True)
self.timestamp = rpki.sundial.now()
diff --git a/rpkid/rpki/sundial.py b/rpkid/rpki/sundial.py
index 2f333b40..95a44142 100644
--- a/rpkid/rpki/sundial.py
+++ b/rpkid/rpki/sundial.py
@@ -91,13 +91,24 @@ class datetime(pydatetime.datetime):
return self.toXMLtime()
@classmethod
- def fromdatetime(cls, x):
+ def from_datetime(cls, x):
"""
Convert a datetime.datetime object into this subclass. This is
whacky due to the weird constructors for datetime.
"""
return cls.combine(x.date(), x.time())
+ def to_datetime(self):
+ """
+ Convert to a datetime.datetime object. In most cases this
+ shouldn't be necessary, but convincing SQL interfaces to use
+ subclasses of datetime can be hard.
+ """
+ return pydatetime.datetime(year = self.year, month = self.month, day = self.day,
+ hour = self.hour, minute = self.minute, second = self.second,
+ microsecond = 0, tzinfo = None)
+
+
@classmethod
def fromOpenSSL(cls, x):
"""
@@ -113,22 +124,13 @@ class datetime(pydatetime.datetime):
"""
Convert from SQL storage format.
"""
- return cls.fromdatetime(x)
+ return cls.from_datetime(x)
def to_sql(self):
"""
Convert to SQL storage format.
-
- There's something whacky going on in the MySQLdb module, it throws
- range errors when storing a derived type into a DATETIME column.
- Investigate some day, but for now brute force this by copying the
- relevant fields into a datetime.datetime for MySQLdb's
- consumption.
-
"""
- return pydatetime.datetime(year = self.year, month = self.month, day = self.day,
- hour = self.hour, minute = self.minute, second = self.second,
- microsecond = 0, tzinfo = None)
+ return self.to_datetime()
def later(self, other):
"""
@@ -147,6 +149,24 @@ class datetime(pydatetime.datetime):
def __rsub__(self, y): return _cast(pydatetime.datetime.__rsub__(self, y))
def __sub__(self, y): return _cast(pydatetime.datetime.__sub__(self, y))
+ @classmethod
+ def DateTime_or_None(cls, s):
+ """
+ MySQLdb converter. Parse as this class if we can, let the default
+ MySQLdb DateTime_or_None() converter deal with failure cases.
+ """
+
+ for sep in " T":
+ d, _, t = s.partition(sep)
+ if t:
+ try:
+ return cls(*[int(x) for x in d.split("-") + t.split(":")])
+ except:
+ break
+
+ from rpki.mysql_import import MySQLdb
+ return MySQLdb.times.DateTime_or_None(s)
+
class timedelta(pydatetime.timedelta):
"""
Timedelta with text parsing. This accepts two input formats:
@@ -245,7 +265,7 @@ def _cast(x):
Cast result of arithmetic operations back into correct subtype.
"""
if isinstance(x, pydatetime.datetime):
- return datetime.fromdatetime(x)
+ return datetime.from_datetime(x)
if isinstance(x, pydatetime.timedelta):
return timedelta.fromtimedelta(x)
return x