Example #1
0
 def ReplaceTableData(self, table_id, row_ids, column_values):
     old_data = self._engine.fetch_table(table_id, formulas=False)
     self._engine.out_actions.undo.append(
         actions.ReplaceTableData(*old_data))
     self._engine.out_actions.summary.remove_records(table_id, old_data[1])
     self._engine.out_actions.summary.add_records(table_id, row_ids)
     self._engine.load_table(
         actions.TableData(table_id, row_ids, column_values))
Example #2
0
 def create_table_views_action(views_to_table, primary_views):
     related_views = sorted(
         set(views_to_table.keys()) - set(primary_views.values()))
     row_ids = list(xrange(1, len(related_views) + 1))
     return actions.ReplaceTableData(
         '_grist_TableViews', row_ids, {
             'tableRef': [views_to_table[v] for v in related_views],
             'viewRef': related_views,
         })
Example #3
0
def migration20(tdset):
    """
  Add _grist_Pages table and populate based on existing TableViews entries, ie: tables are sorted
  alphabetically by their `tableId` and views are gathered within their corresponding table and
  sorted by their id.
  """
    tables = list(
        actions.transpose_bulk_action(tdset.all_tables['_grist_Tables']))
    table_map = {t.id: t for t in tables}
    table_views = list(
        actions.transpose_bulk_action(tdset.all_tables['_grist_TableViews']))
    # Old docs may include "Other views", not associated with any table. Don't include those in
    # table_views_map: they'll get included but not sorted or grouped by tableId.
    table_views_map = {
        tv.viewRef: table_map[tv.tableRef].tableId
        for tv in table_views if tv.tableRef in table_map
    }
    views = list(
        actions.transpose_bulk_action(tdset.all_tables['_grist_Views']))

    def view_key(view):
        """
    Returns ("Table1", 2) where "Table1" is the view's tableId and 2 the view id. For
    primary view (ie: not referenced in _grist_TableViews) returns ("Table1", -1). Useful
    to get the list of views sorted in the same way as in the Table side pane. We use -1
    for primary view to make sure they come first among all the views of the same table.
    """
        if view.id in table_views_map:
            return (table_views_map[view.id], view.id)
        # the name of primary view's is the same as the tableId
        return (view.name, -1)

    views.sort(key=view_key)
    row_ids = list(xrange(1, len(views) + 1))
    return tdset.apply_doc_actions([
        actions.AddTable('_grist_Pages', [
            schema.make_column('viewRef', 'Ref:_grist_Views'),
            schema.make_column('pagePos', 'PositionNumber'),
            schema.make_column('indentation', 'Int'),
        ]),
        actions.ReplaceTableData(
            '_grist_Pages', row_ids, {
                'viewRef': [v.id for v in views],
                'pagePos': row_ids,
                'indentation':
                [1 if v.id in table_views_map else 0 for v in views]
            })
    ])
Example #4
0
def migration1(tdset):
    """
  Add TabItems table, and populate based on existing sections.
  """
    doc_actions = []

    # The very first migration is extra-lax, and creates some tables that are missing in some test
    # docs. That's only because we did not distinguish schema version before migrations were
    # implemented. Other migrations should not need such conditionals.
    if '_grist_Attachments' not in tdset.all_tables:
        doc_actions.append(
            actions.AddTable("_grist_Attachments", [
                schema.make_column("fileIdent", "Text"),
                schema.make_column("fileName", "Text"),
                schema.make_column("fileType", "Text"),
                schema.make_column("fileSize", "Int"),
                schema.make_column("timeUploaded", "DateTime")
            ]))

    if '_grist_TabItems' not in tdset.all_tables:
        doc_actions.append(
            actions.AddTable("_grist_TabItems", [
                schema.make_column("tableRef", "Ref:_grist_Tables"),
                schema.make_column("viewRef", "Ref:_grist_Views"),
            ]))

    if 'schemaVersion' not in tdset.all_tables['_grist_DocInfo'].columns:
        doc_actions.append(add_column('_grist_DocInfo', 'schemaVersion',
                                      'Int'))

    doc_actions.extend([
        add_column('_grist_Attachments', 'imageHeight', 'Int'),
        add_column('_grist_Attachments', 'imageWidth', 'Int'),
    ])

    view_sections = actions.transpose_bulk_action(
        tdset.all_tables['_grist_Views_section'])
    rows = sorted({(s.tableRef, s.parentId) for s in view_sections})
    if rows:
        values = {
            'tableRef': [r[0] for r in rows],
            'viewRef': [r[1] for r in rows]
        }
        row_ids = list(xrange(1, len(rows) + 1))
        doc_actions.append(
            actions.ReplaceTableData('_grist_TabItems', row_ids, values))

    return tdset.apply_doc_actions(doc_actions)
