db_router.py revision e2bf396b7d3870f7565b2b10018087ab7fa6256e
1#pylint: disable-msg=C0111
2
3# Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Django database Router
8
9Django gets configured with two databases in frontend/settings.py.
10- The default database
11    - This database should be used for most things.
12    - For the master, this is the global database.
13    - For shards, this this is the shard-local database.
14- The global database
15    - For the master, this is the same database as default, which is the global
16      database.
17    - For the shards, this is the global database (the same as for the master).
18
19The reason shards need two distinct databases for different objects is, that
20the tko parser should always write to the global database. Otherwise test
21results wouldn't be synced back to the master and would not be accessible in one
22place.
23
24Therefore this class will route all queries that involve `tko_`-prefixed tables
25to the global database. For all others this router will not give a hint, which
26means the default database will be used.
27"""
28
29class Router(object):
30    """
31    Decide if an object should be written to the default or to the global db.
32
33    This is an implementaton of Django's multi-database router interface:
34    https://docs.djangoproject.com/en/1.5/topics/db/multi-db/
35    """
36
37    def _should_be_in_global(self, model):
38        """Returns True if the model should be stored in the global db"""
39        return model._meta.db_table.startswith('tko_')
40
41
42    def db_for_read(self, model, **hints):
43        """
44        Decides if the global database should be used for a reading access.
45
46        @param model: Model to decide for.
47
48        @returns: 'global' for all tko models, None otherwise. None means the
49                  router doesn't have an opinion.
50        """
51        if self._should_be_in_global(model):
52            return 'global'
53        return None
54
55
56    def db_for_write(self, model, **hints):
57        """
58        Decides if the global database should be used for a writing access.
59
60        @param model: Model to decide for.
61
62        @returns: 'global' for all tko models, None otherwise. None means the
63                  router doesn't have an opinion.
64        """
65        if self._should_be_in_global(model):
66            return 'global'
67        return None
68
69
70    def allow_relation(self, obj1, obj2, **hints):
71        """
72        Allow relations only if either both are in tko_ tables or none is.
73
74        @param obj1: First object involved in the relation.
75        @param obj2: Second object involved in the relation.
76
77        @returns False, if the relation should be prohibited,
78                 None, if the router doesn't have an opinion.
79        """
80        if not self._should_be_in_global(
81                type(obj1)) == self._should_be_in_global(type(obj2)):
82            return False
83        return None
84