Skip to content

Commit

Permalink
initial support for adapter based data access
Browse files Browse the repository at this point in the history
  • Loading branch information
joamag committed Nov 25, 2015
1 parent f0bb55f commit 49bf0b3
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 26 deletions.
2 changes: 2 additions & 0 deletions src/appier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from . import compress
from . import config
from . import controller
from . import data
from . import defines
from . import exceptions
from . import export
Expand Down Expand Up @@ -74,6 +75,7 @@
from .compress import Compress
from .config import conf, conf_prefix, conf_s
from .controller import Controller
from .data import DataAdapter, MongoAdapter, Collection, MongoCollection
from .defines import ITERABLES, MOBILE_REGEX, MOBILE_PREFIX_REGEX, BODY_REGEX, TAG_REGEX,\
EMAIL_REGEX, WINDOWS_LOCALE
from .exceptions import AppierException, OperationalError, SecurityError, ValidationError,\
Expand Down
8 changes: 8 additions & 0 deletions src/appier/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
from . import http
from . import meta
from . import util
from . import data
from . import smtp
from . import async
from . import cache
Expand Down Expand Up @@ -265,6 +266,7 @@ def __init__(
self.ssl = False
self.local_url = None
self.cache_d = self.cache_c()
self.adapter = data.MongoAdapter()
self.manager = async.QueueManager(self)
self.routes_v = None
self.tid = None
Expand Down Expand Up @@ -1870,6 +1872,9 @@ def get_bundle(self, name = None):
if name == None: name = self.request.locale
return self.bundles.get(name, None)

def get_adapter(self):
return self.adapter

def get_libraries(self, update = True, map = False, sort = True):
if update: self._update_libraries()
if map: return self.libraries
Expand Down Expand Up @@ -3178,6 +3183,9 @@ def get_model(name):
def get_controller(name):
return APP and APP.get_controller(name)

def get_adapter():
return APP and APP.get_adapter()

def get_level():
global LEVEL
if LEVEL: return LEVEL
Expand Down
76 changes: 76 additions & 0 deletions src/appier/data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Hive Appier Framework
# Copyright (c) 2008-2015 Hive Solutions Lda.
#
# This file is part of Hive Appier Framework.
#
# Hive Appier Framework is free software: you can redistribute it and/or modify
# it under the terms of the Apache License as published by the Apache
# Foundation, either version 2.0 of the License, or (at your option) any
# later version.
#
# Hive Appier Framework 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
# Apache License for more details.
#
# You should have received a copy of the Apache License along with
# Hive Appier Framework. If not, see <http://www.apache.org/licenses/>.

__author__ = "João Magalhães <joamag@hive.pt>"
""" The author(s) of the module """

__version__ = "1.0.0"
""" The version of the module """

__revision__ = "$LastChangedRevision$"
""" The revision number of the module """

__date__ = "$LastChangedDate$"
""" The last change date of the module """

__copyright__ = "Copyright (c) 2008-2015 Hive Solutions Lda."
""" The copyright for the module """

__license__ = "Apache License, Version 2.0"
""" The license for the module """

from . import mongo

class DataAdapter(object):
pass

class MongoAdapter(DataAdapter):

def collection(self, name, *args, **kwargs):
db = mongo.get_db()
collection = db[name]
return MongoCollection(collection)

class Collection(object):
pass

class MongoCollection(Collection):

def __init__(self, base):
self._base = base

def insert(self, *args, **kwargs):
return mongo._store_insert(self._base, *args, **kwargs)

def update(self, *args, **kwargs):
return mongo._store_update(self._base, *args, **kwargs)

def remove(self, *args, **kwargs):
return self._base.remove(*args, **kwargs)

def find(self, *args, **kwargs):
return self._base.find(*args, **kwargs)

def find_one(self, *args, **kwargs):
return self._base.find_one(*args, **kwargs)

def find_and_modify(self, *args, **kwargs):
return mongo._store_find_and_modify(self._base, *args, **kwargs)
35 changes: 11 additions & 24 deletions src/appier/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -467,13 +467,7 @@ def get(cls, *args, **kwargs):
collection = cls._collection()
model = collection.find_one(
kwargs,
projection = fields,
skip = skip,
limit = limit,
sort = sort
) if mongo.is_new() else collection.find_one(
kwargs,
fields = fields,
fields,
skip = skip,
limit = limit,
sort = sort
Expand Down Expand Up @@ -515,13 +509,7 @@ def find(cls, *args, **kwargs):
collection = cls._collection()
models = collection.find(
kwargs,
projection = fields,
skip = skip,
limit = limit,
sort = sort
) if mongo.is_new() else collection.find(
kwargs,
fields = fields,
fields,
skip = skip,
limit = limit,
sort = sort
Expand Down Expand Up @@ -1263,10 +1251,10 @@ def _solve(cls, name):
return definition.get("meta", base)

@classmethod
def _collection(cls):
name = cls._name()
db = mongo.get_db()
collection = db[name]
def _collection(cls, name = None):
name = name or cls._name()
adapter = common.base().get_adapter()
collection = adapter.collection(name)
return collection

@classmethod
Expand Down Expand Up @@ -1502,9 +1490,8 @@ class that does not inherit from the entity class.
@classmethod
def _increment(cls, name):
_name = cls._name() + ":" + name
db = mongo.get_db()
value = mongo._store_find_and_modify(
db.counters,
store = cls._collection(name = "counters")
value = store.find_and_modify(
{
"_id" : _name
},
Expand All @@ -1516,7 +1503,7 @@ def _increment(cls, name):
new = True,
upsert = True
)
value = value or db.counters.find_one({
value = value or store.find_one({
"_id" : _name
})
return value["seq"]
Expand Down Expand Up @@ -1681,8 +1668,8 @@ def save(self, validate = True):
# retrieves the reference to the store object to be used and
# uses it to store the current model data
store = self._get_store()
if is_new: self._id = mongo._store_insert(store, model); self.apply(model)
else: mongo._store_update(store, {"_id" : model["_id"]}, {"$set" : _model})
if is_new: self._id = store.insert(model); self.apply(model)
else: store.update({"_id" : model["_id"]}, {"$set" : _model})

# calls the post save event handlers in order to be able to
# execute appropriate post operations
Expand Down
8 changes: 8 additions & 0 deletions src/appier/test/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ class Person(appier.Model):
)
)

@classmethod
def validate(cls):
return super(Person, cls).validate() + [
appier.not_null("name"),
appier.not_empty("name"),
appier.not_duplicate("name", cls._name())
]

class Cat(appier.Model):

identifier = appier.field(
Expand Down
14 changes: 14 additions & 0 deletions src/appier/test/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,20 @@ def test_basic(self):

self.assertEqual(bool(person), False)

def test_validation(self):
person = mock.Person()

self.assertRaises(appier.ValidationError, person.save)

person = mock.Person()
person.name = "Name"
person.save()

person = mock.Person()
person.name = "Name"

self.assertRaises(appier.ValidationError, person.save)

def test_map(self):
person = mock.Person()
person.name = "Name"
Expand Down
4 changes: 2 additions & 2 deletions src/appier/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ def validation(object, ctx):
value = object.get(name, None)
if value == None: return True
if value == "": return True
db = mongo.get_db()
_collection = db[collection]
adapter = common.base().get_adapter()
_collection = adapter.collection(collection)
item = _collection.find_one({name : value})
if not item: return True
if str(item["_id"]) == str(_id): return True
Expand Down

0 comments on commit 49bf0b3

Please sign in to comment.