def create_schema(sender, instance, created, **kwargs):
    """
    Actually create the schema in the database.

    We do this in a signal handler instead of .save() so we can catch
    those created using raw methods.

    How do we indicate when we should be using a different template?
    """
    if created:
        schema_name = instance.schema

        # How can we work out what values need to go here?
        # Currently, we just allow a single attribute `_clone`, that,
        # if set, will indicate that we should clone a schema.
        template_name = getattr(instance, '_clone', settings.TEMPLATE_SCHEMA)
        include_records = bool(getattr(instance, '_clone', False))

        cursor = connection.cursor()

        if _schema_exists(schema_name):
            raise ValueError('Attempt to create an existing schema: {0}'.format(schema_name))

        cursor.execute("SELECT clone_schema(%s, %s, %s)", [
            template_name,
            schema_name,
            include_records
        ])
        cursor.close()

        if schema_name != settings.TEMPLATE_SCHEMA:
            signals.schema_created.send(sender=get_schema_model(), schema=schema_name)

        LOGGER.info('New schema created: %s', schema_name)
Esempio n. 2
0
    def ready(self):
        if not hasattr(settings, 'BOARDINGHOUSE_TEMPLATE_PREFIX'):
            settings.BOARDINGHOUSE_TEMPLATE_PREFIX = '__tmpl_'

        from boardinghouse.schema import get_schema_model

        from .models import SchemaTemplate
        from ..template import receivers  # NOQA

        if 'django.contrib.admin' in settings.INSTALLED_APPS:
            # We can't just add the action to the SchemaAdmin, because that may not be a subclass of ModelAdmin,
            # in which case the action would be applied to all models.
            from .admin import create_template_from_schema
            Schema = get_schema_model()
            module = import_module(
                Schema.__module__.rsplit('.', 1)[0] + '.admin')
            BaseSchemaAdmin = module.admin.site._registry[Schema].__class__

            from django.contrib import admin
            from django import forms

            admin.site.unregister(Schema)

            class SchemaAdmin(BaseSchemaAdmin):
                actions = list(BaseSchemaAdmin.actions
                               or []) + [create_template_from_schema]

                def get_form(self, request, obj=None, **kwargs):
                    if not obj and 'boardinghouse.contrib.template' in settings.INSTALLED_APPS:

                        class SchemaAdminForm(BaseSchemaAdmin.form
                                              or forms.ModelForm):
                            clone_schema = forms.ModelChoiceField(
                                required=False,
                                queryset=SchemaTemplate.objects.all())

                        kwargs['form'] = SchemaAdminForm
                    return super(SchemaAdmin,
                                 self).get_form(request, obj, **kwargs)

                def get_fields(self, request, obj):
                    fields = super(SchemaAdmin, self).get_fields(request, obj)
                    if 'clone_schema' in fields:
                        fields.remove('clone_schema')
                        return ['clone_schema'] + fields
                    return fields

                def save_model(self, request, obj, form, change):
                    if not change and form.cleaned_data.get(
                            'clone_schema') is not None:
                        obj._clone = form.cleaned_data['clone_schema'].schema
                    return super(SchemaAdmin,
                                 self).save_model(request, obj, form, change)

            admin.site.register(Schema, SchemaAdmin)
Esempio n. 3
0
    def ready(self):
        if self._ready_has_run:
            return

        # Make sure that all default settings have been applied (if not overwritten).
        from boardinghouse import settings as app_settings
        from django.conf import settings, global_settings

        for key in dir(app_settings):
            if key.isupper():
                value = getattr(app_settings, key)
                setattr(global_settings, key, value)
                if not hasattr(settings, key):
                    setattr(settings, key, value)

        # Make non-logged-in users unable to view any schemata.
        from django.contrib.auth import get_user_model, models
        from boardinghouse.schema import get_schema_model
        from boardinghouse.models import visible_schemata

        User = get_user_model()

        models.AnonymousUser.visible_schemata = get_schema_model().objects.none()

        if not hasattr(User, 'visible_schemata'):
            User.visible_schemata = property(visible_schemata)

        if hasattr(User, 'schemata'):
            models.AnonymousUser.schemata = get_schema_model().objects.none()

        # Make sure User <--> Group and User <--> Permission are per-schema.
        # If this is not desired, then it needs to be overriden.
        settings.PRIVATE_MODELS.extend([
            '{m.app_label}.{m.model_name}'.format(m=User.groups.through._meta).lower(),
            '{m.app_label}.{m.model_name}'.format(m=User.user_permissions.through._meta).lower()
        ])

        from boardinghouse import receivers  # NOQA

        self._ready_has_run = True
