From ae078728c8bc1c7d4412c4cb19b6802e9b7e8f74 Mon Sep 17 00:00:00 2001 From: bryan newbold Date: Sun, 14 Jun 2009 19:51:50 -0400 Subject: initial appengine setup; BROKEN --- appengine_django/db/__init__.py | 20 ++++++ appengine_django/db/__init__.pyc | Bin 0 -> 183 bytes appengine_django/db/base.py | 150 +++++++++++++++++++++++++++++++++++++++ appengine_django/db/base.pyc | Bin 0 -> 6210 bytes appengine_django/db/creation.py | 37 ++++++++++ appengine_django/db/creation.pyc | Bin 0 -> 1288 bytes 6 files changed, 207 insertions(+) create mode 100755 appengine_django/db/__init__.py create mode 100644 appengine_django/db/__init__.pyc create mode 100755 appengine_django/db/base.py create mode 100644 appengine_django/db/base.pyc create mode 100755 appengine_django/db/creation.py create mode 100644 appengine_django/db/creation.pyc (limited to 'appengine_django/db') diff --git a/appengine_django/db/__init__.py b/appengine_django/db/__init__.py new file mode 100755 index 0000000..619bc78 --- /dev/null +++ b/appengine_django/db/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Explicitly set the name of this package to "appengine". +# +# The rationale for this is so that Django can refer to the database as +# "appengine" even though at a filesystem level it appears as the "db" package +# within the appengine_django package. +__name__ = "appengine" diff --git a/appengine_django/db/__init__.pyc b/appengine_django/db/__init__.pyc new file mode 100644 index 0000000..879eeaa Binary files /dev/null and b/appengine_django/db/__init__.pyc differ diff --git a/appengine_django/db/base.py b/appengine_django/db/base.py new file mode 100755 index 0000000..8a90182 --- /dev/null +++ b/appengine_django/db/base.py @@ -0,0 +1,150 @@ +#!/usr/bin/python2.4 +# +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This module looks after initialising the appengine api stubs.""" + +import logging +import os + +from appengine_django import appid +from appengine_django import have_appserver +from appengine_django.db.creation import DatabaseCreation + + +from django.db.backends import BaseDatabaseWrapper +from django.db.backends import BaseDatabaseFeatures +from django.db.backends import BaseDatabaseOperations + + +def get_datastore_paths(): + """Returns a tuple with the path to the datastore and history file. + + The datastore is stored in the same location as dev_appserver uses by + default, but the name is altered to be unique to this project so multiple + Django projects can be developed on the same machine in parallel. + + Returns: + (datastore_path, history_path) + """ + from google.appengine.tools import dev_appserver_main + datastore_path = dev_appserver_main.DEFAULT_ARGS['datastore_path'] + history_path = dev_appserver_main.DEFAULT_ARGS['history_path'] + datastore_path = datastore_path.replace("dev_appserver", "django_%s" % appid) + history_path = history_path.replace("dev_appserver", "django_%s" % appid) + return datastore_path, history_path + + +def get_test_datastore_paths(inmemory=True): + """Returns a tuple with the path to the test datastore and history file. + + If inmemory is true, (None, None) is returned to request an in-memory + datastore. If inmemory is false the path returned will be similar to the path + returned by get_datastore_paths but with a different name. + + Returns: + (datastore_path, history_path) + """ + if inmemory: + return None, None + datastore_path, history_path = get_datastore_paths() + datastore_path = datastore_path.replace("datastore", "testdatastore") + history_path = history_path.replace("datastore", "testdatastore") + return datastore_path, history_path + + +def destroy_datastore(datastore_path, history_path): + """Destroys the appengine datastore at the specified paths.""" + for path in [datastore_path, history_path]: + if not path: continue + try: + os.remove(path) + except OSError, e: + if e.errno != 2: + logging.error("Failed to clear datastore: %s" % e) + + +class DatabaseError(Exception): + """Stub class for database errors. Required by Django""" + pass + + +class IntegrityError(Exception): + """Stub class for database integrity errors. Required by Django""" + pass + + +class DatabaseFeatures(BaseDatabaseFeatures): + """Stub class to provide the feaures member expected by Django""" + pass + + +class DatabaseOperations(BaseDatabaseOperations): + """Stub class to provide the options member expected by Django""" + pass + + +class DatabaseWrapper(BaseDatabaseWrapper): + """App Engine database definition for Django. + + This "database" backend does not support any of the standard backend + operations. The only task that it performs is to setup the api stubs required + by the appengine libraries if they have not already been initialised by an + appserver. + """ + + def __init__(self, *args, **kwargs): + super(DatabaseWrapper, self).__init__(*args, **kwargs) + self.features = DatabaseFeatures() + self.ops = DatabaseOperations() + self.creation = DatabaseCreation(self) + self.use_test_datastore = kwargs.get("use_test_datastore", False) + self.test_datastore_inmemory = kwargs.get("test_datastore_inmemory", True) + if have_appserver: + return + self._setup_stubs() + + def _get_paths(self): + if self.use_test_datastore: + return get_test_datastore_paths(self.test_datastore_inmemory) + else: + return get_datastore_paths() + + def _setup_stubs(self): + # If this code is being run without an appserver (eg. via a django + # commandline flag) then setup a default stub environment. + from google.appengine.tools import dev_appserver_main + args = dev_appserver_main.DEFAULT_ARGS.copy() + args['datastore_path'], args['history_path'] = self._get_paths() + from google.appengine.tools import dev_appserver + dev_appserver.SetupStubs(appid, **args) + if self.use_test_datastore: + logging.debug("Configured API stubs for the test datastore") + else: + logging.debug("Configured API stubs for the development datastore") + + def flush(self): + """Helper function to remove the current datastore and re-open the stubs""" + destroy_datastore(*self._get_paths()) + self._setup_stubs() + + def close(self): + pass + + def _commit(self): + pass + + def cursor(self, *args): + pass diff --git a/appengine_django/db/base.pyc b/appengine_django/db/base.pyc new file mode 100644 index 0000000..8699add Binary files /dev/null and b/appengine_django/db/base.pyc differ diff --git a/appengine_django/db/creation.py b/appengine_django/db/creation.py new file mode 100755 index 0000000..74e3048 --- /dev/null +++ b/appengine_django/db/creation.py @@ -0,0 +1,37 @@ +#!/usr/bin/python2.4 +# +# Copyright 2008 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import logging + +from django.db.backends.creation import BaseDatabaseCreation + + +class DatabaseCreation(BaseDatabaseCreation): + + def create_test_db(self, *args, **kw): + """Destroys the test datastore. A new store will be recreated on demand""" + self.destroy_test_db() + self.connection.use_test_datastore = True + self.connection.flush() + + + def destroy_test_db(self, *args, **kw): + """Destroys the test datastore files.""" + from appengine_django.db.base import destroy_datastore + from appengine_django.db.base import get_test_datastore_paths + destroy_datastore(*get_test_datastore_paths()) + logging.debug("Destroyed test datastore") diff --git a/appengine_django/db/creation.pyc b/appengine_django/db/creation.pyc new file mode 100644 index 0000000..2055fb6 Binary files /dev/null and b/appengine_django/db/creation.pyc differ -- cgit v1.2.3