Associate an Eliot action with magicfolder database updates

This commit is contained in:
Jean-Paul Calderone 2019-02-18 11:47:24 -05:00
parent a1491dc0e1
commit 714a7de84a

View File

@ -4,6 +4,86 @@ from collections import namedtuple
from allmydata.util.dbutil import get_db, DBError
from eliot._validation import (
ValidationError,
)
from eliot import (
Field,
ActionType,
)
def _validateInstanceOf(t):
"""
Return an Eliot validator that requires values to be instances of ``t``.
"""
def validator(v):
if not isinstance(v, t):
raise ValidationError("{} not an instance of {}".format(v, t))
return validator
def _validateSetMembership(s):
"""
Return an Eliot validator that requires values to be elements of ``s``.
"""
def validator(v):
if v not in s:
raise ValidationError("{} not in {}".format(v, s))
return validator
PathEntry = namedtuple('PathEntry', 'size mtime_ns ctime_ns version last_uploaded_uri '
'last_downloaded_uri last_downloaded_timestamp')
_RELPATH = Field.for_types(
u"relpath",
[unicode],
u"The relative path of a file in a magic-folder.",
)
_VERSION = Field.for_types(
u"version",
[int, long],
u"The version of the file.",
)
_UPLOADED_URI = Field.for_types(
u"last-uploaded-uri",
[unicode],
u"The filecap to which this version of this file was uploaded.",
)
_DOWNLOADED_URI = Field.for_types(
u"last-downloaded-uri",
[unicode],
u"The filecap from which the previous version of this file was downloaded.",
)
_DOWNLOADED_TIMESTAMP = Field.for_types(
u"last-downloaded-timestamp",
[unicode],
u"(XXX probably not really, don't trust this) The timestamp of the last download of this file.",
)
_PATHINFO = Field(
u"pathinfo",
lambda v: tuple(v),
u"The metadata for this version of this file.",
_validateInstanceOf(PathEntry),
)
_INSERT_OR_UPDATE = Field.for_types(
u"inserted-or-updated",
[unicode],
u"An indication of whether the record for this upload was new or an update to a previous entry.",
_validateSetMembership({u"insert", u"update"}),
)
DID_UPLOAD_VERSION = ActionType(
u"magic-folder-db:did-upload-version",
[_RELPATH, _VERSION, _UPLOADED_URI, _DOWNLOADED_URI, _DOWNLOADED_TIMESTAMP, _PATHINFO],
[_INSERT_OR_UPDATE],
u"An file upload is being recorded in the database.",
)
# magic-folder db schema version 1
SCHEMA_v1 = """
@ -42,9 +122,6 @@ def get_magicfolderdb(dbfile, stderr=sys.stderr,
print >>stderr, e
return None
PathEntry = namedtuple('PathEntry', 'size mtime_ns ctime_ns version last_uploaded_uri '
'last_downloaded_uri last_downloaded_timestamp')
class MagicFolderDB(object):
VERSION = 1
@ -88,17 +165,28 @@ class MagicFolderDB(object):
return set([r[0] for r in rows])
def did_upload_version(self, relpath_u, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp, pathinfo):
try:
self.cursor.execute("INSERT INTO local_files VALUES (?,?,?,?,?,?,?,?)",
(relpath_u, pathinfo.size, pathinfo.mtime_ns, pathinfo.ctime_ns,
version, last_uploaded_uri, last_downloaded_uri,
last_downloaded_timestamp))
except (self.sqlite_module.IntegrityError, self.sqlite_module.OperationalError):
self.cursor.execute("UPDATE local_files"
" SET size=?, mtime_ns=?, ctime_ns=?, version=?, last_uploaded_uri=?,"
" last_downloaded_uri=?, last_downloaded_timestamp=?"
" WHERE path=?",
(pathinfo.size, pathinfo.mtime_ns, pathinfo.ctime_ns, version,
last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp,
relpath_u))
self.connection.commit()
action = DID_UPLOAD_VERSION(
relpath=relpath_u,
version=version,
uploaded_uri=last_uploaded_uri,
downloaded_uri=last_downloaded_uri,
downloaded_timestamp=last_downloaded_timestamp,
pathinfo=pathinfo,
)
with action:
try:
self.cursor.execute("INSERT INTO local_files VALUES (?,?,?,?,?,?,?,?)",
(relpath_u, pathinfo.size, pathinfo.mtime_ns, pathinfo.ctime_ns,
version, last_uploaded_uri, last_downloaded_uri,
last_downloaded_timestamp))
action.add_success_fields(insert_or_update=u"insert")
except (self.sqlite_module.IntegrityError, self.sqlite_module.OperationalError):
self.cursor.execute("UPDATE local_files"
" SET size=?, mtime_ns=?, ctime_ns=?, version=?, last_uploaded_uri=?,"
" last_downloaded_uri=?, last_downloaded_timestamp=?"
" WHERE path=?",
(pathinfo.size, pathinfo.mtime_ns, pathinfo.ctime_ns, version,
last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp,
relpath_u))
action.add_success_fields(inserted_or_updated=u"update")
self.connection.commit()