class CRUDMixin(object):
class Model(CRUDMixin, db.Model):
class SurrogatePK(object):
    def create(cls, **kwargs):
    def update(self, commit=True, **kwargs):
    def save(self, commit=True):
    def delete(self, commit=True):
    def get_by_id(cls, id):
def ReferenceCol(tablename, nullable=False, ondelete=None, pk_name='id', **kwargs): class TemplateBase(Model):
    '''
    Basic metadata about a template

    Fields:
    - created_at: when the template was created
    - updated_at: when the template metadata was last updated
    - title: the displayed title or name of the template
    - description: a freetext description of the template
    '''

    __tablename__ = 'template_base'
    id = Column(db.Integer, primary_key=True)
    created_at = Column(db.DateTime)
    updated_at = Column(db.DateTime)
    title = Column(db.String(255))
    description = Column(db.Text)
    template_text = db.relationship('TemplateSection', cascade='all,delete', lazy='dynamic')
    template_placeholders = db.relationship('TemplatePlaceholders', cascade='all,delete', lazy='dynamic')
    published = Column(db.Boolean, default=False)
    section_order = Column(ARRAY(db.Integer))
    # created_by = ReferenceCol('users')

    def __init__(self, created_at, updated_at, title, description):
        self.created_at = created_at
        self.updated_at = updated_at
        self.title = title
        self.description = description class TemplateSection(Model):
    '''
    TemplateSection is a superclass of section information and maps to section types

    Fields:
    - title: The name of the section
    - description: The description of the section
    - position: Where in the template the section lies
    - template_id: Foreign Key relationship back to the TemplateBase
    - section_type: The type of section to be used. This uses "joined
    table inheritance": http://docs.sqlalchemy.org/en/rel_0_9/orm/inheritance.html
    '''

    __tablename__ = 'template_section'
    id = Column(db.Integer, primary_key=True)
    title = Column(db.String(255))
    description = Column(db.Text)
    template_id = ReferenceCol('template_base')
    template_placeholders = db.relationship('TemplatePlaceholders', cascade='all,delete', lazy='dynamic')
    section_type = Column('section_type', db.String(50))
    __mapper_args__ = {'polymorphic_on': section_type}

    def __init__(self, template_id=None, title=None, description=None):
        self.template_id = template_id
        self.title = title
        self.description = description class TextSection(TemplateSection):
    '''
    TextSection is a class of TemplateSection; it supports large text input with
    placeholder interpolation

    Fields:
    - id: 1:1 Relationship from TemplateSection
    - text: Text of the section
    '''
    __tablename__ = 'text_section'
    section_id = Column(db.Integer, db.ForeignKey('template_section.id'), primary_key=True)
    __mapper_args__ = {
        'polymorphic_identity': 'text',
        'inherit_condition': (section_id == TemplateSection.id)
    }
    text = Column(db.Text)
    choice_type = ('text', 'Text Section')

    def __init__(self, title, description, template_id):
        super(TextSection, self).__init__(template_id=template_id, title=title, description=description) class TemplatePlaceholders(Model):
    '''
    The placeholders associated with each section

    Fields:
    - name: The actual name of the placeholder
    - template_id: Foreign Key back to the TemplateBase model
    - section_id: Foreign Key back to the TemplateSection model
    '''

    __tablename__ = 'template_placeholders'
    id = Column(db.Integer, primary_key=True)
    full_name = Column(db.Text)
    display_name = Column(db.Text)
    type = Column(db.Integer, db.ForeignKey('placeholder_types.id'))
    template_id = ReferenceCol('template_base')
    section_id = ReferenceCol('template_section')

    def __init__(self, name=None, template_id=None, section_id=None):
        self.name = name
        self.template_id = template_id
        self.section_id = section_id class DocumentBase(Model):
    '''
    Metadata about a new document, relates back to
    a template
    '''

    __tablename__ = 'document_base'
    id = Column(db.Integer, primary_key=True)
    created_at = Column(db.DateTime)
    updated_at = Column(db.DateTime)
    name = Column(db.String(255))
    # published = Column(db.Boolean, default=False)
    template_id = ReferenceCol('template_base', ondelete='CASCADE')

    def __init__(self, created_at, updated_at, name, template_id):
        self.created_at = created_at
        self.updated_at = updated_at
        self.name = name
        self.template_id = template_id class DocumentPlaceholder(Model):
    '''
    A document's placeholder's value. Relates to the
    document and the placeholder
    '''

    __tablename__ = 'document_placeholder'
    id = Column(db.Integer, primary_key=True)
    document_id = ReferenceCol('document_base')
    placeholder_id = ReferenceCol('template_placeholders', ondelete='CASCADE')
    value = Column(db.Text)

    def __init__(self, document_id, placeholder_id):
        self.document_id = document_id
        self.placeholder_id = placeholder_id class User(UserMixin, SurrogatePK, Model):

    __tablename__ = 'users'
    email = Column(db.String(80), unique=True, nullable=False)
    created_at = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow)
    first_name = Column(db.String(30), nullable=True)
    last_name = Column(db.String(30), nullable=True)
    active = Column(db.Boolean(), default=False)
    is_admin = Column(db.Boolean(), default=False)

    def __init__(self, email, **kwargs):
        db.Model.__init__(self, email=email, **kwargs)

    @property
    def full_name(self):
        return "{0} {1}".format(self.first_name, self.last_name)

    def __repr__(self):
        return '<User({email!r})>'.format(email=self.email) def set_document_placeholders(template_id, document_base):
    # create the placeholders for the document
    placeholders = get_template_placeholders(template_id)
    for placeholder in placeholders:
        _placeholder = DocumentPlaceholder.query.filter(
            DocumentPlaceholder.placeholder_id==placeholder.id
        ).filter(
            DocumentPlaceholder.document_id==document_base.id
        ).first()

        # if we already have this placeholder, pass
        if _placeholder:
            continue

        new_placeholder = DocumentPlaceholder(
            document_id=document_base.id,
            placeholder_id=placeholder.id,
        )

        db.session.add(new_placeholder)

    db.session.commit() def get_document_placeholders(document_id):
    '''
    Gets all the placeholders associated with a document
    '''
    return db.session.query(
        DocumentPlaceholder.id, TemplatePlaceholders.full_name, TemplatePlaceholders.type,
        TemplatePlaceholders.display_name, DocumentPlaceholder.value
    ).filter(DocumentPlaceholder.document_id==document_id).filter(
        DocumentPlaceholder.placeholder_id==TemplatePlaceholders.id
    ).all()
import datetime
from template_maker.database import db
from template_maker.builder.models import (
    TemplateBase, TemplateSection, TextSection, TemplatePlaceholders
)
from template_maker.generator.models import DocumentBase, DocumentPlaceholder
from template_maker.users.models import User
from template_maker.data.documents import set_document_placeholders, get_document_placeholders

def create_a_template(title='test'):
    now = datetime.datetime.utcnow()
    return TemplateBase(created_at=now, updated_at=now, title=title, description='test')

def insert_new_template(title='test', published=False):
    template = create_a_template(title)
    template.published = published

    db.session.add(template)