Example #5
0
 def alist():
     return [
         actions.BulkUpdateRecord("Table1", [1, 2, 3],
                                  {'Foo': [10, 20, 30]}),
         actions.BulkUpdateRecord("Table2", [1, 2, 3], {
             'Foo': [10, 20, 30],
             'Bar': ['a', 'b', 'c']
         }),
         actions.UpdateRecord("Table1", 17, {'Foo': 10}),
         actions.UpdateRecord("Table2", 18, {
             'Foo': 10,
             'Bar': 'a'
         }),
         actions.AddRecord("Table1", 17, {'Foo': 10}),
         actions.BulkAddRecord("Table2", 18, {
             'Foo': 10,
             'Bar': 'a'
         }),
         actions.ReplaceTableData("Table2", 18, {
             'Foo': 10,
             'Bar': 'a'
         }),
         actions.RemoveRecord("Table1", 17),
         actions.BulkRemoveRecord("Table2", [17, 18]),
         actions.AddColumn("Table1", "Foo", {"type": "Text"}),
         actions.RenameColumn("Table1", "Foo", "Bar"),
         actions.ModifyColumn("Table1", "Foo", {"type": "Text"}),
         actions.RemoveColumn("Table1", "Foo"),
         actions.AddTable("THello", [{
             "id": "Foo"
         }, {
             "id": "Bar"
         }]),
         actions.RemoveTable("THello"),
         actions.RenameTable("THello", "TWorld"),
     ]
Example #6
0
 def create_tab_bar_action(views_to_table):
     row_ids = list(xrange(1, len(views_to_table) + 1))
     return actions.ReplaceTableData(
         '_grist_TabBar', row_ids,
         {'viewRef': sorted(views_to_table.keys())})
Example #7
0
    def test_prune_actions(self):
        # prune_actions is in-place, so we make a new list every time.
        def alist():
            return [
                actions.BulkUpdateRecord("Table1", [1, 2, 3],
                                         {'Foo': [10, 20, 30]}),
                actions.BulkUpdateRecord("Table2", [1, 2, 3], {
                    'Foo': [10, 20, 30],
                    'Bar': ['a', 'b', 'c']
                }),
                actions.UpdateRecord("Table1", 17, {'Foo': 10}),
                actions.UpdateRecord("Table2", 18, {
                    'Foo': 10,
                    'Bar': 'a'
                }),
                actions.AddRecord("Table1", 17, {'Foo': 10}),
                actions.BulkAddRecord("Table2", 18, {
                    'Foo': 10,
                    'Bar': 'a'
                }),
                actions.ReplaceTableData("Table2", 18, {
                    'Foo': 10,
                    'Bar': 'a'
                }),
                actions.RemoveRecord("Table1", 17),
                actions.BulkRemoveRecord("Table2", [17, 18]),
                actions.AddColumn("Table1", "Foo", {"type": "Text"}),
                actions.RenameColumn("Table1", "Foo", "Bar"),
                actions.ModifyColumn("Table1", "Foo", {"type": "Text"}),
                actions.RemoveColumn("Table1", "Foo"),
                actions.AddTable("THello", [{
                    "id": "Foo"
                }, {
                    "id": "Bar"
                }]),
                actions.RemoveTable("THello"),
                actions.RenameTable("THello", "TWorld"),
            ]

        def prune(table_id, col_id):
            a = alist()
            actions.prune_actions(a, table_id, col_id)
            return a

        self.assertEqual(
            prune('Table1', 'Foo'),
            [
                actions.BulkUpdateRecord("Table2", [1, 2, 3], {
                    'Foo': [10, 20, 30],
                    'Bar': ['a', 'b', 'c']
                }),
                actions.UpdateRecord("Table2", 18, {
                    'Foo': 10,
                    'Bar': 'a'
                }),
                actions.BulkAddRecord("Table2", 18, {
                    'Foo': 10,
                    'Bar': 'a'
                }),
                actions.ReplaceTableData("Table2", 18, {
                    'Foo': 10,
                    'Bar': 'a'
                }),
                actions.RemoveRecord("Table1", 17),
                actions.BulkRemoveRecord("Table2", [17, 18]),
                # It doesn't do anything with column renames; it can be addressed if needed.
                actions.RenameColumn("Table1", "Foo", "Bar"),
                # It doesn't do anything with AddTable, which is expected.
                actions.AddTable("THello", [{
                    "id": "Foo"
                }, {
                    "id": "Bar"
                }]),
                actions.RemoveTable("THello"),
                actions.RenameTable("THello", "TWorld"),
            ])

        self.assertEqual(prune('Table2', 'Foo'), [
            actions.BulkUpdateRecord("Table1", [1, 2, 3],
                                     {'Foo': [10, 20, 30]}),
            actions.BulkUpdateRecord("Table2", [1, 2, 3],
                                     {'Bar': ['a', 'b', 'c']}),
            actions.UpdateRecord("Table1", 17, {'Foo': 10}),
            actions.UpdateRecord("Table2", 18, {'Bar': 'a'}),
            actions.AddRecord("Table1", 17, {'Foo': 10}),
            actions.BulkAddRecord("Table2", 18, {'Bar': 'a'}),
            actions.ReplaceTableData("Table2", 18, {'Bar': 'a'}),
            actions.RemoveRecord("Table1", 17),
            actions.BulkRemoveRecord("Table2", [17, 18]),
            actions.AddColumn("Table1", "Foo", {"type": "Text"}),
            actions.RenameColumn("Table1", "Foo", "Bar"),
            actions.ModifyColumn("Table1", "Foo", {"type": "Text"}),
            actions.RemoveColumn("Table1", "Foo"),
            actions.AddTable("THello", [{
                "id": "Foo"
            }, {
                "id": "Bar"
            }]),
            actions.RemoveTable("THello"),
            actions.RenameTable("THello", "TWorld"),
        ])