]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/magicfolderdb.py
982b5fe298f8b02f52182d6b608b292d8bbdccf1
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / magicfolderdb.py
1
2 import sys
3 from collections import namedtuple
4
5 from allmydata.util.dbutil import get_db, DBError
6
7
8 # magic-folder db schema version 1
9 SCHEMA_v1 = """
10 CREATE TABLE version
11 (
12  version INTEGER  -- contains one row, set to 1
13 );
14
15 CREATE TABLE local_files
16 (
17  path                VARCHAR(1024) PRIMARY KEY, -- UTF-8 filename relative to local magic folder dir
18  -- note that size is before mtime and ctime here, but after in function parameters
19  size                INTEGER,                   -- ST_SIZE, or NULL if the file has been deleted
20  mtime               NUMBER,                      -- ST_MTIME
21  ctime               NUMBER,                      -- ST_CTIME
22  version             INTEGER,
23  last_uploaded_uri   VARCHAR(256),                -- URI:CHK:...
24  last_downloaded_uri VARCHAR(256),                -- URI:CHK:...
25  last_downloaded_timestamp TIMESTAMP
26 );
27 """
28
29
30 def get_magicfolderdb(dbfile, stderr=sys.stderr,
31                       create_version=(SCHEMA_v1, 1), just_create=False):
32     # Open or create the given backupdb file. The parent directory must
33     # exist.
34     try:
35         (sqlite3, db) = get_db(dbfile, stderr, create_version,
36                                just_create=just_create, dbname="magicfolderdb")
37         if create_version[1] in (1, 2):
38             return MagicFolderDB(sqlite3, db)
39         else:
40             print >>stderr, "invalid magicfolderdb schema version specified"
41             return None
42     except DBError, e:
43         print >>stderr, e
44         return None
45
46 PathEntry = namedtuple('PathEntry', 'size mtime ctime version last_uploaded_uri last_downloaded_uri last_downloaded_timestamp')
47
48 class MagicFolderDB(object):
49     VERSION = 1
50
51     def __init__(self, sqlite_module, connection):
52         self.sqlite_module = sqlite_module
53         self.connection = connection
54         self.cursor = connection.cursor()
55
56     def get_db_entry(self, relpath_u):
57         """
58         Retrieve the entry in the database for a given path, or return None
59         if there is no such entry.
60         """
61         c = self.cursor
62         c.execute("SELECT size, mtime, ctime, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp"
63                   " FROM local_files"
64                   " WHERE path=?",
65                   (relpath_u,))
66         row = self.cursor.fetchone()
67         if not row:
68             return None
69         else:
70             (size, mtime, ctime, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp) = row
71             return PathEntry(size=size, mtime=mtime, ctime=ctime, version=version,
72                              last_uploaded_uri=last_uploaded_uri,
73                              last_downloaded_uri=last_downloaded_uri,
74                              last_downloaded_timestamp=last_downloaded_timestamp)
75
76     def get_all_relpaths(self):
77         """
78         Retrieve a set of all relpaths of files that have had an entry in magic folder db
79         (i.e. that have been downloaded at least once).
80         """
81         self.cursor.execute("SELECT path FROM local_files")
82         rows = self.cursor.fetchall()
83         return set([r[0] for r in rows])
84
85     def did_upload_version(self, relpath_u, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp, pathinfo):
86         print "%r.did_upload_version(%r, %r, %r, %r, %r, %r)" % (self, relpath_u, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp, pathinfo)
87         try:
88             print "insert"
89             self.cursor.execute("INSERT INTO local_files VALUES (?,?,?,?,?,?,?,?)",
90                                 (relpath_u, pathinfo.size, pathinfo.mtime, pathinfo.ctime, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp))
91         except (self.sqlite_module.IntegrityError, self.sqlite_module.OperationalError):
92             print "err... update"
93             self.cursor.execute("UPDATE local_files"
94                                 " SET size=?, mtime=?, ctime=?, version=?, last_uploaded_uri=?, last_downloaded_uri=?, last_downloaded_timestamp=?"
95                                 " WHERE path=?",
96                                 (pathinfo.size, pathinfo.mtime, pathinfo.ctime, version, last_uploaded_uri, last_downloaded_uri, last_downloaded_timestamp, relpath_u))
97         self.connection.commit()
98         print "committed"