openlp/openlp/plugins/songs/lib/db.py

261 lines
8.9 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
2013-01-06 17:25:49 +00:00
# vim: autoindent shiftwidth=4 expandtab textwidth=120 tabstop=4 softtabstop=4
###############################################################################
# OpenLP - Open Source Lyrics Projection #
# --------------------------------------------------------------------------- #
2012-12-29 20:56:56 +00:00
# Copyright (c) 2008-2013 Raoul Snyman #
# Portions copyright (c) 2008-2013 Tim Bentley, Gerald Britton, Jonathan #
# Corwin, Samuel Findlay, Michael Gorven, Scott Guerrieri, Matthias Hub, #
2012-11-11 21:16:14 +00:00
# Meinert Jordan, Armin Köhler, Erik Lundin, Edwin Lunando, Brian T. Meyer. #
2012-10-21 13:16:22 +00:00
# Joshua Miller, Stevan Pettit, Andreas Preikschat, Mattias Põldaru, #
# Christian Richter, Philip Ridout, Simon Scudder, Jeffrey Smith, #
# Maikel Stuivenberg, Martin Thompson, Jon Tibble, Dave Warnock, #
# Frode Woldsund, Martin Zibricky, Patrick Zimmermann #
# --------------------------------------------------------------------------- #
# 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 database and schema that is the backend for
the Songs plugin
"""
2012-10-16 15:23:37 +00:00
import re
2011-07-07 18:03:12 +00:00
from sqlalchemy import Column, ForeignKey, Table, types
from sqlalchemy.orm import mapper, relation, reconstructor
2011-08-26 12:02:06 +00:00
from sqlalchemy.sql.expression import func
from openlp.core.lib.db import BaseModel, init_db
from openlp.core.utils import get_natural_key
2012-11-08 21:28:42 +00:00
class Author(BaseModel):
"""
Author model
"""
pass
2011-01-18 16:42:59 +00:00
class Book(BaseModel):
"""
Book model
"""
def __repr__(self):
2013-01-06 17:25:49 +00:00
return u'<Book id="%s" name="%s" publisher="%s" />' % (str(self.id), self.name, self.publisher)
2011-01-18 16:42:59 +00:00
2010-07-20 12:43:21 +00:00
class MediaFile(BaseModel):
"""
MediaFile model
"""
pass
2011-01-18 16:42:59 +00:00
class Song(BaseModel):
"""
Song model
"""
def __init__(self):
2012-11-08 21:28:42 +00:00
self.sort_key = ()
@reconstructor
def init_on_load(self):
"""
Precompute a natural sorting, locale aware sorting key.
Song sorting is performance sensitive operation.
To get maximum speed lets precompute the sorting key.
"""
self.sort_key = get_natural_key(self.title)
2011-01-18 16:42:59 +00:00
class Topic(BaseModel):
"""
Topic model
"""
pass
def init_schema(url):
"""
2011-01-18 16:42:59 +00:00
Setup the songs database connection and initialise the database schema.
``url``
The database to setup
2011-01-14 17:33:48 +00:00
2011-01-18 16:42:59 +00:00
The song database contains the following tables:
2011-02-03 17:11:41 +00:00
2011-01-14 17:33:48 +00:00
* authors
* authors_songs
* media_files
* media_files_songs
* song_books
* songs
* songs_topics
* topics
2011-02-03 17:11:41 +00:00
**authors** Table
2011-01-14 17:33:48 +00:00
This table holds the names of all the authors. It has the following
columns:
2011-02-03 17:11:41 +00:00
* id
* first_name
* last_name
* display_name
**authors_songs Table**
2011-01-18 16:42:59 +00:00
This is a bridging table between the *authors* and *songs* tables, which
2011-01-14 17:33:48 +00:00
serves to create a many-to-many relationship between the two tables. It
has the following columns:
2011-02-03 17:11:41 +00:00
* author_id
* song_id
**media_files Table**
* id
* file_name
* type
**song_books Table**
2011-01-18 16:42:59 +00:00
The *song_books* table holds a list of books that a congregation gets
2011-01-14 17:33:48 +00:00
their songs from, or old hymnals now no longer used. This table has the
following columns:
2011-02-03 17:11:41 +00:00
* id
* name
* publisher
**songs Table**
2011-01-14 17:33:48 +00:00
This table contains the songs, and each song has a list of attributes.
2011-01-18 16:42:59 +00:00
The *songs* table has the following columns:
2011-02-03 17:11:41 +00:00
* id
* song_book_id
* title
* alternate_title
* lyrics
* verse_order
* copyright
* comments
* ccli_number
* song_number
* theme_name
* search_title
* search_lyrics
**songs_topics Table**
2011-01-18 16:42:59 +00:00
This is a bridging table between the *songs* and *topics* tables, which
2011-01-14 17:33:48 +00:00
serves to create a many-to-many relationship between the two tables. It
has the following columns:
2011-02-03 17:11:41 +00:00
* song_id
* topic_id
**topics Table**
2011-01-14 17:33:48 +00:00
The topics table holds a selection of topics that songs can cover. This
is useful when a worship leader wants to select songs with a certain
theme. This table has the following columns:
2011-02-03 17:11:41 +00:00
* id
* name
"""
session, metadata = init_db(url)
# Definition of the "authors" table
authors_table = Table(u'authors', metadata,
2011-08-25 09:02:59 +00:00
Column(u'id', types.Integer(), primary_key=True),
Column(u'first_name', types.Unicode(128)),
Column(u'last_name', types.Unicode(128)),
Column(u'display_name', types.Unicode(255), index=True, nullable=False)
)
2010-07-20 12:43:21 +00:00
# Definition of the "media_files" table
media_files_table = Table(u'media_files', metadata,
2011-08-25 09:02:59 +00:00
Column(u'id', types.Integer(), primary_key=True),
Column(u'song_id', types.Integer(), ForeignKey(u'songs.id'),
default=None),
2010-07-20 12:43:21 +00:00
Column(u'file_name', types.Unicode(255), nullable=False),
2011-08-25 09:02:59 +00:00
Column(u'type', types.Unicode(64), nullable=False, default=u'audio'),
Column(u'weight', types.Integer(), default=0)
2010-07-20 12:43:21 +00:00
)
# Definition of the "song_books" table
song_books_table = Table(u'song_books', metadata,
2011-08-25 09:02:59 +00:00
Column(u'id', types.Integer(), primary_key=True),
Column(u'name', types.Unicode(128), nullable=False),
Column(u'publisher', types.Unicode(128))
)
# Definition of the "songs" table
songs_table = Table(u'songs', metadata,
2011-08-25 09:02:59 +00:00
Column(u'id', types.Integer(), primary_key=True),
Column(u'song_book_id', types.Integer(),
ForeignKey(u'song_books.id'), default=None),
Column(u'title', types.Unicode(255), nullable=False),
2010-07-17 17:36:03 +00:00
Column(u'alternate_title', types.Unicode(255)),
Column(u'lyrics', types.UnicodeText, nullable=False),
Column(u'verse_order', types.Unicode(128)),
Column(u'copyright', types.Unicode(255)),
Column(u'comments', types.UnicodeText),
Column(u'ccli_number', types.Unicode(64)),
Column(u'song_number', types.Unicode(64)),
Column(u'theme_name', types.Unicode(128)),
Column(u'search_title', types.Unicode(255), index=True, nullable=False),
2011-08-26 12:02:06 +00:00
Column(u'search_lyrics', types.UnicodeText, nullable=False),
Column(u'create_date', types.DateTime(), default=func.now()),
2011-08-26 13:13:32 +00:00
Column(u'last_modified', types.DateTime(), default=func.now(),
2011-12-03 09:05:01 +00:00
onupdate=func.now()),
2011-12-03 19:08:02 +00:00
Column(u'temporary', types.Boolean(), default=False)
)
# Definition of the "topics" table
topics_table = Table(u'topics', metadata,
2011-08-25 09:02:59 +00:00
Column(u'id', types.Integer(), primary_key=True),
Column(u'name', types.Unicode(128), index=True, nullable=False)
)
# Definition of the "authors_songs" table
authors_songs_table = Table(u'authors_songs', metadata,
2011-08-25 09:02:59 +00:00
Column(u'author_id', types.Integer(),
ForeignKey(u'authors.id'), primary_key=True),
2011-08-25 09:02:59 +00:00
Column(u'song_id', types.Integer(),
2010-07-20 12:43:21 +00:00
ForeignKey(u'songs.id'), primary_key=True)
)
# Definition of the "songs_topics" table
songs_topics_table = Table(u'songs_topics', metadata,
2011-08-25 09:02:59 +00:00
Column(u'song_id', types.Integer(),
ForeignKey(u'songs.id'), primary_key=True),
2011-08-25 09:02:59 +00:00
Column(u'topic_id', types.Integer(),
ForeignKey(u'topics.id'), primary_key=True)
)
mapper(Author, authors_table)
mapper(Book, song_books_table)
2010-07-20 12:43:21 +00:00
mapper(MediaFile, media_files_table)
mapper(Song, songs_table,
2010-07-19 12:18:56 +00:00
properties={
'authors': relation(Author, backref='songs',
2011-03-11 18:03:16 +00:00
secondary=authors_songs_table, lazy=False),
'book': relation(Book, backref='songs'),
'media_files': relation(MediaFile, backref='songs',
order_by=media_files_table.c.weight),
'topics': relation(Topic, backref='songs',
2010-07-19 12:18:56 +00:00
secondary=songs_topics_table)
})
mapper(Topic, topics_table)
2010-06-12 02:14:18 +00:00
metadata.create_all(checkfirst=True)
2011-01-14 17:33:48 +00:00
return session