Source code for stoqlib.database.orm
# -*- coding: utf-8 -*-
# vi:si:et:sw=4:sts=4:ts=4
##
## Copyright (c) 2006, 2007 Canonical
## Copyright (C) 2008-2013 Async Open Source <http://www.async.com.br>
## All rights reserved
##
## 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; either version 2 of the License, or
## (at your option) any later version.
##
## 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., or visit: http://www.gnu.org/.
##
## Author(s): Stoq Team <stoq-devel@async.com.br>
## Gustavo Niemeyer <gustavo@niemeyer.net>
##
# This file is full of hacks to mimic the SQLObject API
# TODO:
# - Replace get/etc with storm.find()
"""Simple ORM abstraction layer"""
import warnings
from storm.base import Storm
from storm.store import Store
from stoqlib.database.exceptions import ORMObjectNotFound
[docs]class SQLObjectBase(Storm):
"""The root class of all SQLObject-emulating classes in your application.
The general strategy for using Storm's SQLObject emulation layer
is to create an application-specific subclass of SQLObjectBase
(probably named "SQLObject") that provides an implementation of
get_store to return an instance of :class:`storm.store.Store`. It may
even be implemented as returning a global :class:`Store` instance. Then
all database classes should subclass that class.
"""
# FIXME: Remove
@classmethod
[docs] def get(cls, obj_id, store=None):
warnings.warn("use store.get() or store.fetch()", DeprecationWarning,
stacklevel=2)
obj = store.get(cls, obj_id)
if obj is None:
raise ORMObjectNotFound("Object not found")
return obj
# FIXME: Remove
[docs] def sync(self):
warnings.warn("use store.flush()", DeprecationWarning, stacklevel=2)
store = self.store
store.flush()
store.autoreload(self)
# FIXME: Remove
@classmethod
[docs] def delete(cls, id, store=None):
warnings.warn("use store.remove()", DeprecationWarning, stacklevel=2)
obj = store.get(cls, id)
Store.of(obj).remove(obj)
[docs]class ORMObject(SQLObjectBase):
def __init__(self, store=None, **kwargs):
if store:
store.add(self)
cls = type(self)
for attr, value in kwargs.items():
if not hasattr(cls, attr):
raise TypeError("class %s does not have an attribute %s" % (
cls.__name__, attr))
# FIXME: storm is not setting foreign keys correctly if the
# value is None (NULL)
if value is not None:
setattr(self, attr, value)
def __eq__(self, other):
if type(self) is not type(other):
return False
from stoqlib.lib.environment import is_developer_mode
if is_developer_mode():
# Check this only in develper mode to get as many potential errors
# as possible.
assert Store.of(self) is Store.of(other)
return self.id == other.id
def __ne__(self, other):
return not self.__eq__(other)
@property
def store(self):
return Store.of(self)