class LogEntry(db.Model): __tablename__ = 'log_entries' id = db.Column(db.Integer, primary_key=True) who = db.Column(db.String(256)) what = db.Column(db.String(256)) obj = db.Column(db.String(256)) when = db.Column(db.DateTime(), default=text('NOW()')) def __repr__(self): return ' '.join([self.who, self.what, self.obj])
class Book(Document): """ Book document type. These could be checked out for 2 weeks, if they are bestsellers. Otherwise, students check out these for 3 weeks, and faculty members check out these for 4 weeks. """ __tablename__ = 'books' id = db.Column(db.Integer, db.ForeignKey('documents.id'), primary_key=True) """ Integer primary foreign key to documents. """ edition = db.Column(db.Integer) """ Book edition. """ publishment_year = db.Column(db.Integer) """ Publishment year. """ bestseller = db.Column(db.Boolean, default=False) """ Whether this book is a bestseller. """ publisher = db.Column(db.String(80)) """ Relation with publisher. """ reference = db.Column(db.Boolean, default=False) """ Whether this book is a reference book""" __mapper_args__ = {'polymorphic_identity': 'book'}
class User(db.Model, Searchable): """ Base class for all users in the system. Should not be directly instantiated. (`hexagonal.auth` currently does that, but i'm working on it) """ __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) """ Integer primary key. """ login = db.Column(db.String(80), unique=True, index=True, nullable=False) """ Login of the user. Must be unique. """ password = db.Column(db.String(128), nullable=False) """ Password hash of the user. """ reset_password = db.Column(db.Boolean, default=False) """ Reset password flag. If true, on next login user would be prompted to reset the password. """ role = db.Column(db.String(20), index=True, nullable=False) """ Polymorphic identity of the user. Used to implement inheritance. """ name = db.Column(db.String(80), index=True, nullable=False) """ User's full name. """ address = db.Column(db.String(80), nullable=False) """ User's full address. """ phone = db.Column(db.String(80), nullable=False) """ User's phone number. """ card_number = db.Column(db.String(80), nullable=False) """ User's library card number. """ queued_requests = db.relationship('QueuedRequest', back_populates='patron') queued_documents = association_proxy('queued_requests', 'document') __mapper_args__ = { 'polymorphic_on': role, 'polymorphic_identity': 'user' } permissions = [] fuzzy_search_fields = ['name', 'address', 'phone'] def has_permission(self, permission): """ Whether this user has the required permission. By default returns whether permission is present in the class static field `permissions`. :param permission: permission to be checked. :return: whether the current user has the required permission. """ return permission in self.permissions
class JournalArticle(Document): """ Journal article type of document. These could be checked out for two weeks by anyone. """ __tablename__ = 'journal_articles' id = db.Column(db.Integer, db.ForeignKey('documents.id'), primary_key=True) """ Integer primary key. """ issue_editor = db.Column(db.String(80)) """ Editor of the issue. """ issue_publication_date = db.Column(db.Date) """ Publication date of the issue. """ journal = db.Column(db.String(80)) """ Journal. """ __mapper_args__ = {'polymorphic_identity': 'journal_article'}
class DocumentCopy(db.Model): """ Copy of a document. References a specific document and document type by foreign key. """ __tablename__ = 'document_copies' id = db.Column(db.Integer, primary_key=True) """ Integer primary key. """ document_id = db.Column(db.Integer, db.ForeignKey('documents.id')) """ Foreign key to documents. """ document = db.relationship('Document', back_populates='copies') """ Associated document. """ location = db.Column(db.String(200)) """ Location of the copy in the physical library. """ loan = db.relationship('Loan', back_populates='document_copy', uselist=False) """ Relation to current loan. May be None when document is available. """
class Document(db.Model, Searchable): """ Base class for all documents. Should not be instantiated directly. Contains common fields for all documents, and inherits from :py:class:`hexagonal.model.searchable.Searchable`, adding search capability. Fuzzy search fields are `title` and `type`. Fuzzy array search fields are `keywords` and `authors`. """ __tablename__ = 'documents' id = db.Column(db.Integer, primary_key=True) """ Integer primary key (referenced from subclasses) """ title = db.Column(db.String(80), unique=True, index=True, nullable=False) """ Document title (exists for all types) """ price = db.Column(db.Integer, nullable=False, default=0) """ Document price (used in calculating overdue fine) """ copies = db.relationship('DocumentCopy', back_populates='document', cascade='all, delete-orphan') """ Relation with copies of this document. """ keywords = db.Column(db.ARRAY(db.String(80))) """ Relation with keywords. """ authors = db.Column(db.ARRAY(db.String(80))) """ Authors of this document. """ type = db.Column(db.String(20), nullable=False) """ Polymorphic identity column for inheritance support. """ queued_requests = db.relationship('QueuedRequest', back_populates='document') awaiting_patrons = association_proxy('queued_requests', 'patron') outstanding = db.Column(db.Boolean, default=False) __mapper_args__ = { 'polymorphic_on': type, 'polymorphic_identity': 'document' } fuzzy_search_fields = ['title', 'type'] fuzzy_array_search_fields = ['keywords', 'authors'] @hybrid_property def available_copies(self): """ Hybrid property for currently available copies of this document. Available copies are copies which don't have an associated loan. """ return DocumentCopy.query.filter( DocumentCopy.document == self, DocumentCopy.loan == None ).all() def outstanding_request(self): from hexagonal.model.loan import Loan import datetime self.outstanding = True db.session.add(self) for qr in self.queued_requests: db.session.delete(qr) loans = Loan.query.filter(Loan.document == self).all() for loan in loans: db.session.add(loan) loan.due_date = datetime.date.today() db.session.commit()