]>
git.ipfire.org Git - oddments/ddns.git/blob - src/ddns/database.py
2 ###############################################################################
4 # ddns - A dynamic DNS client for IPFire #
5 # Copyright (C) 2014 IPFire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
26 # Initialize the logger.
28 logger
= logging
.getLogger("ddns.database")
31 class DDNSDatabase(object):
32 def __init__(self
, core
, path
):
36 # We won't open the connection to the database directly
37 # so that we do not do it unnecessarily.
40 def _open_database(self
, path
):
41 logger
.debug("Opening database %s" % path
)
43 exists
= os
.path
.exists(path
)
45 conn
= sqlite3
.connect(path
, detect_types
=sqlite3
.PARSE_DECLTYPES|sqlite3
.PARSE_COLNAMES
)
46 conn
.isolation_level
= None
48 if not exists
and self
.is_writable():
49 logger
.debug("Initialising database layout")
52 CREATE TABLE updates (
53 hostname TEXT NOT NULL,
56 timestamp timestamp NOT NULL
59 CREATE TABLE settings (
64 CREATE INDEX idx_updates_hostname ON updates(hostname);
66 c
.execute("INSERT INTO settings(k, v) VALUES(?, ?)", ("version", "1"))
70 def is_writable(self
):
71 # Check if the database file exists and is writable.
72 ret
= os
.access(self
.path
, os
.W_OK
)
76 # If not, we check if we are able to write to the directory.
77 # In that case the database file will be created in _open_database().
78 return os
.access(os
.path
.dirname(self
.path
), os
.W_OK
)
80 def _execute(self
, query
, *parameters
):
82 self
._db
= self
._open
_database
(self
.path
)
86 c
.execute(query
, parameters
)
90 def add_update(self
, hostname
, status
, message
=None):
91 if not self
.is_writable():
92 logger
.warning("Could not log any updates because the database is not writable")
95 self
._execute
("INSERT INTO updates(hostname, status, message, timestamp) \
96 VALUES(?, ?, ?, ?)", hostname
, status
, message
, datetime
.datetime
.utcnow())
98 def log_success(self
, hostname
):
99 logger
.debug("Logging successful update for %s" % hostname
)
101 return self
.add_update(hostname
, "success")
103 def log_failure(self
, hostname
, exception
):
105 message
= "%s: %s" % (exception
.__class
__.__name
__, exception
.reason
)
109 logger
.debug("Logging failed update for %s: %s" % (hostname
, message
or ""))
111 return self
.add_update(hostname
, "failure", message
=message
)
113 def last_update(self
, hostname
, status
=None):
115 Returns the timestamp of the last update (with the given status code).
118 self
._db
= self
._open
_database
(self
.path
)
120 c
= self
._db
.cursor()
124 c
.execute("SELECT timestamp FROM updates WHERE hostname = ? AND status = ? \
125 ORDER BY timestamp DESC LIMIT 1", (hostname
, status
))
127 c
.execute("SELECT timestamp FROM updates WHERE hostname = ? \
128 ORDER BY timestamp DESC LIMIT 1", (hostname
,))
135 def last_update_status(self
, hostname
):
137 Returns the update status of the last update.
140 self
._db
= self
._open
_database
(self
.path
)
142 c
= self
._db
.cursor()
145 c
.execute("SELECT status FROM updates WHERE hostname = ? \
146 ORDER BY timestamp DESC LIMIT 1", (hostname
,))
153 def last_update_failure_message(self
, hostname
):
155 Returns the reason string for the last failed update (if any).
158 self
._db
= self
._open
_database
(self
.path
)
160 c
= self
._db
.cursor()
163 c
.execute("SELECT message FROM updates WHERE hostname = ? AND status = ? \
164 ORDER BY timestamp DESC LIMIT 1", (hostname
, "failure"))