Add datetime and timestamp fields

This commit is contained in:
evilchili 2025-10-04 15:22:07 -07:00
parent 9449cc3937
commit 44ee664a77
3 changed files with 43 additions and 3 deletions

View File

@ -1,4 +1,4 @@
from grung.types import BackReference, Collection, Field, Integer, Password, Record
from grung.types import BackReference, Collection, DateTime, Field, Integer, Password, Record, Timestamp
class User(Record):
@ -10,6 +10,8 @@ class User(Record):
Integer("number", default=0),
Field("email", unique=True),
Password("password"),
DateTime("created"),
Timestamp("last_updated"),
BackReference("groups", Group),
]

View File

@ -6,6 +6,7 @@ import os
import re
from collections import namedtuple
from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, List
import nanoid
@ -37,7 +38,7 @@ class Field:
if value is not None:
return str(value)
def deserialize(self, value: value_type, db: TinyDB, recurse: bool = False) -> value_type:
def deserialize(self, value: str, db: TinyDB, recurse: bool = False) -> value_type:
return value
@ -50,6 +51,30 @@ class Integer(Field):
return int(value)
@dataclass
class DateTime(Field):
value_type: datetime
default: datetime = datetime.utcfromtimestamp(0)
def serialize(self, value: value_type) -> str:
return (value - datetime.utcfromtimestamp(0)).total_seconds()
def deserialize(self, value: str, db: TinyDB, recurse: bool = False) -> value_type:
return datetime.utcfromtimestamp(int(value))
def before_insert(self, value: value_type, db: TinyDB, record: Record) -> None:
if not value:
record[self.name] = datetime.utcnow().replace(microsecond=0)
@dataclass
class Timestamp(DateTime):
value_type: datetime
def before_insert(self, value: value_type, db: TinyDB, record: Record) -> None:
super().before_insert(None, db, record)
@dataclass
class Password(Field):
value_type = str
@ -67,7 +92,7 @@ class Password(Field):
try:
if passwd[offset] != ":":
return False
digest = passwd[offset + 1 :]
digest = passwd[(offset + 1) :]
if len(digest) != cls.digest_size * 2:
return False
return re.match(r"^[0-9a-f]+$", digest)

View File

@ -1,4 +1,6 @@
from datetime import datetime
from pprint import pprint as print
from time import sleep
import pytest
from tinydb import Query
@ -133,3 +135,14 @@ def test_password(db):
assert check("fnord", user.password)
assert not check("wrong password", user.password)
assert not check("", user.password)
def test_datetime(db):
user = db.save(examples.User(name="john", email="john@foo", password="fnord", created=datetime.utcnow()))
assert user.created > datetime.utcfromtimestamp(0)
assert user.created < datetime.utcnow()
assert user.last_updated == user.created
sleep(1)
user = db.save(user)
assert user.last_updated >= user.created