Esempio n. 4
0
    def ready(self):
        if not hasattr(settings, 'BOARDINGHOUSE_TEMPLATE_PREFIX'):
            settings.BOARDINGHOUSE_TEMPLATE_PREFIX = '__tmpl_'

        from boardinghouse.schema import get_schema_model

        from .models import SchemaTemplate
        from ..template import receivers  # NOQA

        if 'django.contrib.admin' in settings.INSTALLED_APPS:
            # We can't just add the action to the SchemaAdmin, because that may not be a subclass of ModelAdmin,
            # in which case the action would be applied to all models.
            from .admin import create_template_from_schema
            Schema = get_schema_model()
            module = import_module(Schema.__module__.rsplit('.', 1)[0] + '.admin')
            BaseSchemaAdmin = module.admin.site._registry[Schema].__class__

            from django.contrib import admin
            from django import forms

            admin.site.unregister(Schema)

            class SchemaAdmin(BaseSchemaAdmin):
                actions = list(BaseSchemaAdmin.actions or []) + [create_template_from_schema]

                def get_form(self, request, obj=None, **kwargs):
                    if not obj and 'boardinghouse.contrib.template' in settings.INSTALLED_APPS:
                        class SchemaAdminForm(BaseSchemaAdmin.form or forms.ModelForm):
                            clone_schema = forms.ModelChoiceField(required=False,
                                                                  queryset=SchemaTemplate.objects.all())
                        kwargs['form'] = SchemaAdminForm
                    return super(SchemaAdmin, self).get_form(request, obj, **kwargs)

                def get_fields(self, request, obj):
                    fields = super(SchemaAdmin, self).get_fields(request, obj)
                    if 'clone_schema' in fields:
                        fields.remove('clone_schema')
                        return ['clone_schema'] + fields
                    return fields

                def save_model(self, request, obj, form, change):
                    if not change and form.cleaned_data.get('clone_schema') is not None:
                        obj._clone = form.cleaned_data['clone_schema'].schema
                    return super(SchemaAdmin, self).save_model(request, obj, form, change)

            admin.site.register(Schema, SchemaAdmin)
Esempio n. 5
0
from django.test import TestCase

from boardinghouse.schema import get_schema_model
from ..models import AwareModel

Schema = get_schema_model()


class TestMultiSchemaManager(TestCase):
    def test_multi_schema_fetches_objects_correctly(self):
        Schema.objects.mass_create('a', 'b')

        a = Schema.objects.get(name='a')
        a.activate()
        AwareModel.objects.create(name='foo')
        AwareModel.objects.create(name='bar')
        AwareModel.objects.create(name='baz')

        b = Schema.objects.get(name='b')
        b.activate()
        AwareModel.objects.create(name='foo')
        AwareModel.objects.create(name='bar')
        AwareModel.objects.create(name='baz')

        b.deactivate()

        objects = list(AwareModel.objects.from_schemata(a))
        self.assertEqual(3, len(objects))

        objects = list(AwareModel.objects.from_schemata(a, b))
        self.assertEqual(6, len(objects))
 def test_invalid_schema_model_string(self):
     settings.BOARDINGHOUSE_SCHEMA_MODEL = 'foo__bar'
     with self.assertRaises(ImproperlyConfigured):
         get_schema_model()
 def test_schema_model_model_not_found(self):
     settings.BOARDINGHOUSE_SCHEMA_MODEL = 'boardinghouse.NotSchemaModel'
     with self.assertRaises(ImproperlyConfigured):
         get_schema_model()
 def test_schema_model_app_not_found(self):
     settings.BOARDINGHOUSE_SCHEMA_MODEL = 'foo.bar'
     with self.assertRaises(ImproperlyConfigured):
         get_schema_model()
def execute_on_all_schemata(sender, db_table, function, **kwargs):
    if _schema_table_exists():
        for each in get_schema_model().objects.all():
            each.activate()
            function(*kwargs.get('args', []), **kwargs.get('kwargs', {}))
 def test_schema_model_model_not_found(self):
     settings.BOARDINGHOUSE_SCHEMA_MODEL = 'boardinghouse.NotSchemaModel'
     with self.assertRaises(ImproperlyConfigured):
         get_schema_model()
 def test_no_BOARDINGHOUSE_SCHEMA_MODEL(self):
     del settings.BOARDINGHOUSE_SCHEMA_MODEL
     with self.assertRaises(exceptions.ImproperlyConfigured):
         get_schema_model()
Esempio n. 12
0
def verbose_name():
    if 'makemigrations' in sys.argv:
        return u'template schema'
    return u'template {0}'.format(get_schema_model()._meta.verbose_name)
 def test_no_BOARDINGHOUSE_SCHEMA_MODEL(self):
     del settings.BOARDINGHOUSE_SCHEMA_MODEL
     with self.assertRaises(exceptions.ImproperlyConfigured):
         get_schema_model()
Esempio n. 14
0
def verbose_name():
    if 'makemigrations' in sys.argv:
        return u'template schema'
    return u'template {0}'.format(get_schema_model()._meta.verbose_name)
 def test_invalid_schema_model_string(self):
     settings.BOARDINGHOUSE_SCHEMA_MODEL = 'foo__bar'
     with self.assertRaises(ImproperlyConfigured):
         get_schema_model()
from django.test import TestCase

from boardinghouse.schema import get_schema_model
from ..models import AwareModel, NaiveModel

Schema = get_schema_model()


class TestObjectEquality(TestCase):
    def test_objects_from_different_schema_differ(self):
        first, second = Schema.objects.mass_create('first', 'second')

        first.activate()
        object_1 = AwareModel.objects.create(name="foo")

        second.activate()
        object_2 = AwareModel.objects.create(name="foo")

        self.assertEqual(object_1.pk, object_2.pk)
        self.assertNotEqual(object_1,
                            object_2,
                            "Objects with the same id from different schemata should not be equal.")

    def test_objects_from_same_schema_equal(self):
        first, second = Schema.objects.mass_create('first', 'second')

        first.activate()
        AwareModel.objects.create(name="foo")

        second.activate()
        object_2 = AwareModel.objects.create(name="foo")
 def test_schema_model_app_not_found(self):
     settings.BOARDINGHOUSE_SCHEMA_MODEL = 'foo.bar'
     with self.assertRaises(ImproperlyConfigured):
         get_schema_model()