Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Updated morglib.database documentation. |
|---|---|
| Timelines: | family | ancestors | descendants | both | dev |
| Files: | files | file ages | folders |
| SHA1: |
f2db9284504411616c4627609ae534f4 |
| User & Date: | mvnathan 2014-09-18 21:07:15.581 |
Context
|
2014-09-18
| ||
| 21:13 | Use between operator for numeric property range constraints instead of the relational operators. check-in: 0caa6b62ab user: mvnathan tags: dev | |
| 21:07 | Updated morglib.database documentation. check-in: f2db928450 user: mvnathan tags: dev | |
| 06:29 | Implemented database sanity check. check-in: 4c162d2c43 user: mvnathan tags: dev | |
Changes
Changes to py/morglib/database.py.
| ︙ | ︙ | |||
102 103 104 105 106 107 108 |
@param reason (any) Additional information about connection failure.
Typically, reason will be a string explaining the problem with
the tasks file. However, this parameter can be any object and
will, via the base class constructor, be converted to a string.
'''
| | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
@param reason (any) Additional information about connection failure.
Typically, reason will be a string explaining the problem with
the tasks file. However, this parameter can be any object and
will, via the base class constructor, be converted to a string.
'''
msg = 'cannot use database {}'.format(tasks_file)
database_error.__init__(self, msg, reason)
class sql_error(database_error):
'''For reporting inability to execute SQL queries.'''
def __init__(self, query, reason = None):
'''Construct SQL error.
|
| ︙ | ︙ | |||
147 148 149 150 151 152 153 |
msg = ('property error: name = "{}", type = {}, range = {}'.
format(n, t, r))
database_error.__init__(self, msg, e)
#--------------------------- TASKS DATABASE -----------------------------
class database:
| | > > > > > > > > > > > | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 |
msg = ('property error: name = "{}", type = {}, range = {}'.
format(n, t, r))
database_error.__init__(self, msg, e)
#--------------------------- TASKS DATABASE -----------------------------
class database:
'''Encapsulation of interface to Morg tasks database.
This class provides clients a high-level API for dealing with the
Morg database. With it, you can add and remove tasks and properties
and even execute arbitrary SQL queries.
The Morg application instantiates this class early on and then passes
that object to all <tt>morglib.command</tt> instances to allow them
to easily implement their respective functionalities by manipulating
the Morg database as required.
'''
# Substantial changes to the structure of the Morg database should be
# accompanied by increments to the following version number.
SCHEMA_VERSION = 1
# Hard-coded string to help identify whether an SQLite file is a Morg
# database or not.
|
| ︙ | ︙ | |||
173 174 175 176 177 178 179 |
creating the entire directory hierarchy specified in the
tasks_file parameter).
Failure to open the SQLite file will result in a connection_error
exception.
Once the database has been successfully opened, the constructor
| | > > | > > > > > | > > > > | > > > > > > > > > > > > > > > > > > > > > > > | | | | > > | > < < | 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 |
creating the entire directory hierarchy specified in the
tasks_file parameter).
Failure to open the SQLite file will result in a connection_error
exception.
Once the database has been successfully opened, the constructor
will proceed to check if the database is empty or not. In an
empty database, Morg will create a watermark table so that it can
subsequently identify that SQLite file as one that it can use.
Failure to create the watermark table will usually lead to a
sql_error. However, to populate the watermark table, Morg uses
the current time, host name, user name, and an SHA-1 hex string.
Thus, depending on exactly which of these steps fails, some other
exception may also be raised. (Though that should be quite rare.)
If the database is not empty, Morg will perform a sanity check
using the watermark table to see if the database to which it is
connected was its creation and, therefore, usable by it. If that
is not the case, the constructor will raise a sanity_check_error.
Please note that the watermark system Morg uses is not foolproof.
You can easily enough insert and populate such a table in an
arbitrary SQLite file and trick Morg into using that file as its
database. Alternatively, you can remove the watermark table from
an actual Morg database and prevent Morg from using that.
However, it requires a small amount of effort to manually mangle
SQLite files in this way and the payoff, at least in this case,
is pretty much non-existent. Thus, the purpose of the watermark
is simply to record some metadata and to assure Morg that the
SQLite file it is using is most likely a valid Morg database
rather than to enforce some strict, tamperproof barrier that
prevents intentional or unintentional cross-application data
pollution.
After the watermark creation or verification phase, the
constructor proceeds to creating the basic database structure
required by Morg. At the very least, Morg needs a <tt>task</tt>
table to record all your tasks as well as several property tables
that define and record the various properties associated with
tasks. Preexisting task and property tables will be left
untouched.
However, the database constructor allows you to define new
properties during initialization. These initial properties are
specified via the properties parameter, which is a dict that maps
strings to 2-tuples. The key is the name of a property. The
2-tuple corresponding to the property name contains the property
type and its range.
The property type can be one of the following (case-insensitive)
strings:
@li <tt>integer</tt>
@li <tt>real</tt>
@li <tt>text</tt>
The property range may be either <tt>None</tt> or a string
describing the range of values that particular property may take
on. Commas can be used to separate items in a list of discrete
values. Double dots can be used for numeric ranges. Here are a
few illustrative examples:
@verbatim
|
| ︙ | ︙ |
Changes to wiki/todo.wiki.
| ︙ | ︙ | |||
14 15 16 17 18 19 20 21 22 23 | * Instantiate database object in <tt>main()</tt>. * Create <tt>morg</tt> table on database init. * Create <tt>task</tt> table on database init. * Create <tt>property</tt> table on database init. * Add default properties dict. * Create <tt>property_NNN</tt> tables on database init. * Implement sanity check on database initialization. <h2>PENDING</h2> | > | > > | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | * Instantiate database object in <tt>main()</tt>. * Create <tt>morg</tt> table on database init. * Create <tt>task</tt> table on database init. * Create <tt>property</tt> table on database init. * Add default properties dict. * Create <tt>property_NNN</tt> tables on database init. * Implement sanity check on database initialization. * Update database constructor doc string. <h2>PENDING</h2> * Use the BETWEEN operator in property range constraints. * Implement a watermark class to ease verification and "Morgification." * The watermark table should be created and populated in a transaction. * Pass database to all commands' <tt>__call__</tt> method. * Implement <tt>new</tt> command. |