aboutsummaryrefslogtreecommitdiff
path: root/rpki/irdb/router.py
diff options
context:
space:
mode:
authorRob Austein <sra@hactrn.net>2014-04-05 22:42:12 +0000
committerRob Austein <sra@hactrn.net>2014-04-05 22:42:12 +0000
commitfe0bf509f528dbdc50c7182f81057c6a4e15e4bd (patch)
tree07c9a923d4a0ccdfea11c49cd284f6d5757c5eda /rpki/irdb/router.py
parentaa28ef54c271fbe4d52860ff8cf13cab19e2207c (diff)
Source tree reorg, phase 1. Almost everything moved, no file contents changed.
svn path=/branches/tk685/; revision=5757
Diffstat (limited to 'rpki/irdb/router.py')
-rw-r--r--rpki/irdb/router.py95
1 files changed, 95 insertions, 0 deletions
diff --git a/rpki/irdb/router.py b/rpki/irdb/router.py
new file mode 100644
index 00000000..1f27d0c9
--- /dev/null
+++ b/rpki/irdb/router.py
@@ -0,0 +1,95 @@
+# $Id$
+#
+# Copyright (C) 2012 Internet Systems Consortium ("ISC")
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+"""
+Django-style "Database router".
+
+For most programs, you don't need this. Django's normal mode of
+behavior is to use a single SQL database for the IRDB, which is
+normally what we want. For certain test scenarios, however, it's
+useful to be able to use the same Django ORM models and managers with
+multiple databases without having to complicate the interface by
+passing database names everywhere. Using a database router
+accomplishes this.
+"""
+
+class DBContextRouter(object):
+ """
+ A Django database router for use with multiple IRDBs.
+
+ This router is designed to work in conjunction with the
+ rpki.irdb.database context handler (q.v.).
+ """
+
+ _app = "irdb"
+
+ _database = None
+
+ def db_for_read(self, model, **hints):
+ if model._meta.app_label == self._app:
+ return self._database
+ else:
+ return None
+
+ def db_for_write(self, model, **hints):
+ if model._meta.app_label == self._app:
+ return self._database
+ else:
+ return None
+
+ def allow_relation(self, obj1, obj2, **hints):
+ if self._database is None:
+ return None
+ elif obj1._meta.app_label == self._app and obj2._meta.app_label == self._app:
+ return True
+ else:
+ return None
+
+ def allow_syncdb(self, db, model):
+ if db == self._database and model._meta.app_label == self._app:
+ return True
+ else:
+ return None
+
+class database(object):
+ """
+ Context manager for use with DBContextRouter. Use thusly:
+
+ with rpki.irdb.database("blarg"):
+ do_stuff()
+
+ This binds IRDB operations to database blarg for the duration of
+ the call to do_stuff(), then restores the prior state.
+ """
+
+ def __init__(self, name, on_entry = None, on_exit = None):
+ if not isinstance(name, str):
+ raise ValueError("database name must be a string, not %r" % name)
+ self.name = name
+ self.on_entry = on_entry
+ self.on_exit = on_exit
+
+ def __enter__(self):
+ if self.on_entry is not None:
+ self.on_entry()
+ self.former = DBContextRouter._database
+ DBContextRouter._database = self.name
+
+ def __exit__(self, _type, value, traceback):
+ assert DBContextRouter._database is self.name
+ DBContextRouter._database = self.former
+ if self.on_exit is not None:
+ self.on_exit()