openlp/openlp/core/lib/db.py

254 lines
8.7 KiB
Python
Raw Normal View History

2010-05-28 00:26:49 +00:00
# -*- coding: utf-8 -*-
# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
# Copyright (c) 2008-2010 Raoul Snyman #
# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael #
# Gorven, Scott Guerrieri, Christian Richter, Maikel Stuivenberg, Martin #
# Thompson, Jon Tibble, Carsten Tinggaard #
# --------------------------------------------------------------------------- #
# This program is free software; you can redistribute it and/or modify it #
# under the terms of the GNU General Public License as published by the Free #
# Software Foundation; version 2 of the License. #
# #
# This program is distributed in the hope that it will be useful, but WITHOUT #
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
# more details. #
# #
# You should have received a copy of the GNU General Public License along #
# with this program; if not, write to the Free Software Foundation, Inc., 59 #
# Temple Place, Suite 330, Boston, MA 02111-1307 USA #
###############################################################################
"""
The :mod:`db` module provides the core database functionality for OpenLP
"""
2010-06-12 23:00:14 +00:00
import logging
2010-06-18 01:26:01 +00:00
import os
2010-06-12 23:00:14 +00:00
from PyQt4 import QtCore
from sqlalchemy import create_engine, MetaData
2010-06-12 23:00:14 +00:00
from sqlalchemy.exceptions import InvalidRequestError
from sqlalchemy.orm import scoped_session, sessionmaker
2010-06-12 23:00:14 +00:00
from openlp.core.utils import AppLocation
log = logging.getLogger(__name__)
def init_db(url, auto_flush=True, auto_commit=False):
"""
Initialise and return the session and metadata for a database
``url``
The database to initialise connection with
``auto_flush``
Sets the flushing behaviour of the session
``auto_commit``
Sets the commit behaviour of the session
"""
engine = create_engine(url)
metadata = MetaData(bind=engine)
session = scoped_session(sessionmaker(autoflush=auto_flush,
autocommit=auto_commit, bind=engine))
return session, metadata
2010-05-28 00:26:49 +00:00
2010-06-18 01:26:01 +00:00
def delete_database(plugin_name, db_file_name=None):
"""
Remove a database file from the system.
``plugin_name``
The name of the plugin to remove the database for
``db_file_name``
The database file name. Defaults to None resulting in the
plugin_name being used.
"""
db_file_path = None
if db_file_name:
db_file_path = os.path.join(
AppLocation.get_section_data_path(plugin_name), db_file_name)
else:
db_file_path = os.path.join(
AppLocation.get_section_data_path(plugin_name), plugin_name)
try:
os.remove(db_file_path)
return True
except OSError:
return False
2010-05-28 00:26:49 +00:00
class BaseModel(object):
"""
BaseModel provides a base object with a set of generic functions
"""
@classmethod
def populate(cls, **kwargs):
"""
Creates an instance of a class and populates it, returning the instance
"""
me = cls()
2010-05-29 20:57:56 +00:00
for key in kwargs:
2010-05-28 00:26:49 +00:00
me.__setattr__(key, kwargs[key])
return me
2010-06-12 23:00:14 +00:00
class Manager(object):
"""
Provide generic object persistence management
"""
2010-06-15 00:44:06 +00:00
def __init__(self, plugin_name, init_schema, db_file_name=None):
2010-06-12 23:00:14 +00:00
"""
Runs the initialisation process that includes creating the connection
to the database and the tables if they don't exist.
``plugin_name``
The name to setup paths and settings section names
2010-06-15 00:44:06 +00:00
``init_schema``
The init_schema function for this database
``db_file_name``
The file name to use for this database. Defaults to None resulting
in the plugin_name being used.
2010-06-12 23:00:14 +00:00
"""
settings = QtCore.QSettings()
settings.beginGroup(plugin_name)
self.db_url = u''
db_type = unicode(
settings.value(u'db type', QtCore.QVariant(u'sqlite')).toString())
if db_type == u'sqlite':
2010-06-15 00:44:06 +00:00
if db_file_name:
self.db_url = u'sqlite:///%s/%s' % (
AppLocation.get_section_data_path(plugin_name),
db_file_name)
else:
self.db_url = u'sqlite:///%s/%s.sqlite' % (
AppLocation.get_section_data_path(plugin_name), plugin_name)
2010-06-12 23:00:14 +00:00
else:
self.db_url = u'%s://%s:%s@%s/%s' % (db_type,
unicode(settings.value(u'db username').toString()),
unicode(settings.value(u'db password').toString()),
unicode(settings.value(u'db hostname').toString()),
unicode(settings.value(u'db database').toString()))
settings.endGroup()
self.session = init_schema(self.db_url)
2010-06-28 13:38:29 +00:00
def save_object(self, object_instance):
2010-06-12 23:00:14 +00:00
"""
Save an object to the database
``object_instance``
The object to save
"""
try:
self.session.add(object_instance)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Object save failed')
return False
2010-06-18 01:26:01 +00:00
def get_object(self, object_class, key=None):
2010-06-12 23:00:14 +00:00
"""
Return the details of an object
``object_class``
The type of object to return
2010-06-18 01:26:01 +00:00
``key``
The unique reference or primary key for the instance to return
2010-06-12 23:00:14 +00:00
"""
2010-06-18 01:26:01 +00:00
if not key:
2010-06-12 23:00:14 +00:00
return object_class()
else:
2010-06-18 01:26:01 +00:00
return self.session.query(object_class).get(key)
2010-06-12 23:00:14 +00:00
2010-06-30 22:05:51 +00:00
def get_object_filtered(self, object_class, filter_clause):
2010-06-15 18:08:02 +00:00
"""
Returns an object matching specified criteria
``object_class``
The type of object to return
2010-06-30 22:05:51 +00:00
``filter_clause``
2010-06-15 18:08:02 +00:00
The criteria to select the object by
"""
2010-06-30 22:05:51 +00:00
return self.session.query(object_class).filter(filter_clause).first()
2010-06-15 18:08:02 +00:00
2010-06-12 23:00:14 +00:00
def get_all_objects(self, object_class, order_by_ref=None):
"""
Returns all the objects from the database
``object_class``
2010-06-15 02:08:22 +00:00
The type of objects to return
2010-06-12 23:00:14 +00:00
``order_by_ref``
Any parameters to order the returned objects by. Defaults to None.
"""
2010-07-01 10:31:37 +00:00
query = self.session.query(object_class)
2010-07-05 11:39:48 +00:00
if order_by_ref is not None:
2010-07-01 10:31:37 +00:00
return query.order_by(order_by_ref).all()
return query.all()
2010-06-12 23:00:14 +00:00
2010-06-30 22:05:51 +00:00
def get_all_objects_filtered(self, object_class, filter_clause,
order_by_ref=None):
2010-06-15 02:08:22 +00:00
"""
Returns a selection of objects from the database
``object_class``
The type of objects to return
2010-06-30 22:05:51 +00:00
``filter_clause``
2010-06-15 02:08:22 +00:00
The filter governing selection of objects to return
2010-06-30 22:05:51 +00:00
``order_by_ref``
Any parameters to order the returned objects by. Defaults to None.
2010-06-15 02:08:22 +00:00
"""
2010-07-01 10:31:37 +00:00
query = self.session.query(object_class).filter(filter_clause)
2010-07-05 11:39:48 +00:00
if order_by_ref is not None:
2010-07-01 10:31:37 +00:00
return query.order_by(order_by_ref).all()
return query.all()
2010-06-15 02:08:22 +00:00
2010-06-18 01:26:01 +00:00
def delete_object(self, object_class, key):
2010-06-12 23:00:14 +00:00
"""
Delete an object from the database
``object_class``
The type of object to delete
2010-06-18 01:26:01 +00:00
``key``
The unique reference or primary key for the instance to be deleted
2010-06-12 23:00:14 +00:00
"""
2010-06-18 01:26:01 +00:00
if key != 0:
object_instance = self.get_object(object_class, key)
2010-06-12 23:00:14 +00:00
try:
2010-06-18 01:26:01 +00:00
self.session.delete(object_instance)
2010-06-12 23:00:14 +00:00
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete object')
return False
else:
return True
def delete_all_objects(self, object_class):
"""
Delete all object records
``object_class``
The type of object to delete
"""
try:
self.session.query(object_class).delete(synchronize_session=False)
self.session.commit()
return True
except InvalidRequestError:
self.session.rollback()
log.exception(u'Failed to delete all %s records',
object_class.__name__)
return False