pvl/verkko/db.py
author Tero Marttila <terom@paivola.fi>
Sun, 10 Feb 2013 13:20:29 +0200
changeset 205 f7658198c224
parent 184 eef756d892e9
child 237 3534d31282b3
permissions -rw-r--r--
pvl.verkko.hosts: refactor RealtimeHandler to use HostsTable
"""
    SQLAlchemy Database tables model for pvl.verkko
"""

import sqlalchemy
from sqlalchemy import *

import logging; log = logging.getLogger('pvl.verkko.db')

# schema
metadata = MetaData()

dhcp_hosts = Table('dhcp_hosts', metadata,
    Column('id',            Integer,    primary_key=True),

    # unique
    Column('ip',            String,     nullable=False),
    Column('mac',           String,     nullable=False),
    Column('gw',            String,     nullable=False),
    
    # updated
    Column('first_seen',    DateTime,   nullable=False),
    Column('last_seen',     DateTime,   nullable=False),
    
    # scalar; updated
    Column('name',          String,     nullable=True),
    Column('state',         String,     nullable=True),
    Column('error',         String,     nullable=True),
    
    # counters
    Column('count',         Integer,    default=1),

    UniqueConstraint('ip', 'mac', 'gw'),
)

dhcp_leases = Table('dhcp_leases', metadata,
    Column('id',            Integer,    primary_key=True),

    Column('ip',            String,     nullable=False),
    Column('mac',           String,     nullable=False),
    Column('hostname',      String,     nullable=True),

    Column('starts',        DateTime,   nullable=False),
    Column('ends',          DateTime,   nullable=True),  # never
    # TODO: renewed

    Column('state',         String,     nullable=True),
    Column('next',          String,     nullable=True),
)

# for ORM models
from sqlalchemy.orm import mapper, sessionmaker

Session = sessionmaker()

class Database (object) :
    """
        Our underlying database.
    """
    
    def __init__ (self, database) :
        """
            database        - sqlalchemy connection URI
        """

        self.engine = create_engine(database, 
            echo    = (log.isEnabledFor(logging.DEBUG)),
        )

    # ORM
    def session (self) :
        """
            Return a new ORM session bound to our engine.

            XXX: session lifetimes? Explicit close?
        """

        return Session(bind=self.engine)
   
    # SQL
    def connect (self) :
        return self.engine.connect()

    def execute (self, query) :
        return self.engine.execute(query)

    def select (self, query) :
        return self.engine.execute(query)

    def get (self, query) :
        """
            Fetch a single row.
            
            XXX: returning None if not found
        """

        return self.select(query).fetchone()

    def insert (self, insert) :
        """
            Execute given INSERT query, returning the inserted primary key.
        """

        result = self.engine.execute(insert)

        id, = result.inserted_primary_key
        
        return id

    def update (self, update) :
        """
            Execute given UPDATE query, returning the number of matched rows.
        """

        result = self.engine.execute(update)
        
        return result.rowcount