Exemple #1
0
    def test_indexed_ordering01(self):
        "FakeOrganisation"
        self.assertEqual((('name', 'cremeentity_ptr'), ),
                         FakeOrganisation._meta.index_together)

        self.assertIsNone(get_indexed_ordering(FakeOrganisation, ['phone']))

        self.assertEqual(('sector_id', ),
                         get_indexed_ordering(FakeOrganisation, ['sector_id']))

        # TODO: ?
        # self.assertEqual(('sector',),
        #                  get_best_ordering(FakeOrganisation, ['sector_id'])
        #                 )

        self.assertEqual(('name', 'cremeentity_ptr_id'),
                         get_indexed_ordering(FakeOrganisation, ['name']))

        # Order is important
        self.assertEqual(('name', 'cremeentity_ptr_id'),
                         get_indexed_ordering(FakeOrganisation,
                                              ['name', 'cremeentity_ptr_id']))

        self.assertIsNone(
            get_indexed_ordering(FakeOrganisation,
                                 ['cremeentity_ptr_id', 'name']))
Exemple #2
0
    def test_indexed_ordering06(self):
        "Avoid successive wildcards"
        with self.assertRaises(ValueError):
            get_indexed_ordering(FakeContact, ['*', '*', 'cremeentity_ptr_id'])

        with self.assertRaises(ValueError):
            get_indexed_ordering(FakeContact,
                                 ['last_name', '*', '*', 'cremeentity_ptr_id'])
Exemple #3
0
 def test_indexed_ordering03(self):
     "DESC order => inverted index"
     expected = ('-name', '-cremeentity_ptr_id')
     self.assertEqual(expected,
                      get_indexed_ordering(FakeOrganisation, ['-name']))
     self.assertEqual(
         expected,
         get_indexed_ordering(FakeOrganisation,
                              ['-name', '-cremeentity_ptr_id']))
Exemple #4
0
    def test_indexed_ordering05(self):
        "Blurred query + other model + DESC"
        self.assertEqual(('name', 'cremeentity_ptr_id'),
                         get_indexed_ordering(FakeOrganisation, ['name', '*']))
        self.assertEqual(('-name', '-cremeentity_ptr_id'),
                         get_indexed_ordering(FakeOrganisation,
                                              ['-name', '*']))

        self.assertEqual(
            ('-last_name', '-first_name', '-cremeentity_ptr_id'),
            get_indexed_ordering(
                FakeContact,
                ['-last_name', '-first_name', '*', '-cremeentity_ptr_id']))
Exemple #5
0
    def test_indexed_ordering04(self):
        "Blurred query"
        expected = ('last_name', 'first_name', 'cremeentity_ptr_id')
        self.assertEqual(
            expected,
            get_indexed_ordering(FakeContact,
                                 ['last_name', '*', 'cremeentity_ptr_id']))
        self.assertEqual(
            expected,
            get_indexed_ordering(FakeContact,
                                 ['*', 'first_name', 'cremeentity_ptr_id']))
        self.assertEqual(
            expected,
            get_indexed_ordering(FakeContact,
                                 ['last_name', 'first_name', '*']))

        self.assertEqual(
            expected,
            get_indexed_ordering(
                FakeContact,
                ['last_name', 'first_name', '*', 'cremeentity_ptr_id']))
        # self.assertEqual(expected, get_indexed_ordering(FakeContact, ['*', 'cremeentity_ptr_id']))  # Ambiguous
        self.assertEqual(
            expected,
            get_indexed_ordering(FakeContact, ['*', 'first_name', '*']))
        # self.assertEqual(expected, get_indexed_ordering(FakeContact, ['*', 'cremeentity_ptr_id', '*'])) # Ambiguous
        self.assertEqual(
            expected,
            get_indexed_ordering(
                FakeContact, ['*', 'first_name', '*', 'cremeentity_ptr_id']))

        self.assertIsNone(
            get_indexed_ordering(FakeContact, ['last_name', '*', 'phone']))
Exemple #6
0
    def test_sort_twoorders_05(self):
        "set_sort(): one natural ordering field not in cells"
        self.assertEqual(('name', '-expiration_date'),
                         FakeInvoice._meta.ordering
                        )
        self.assertIsNone(get_indexed_ordering(FakeInvoice, ['name', '-expiration_date']))

        field_name1 = 'name'

        build_cell = partial(EntityCellRegularField.build, model=FakeInvoice)
        cells = [build_cell(name='number'),
                 build_cell(name=field_name1),
                 # Not expiration_date
                ]

        lvs = ListViewState()
        ordering = lvs.set_sort(model=FakeInvoice, cells=cells, cell_key=None, order=None)
        self.assertEqual((field_name1, 'cremeentity_ptr_id'), ordering)

        key = cells[1].key  # First natural order
        self.assertEqual(key, lvs.sort_field)
        self.assertEqual('', lvs.sort_order)
Exemple #7
0
    def test_regularfield_default_twoorders_05(self):
        "One natural ordering field not in cells."
        sorter = QuerySorter()

        self.assertEqual(('name', '-expiration_date'),
                         FakeInvoice._meta.ordering)
        self.assertIsNone(
            get_indexed_ordering(FakeInvoice, ['name', '-expiration_date']))

        field_name1 = 'name'

        build_cell = partial(EntityCellRegularField.build, model=FakeInvoice)
        cells = [
            build_cell(name='number'),
            build_cell(name=field_name1),
            # Not expiration_date
        ]

        sortinfo = sorter.get(model=FakeInvoice, cells=cells, cell_key=None)
        self.assertEqual((field_name1, 'cremeentity_ptr_id'),
                         sortinfo.field_names)
        self.assertEqual(cells[1].key,
                         sortinfo.main_cell_key)  # First natural order
        self.assertTrue(sortinfo.main_order.asc)
Exemple #8
0
    def test_indexed_ordering02(self):
        "FakeContact"
        self.assertEqual((('last_name', 'first_name', 'cremeentity_ptr'), ),
                         FakeContact._meta.index_together)

        self.assertIsNone(get_indexed_ordering(FakeContact, ['phone']))
        self.assertIsNone(get_indexed_ordering(FakeContact,
                                               ['phone', 'email']))

        expected = ('last_name', 'first_name', 'cremeentity_ptr_id')
        self.assertEqual(expected,
                         get_indexed_ordering(FakeContact, ['last_name']))
        self.assertEqual(
            expected,
            get_indexed_ordering(FakeContact, ['last_name', 'first_name']))
        self.assertEqual(
            expected,
            get_indexed_ordering(
                FakeContact,
                ['last_name', 'first_name', 'cremeentity_ptr_id']))

        self.assertIsNone(
            get_indexed_ordering(FakeContact, ['first_name', 'last_name']))
Exemple #9
0
    def get(self, model, cells, cell_key, order=None, fast_mode=False):
        """Get a QuerySortInfo instance for a model & a main ordering cell,
        using the natural ordering of this model & the DB-indices.

        @param model: CremeEntity subclass.
        @param: cells: Sequence of displayed EntityCells (eg: columns of the list-view) ;
                If the natural ordering fields of the model are not present within the
                cells, they are not used in the result (excepted if it allows to use a
                DB-index).
        @param: cell_key: Key of the main (ie: first) ordering cell (string).
        @param order: <creme_core.utils.meta.Order> instance (or None, meaning "ASC order").
        @param fast_mode: Boolean ; <True> means "There are lots of entities, use
               a faster/simpler ordering".
        @return: A QuerySortInfo instance.
        """
        if order is None:
            order = Order()

        cells_dict = {c.key: c for c in cells}

        build_cell = partial(EntityCellRegularField.build, model=model)
        ordering = [
            ofield_str for ofield_str in model._meta.ordering if build_cell(
                name=OrderedField(ofield_str).field_name).key in cells_dict
        ]

        # Name of the main model-field used to perform the "ORDER BY" instruction.
        sort_field = self._get_field_name(cells_dict, cell_key)

        if sort_field:
            for ordered_field_str in (sort_field, '-' + sort_field):
                if ordered_field_str in ordering:
                    ordering.remove(ordered_field_str)
                    ordering.insert(0, sort_field)

                    if order.desc:
                        ordering = [
                            str(OrderedField(o).reversed()) for o in ordering
                        ]

                    break
            else:
                ordering.insert(0, order.prefix + sort_field)
        else:
            cell_key, order = self._default_key_n_order(model, ordering)

        sort_info = QuerySortInfo(cell_key=cell_key, order=order)

        if sort_field and self._is_field_unique(model, sort_field):
            ind_ordering = get_indexed_ordering(model, [*ordering, '*'])

            if ind_ordering is not None:
                sort_info.field_names = ind_ordering
            elif fast_mode:
                o_sort_field = order.prefix + sort_field
                ind_ordering = get_indexed_ordering(model, [o_sort_field, '*'])
                sort_info.field_names = (
                    o_sort_field, ) if ind_ordering is None else ind_ordering
            else:
                sort_info.field_names = tuple(ordering)
        else:
            # NB: we order by ID (like 'cremeentity_ptr_id' in entity sub-classes)
            #     in order to be sure that successive queries give consistent contents
            #     (if you order by 'name' & there are some duplicated names,
            #     the order by directive can be respected, but the order of the
            #     duplicates in the queries results be different -- so the
            #     paginated contents are not consistent).
            last_field = order.prefix + self._get_local_id_field(model).attname

            if ordering:
                ind_ordering = get_indexed_ordering(
                    model, [*ordering, '*', last_field])

                if ind_ordering is not None:
                    sort_info.field_names = ind_ordering
                elif fast_mode:
                    first_order = ordering[0]
                    ind_ordering = get_indexed_ordering(
                        model, [first_order, '*', last_field])

                    sort_info.field_names = (
                        first_order,
                        last_field) if ind_ordering is None else ind_ordering
                else:
                    sort_info.field_names = (*ordering, last_field)
            else:
                sort_info.field_names = (last_field, )

        return sort_info