def MakeImportTransformColumns(self, hidden_table_id, transform_rule, gen_all): """ Makes prefixed columns in the grist hidden import table (hidden_table_id) hidden_table_id: id of temporary hidden table in which columns are made transform_rule: defines columns to make (colids must be filled in!) gen_all: If true, all columns will be generated If false, formulas that just copy will be skipped returns list of newly created colrefs (rowids into _grist_Tables_column) """ tables = self._docmodel.tables hidden_table_rec = tables.lookupOne(tableId=hidden_table_id) src_cols = {c.colId for c in hidden_table_rec.columns} log.debug("destCols:" + repr(transform_rule['destCols'])) #wrap dest_cols as namedtuples, to allow access like 'dest_col.param' dest_cols = [ namedtuple('col', c.keys())(*c.values()) for c in transform_rule['destCols'] ] log.debug("MakeImportTransformColumns: {}".format( "gen_all" if gen_all else "optimize")) #create prefixed formula column for each of dest_cols #take formula from transform_rule new_cols = [] for c in dest_cols: # skip copy columns (unless gen_all) formula = c.formula.strip() isCopyFormula = (formula.startswith("$") and formula[1:] in src_cols) if gen_all or not isCopyFormula: # If colId specified, use that. Otherwise, use the (sanitized) label. col_id = c.colId or identifiers.pick_col_ident(c.label) new_col_id = _import_transform_col_prefix + col_id new_col_spec = { "label": c.label, "type": c.type, "isFormula": True, "formula": c.formula } result = self._useractions.doAddColumn(hidden_table_id, new_col_id, new_col_spec) new_cols.append(result["colRef"]) return new_cols
def test_pick_col_ident(self): self.assertEqual(identifiers.pick_col_ident("asdf"), "asdf") self.assertEqual(identifiers.pick_col_ident(" a s==d!~@#$%^f"), "a_s_d_f") self.assertEqual(identifiers.pick_col_ident("123asdf"), "c123asdf") self.assertEqual(identifiers.pick_col_ident("!@#"), "A") self.assertEqual(identifiers.pick_col_ident("!@#1"), "c1") self.assertEqual(identifiers.pick_col_ident("heLLO world"), "heLLO_world") self.assertEqual(identifiers.pick_col_ident("!@#", avoid={"A"}), "B") self.assertEqual(identifiers.pick_col_ident("foo", avoid={"bar"}), "foo") self.assertEqual(identifiers.pick_col_ident("foo", avoid={"foo"}), "foo2") self.assertEqual( identifiers.pick_col_ident("foo", avoid={"foo", "foo2", "foo3"}), "foo4") self.assertEqual( identifiers.pick_col_ident("foo1", avoid={"foo1", "foo2", "foo1_2"}), "foo1_3") self.assertEqual(identifiers.pick_col_ident(""), "A") self.assertEqual(identifiers.pick_table_ident(""), "Table1") self.assertEqual(identifiers.pick_col_ident("", avoid={"A"}), "B") self.assertEqual(identifiers.pick_col_ident("", avoid={"A", "B"}), "C") self.assertEqual(identifiers.pick_col_ident(None, avoid={"A", "B"}), "C") self.assertEqual( identifiers.pick_col_ident("", avoid={'a', 'b', 'c', 'd', 'E'}), 'F') self.assertEqual(identifiers.pick_col_ident(2, avoid={"c2"}), "c2_2") large_set = set() for i in xrange(730): large_set.add(identifiers._gen_ident(large_set)) self.assertEqual(identifiers.pick_col_ident("", avoid=large_set), "ABC")
def migration10(tdset): """ Add displayCol to all reference cols, with formula $<ref_col_id>.<visible_col_id> (Note that displayCol field was added in the previous migration.) """ doc_actions = [] tables = list( actions.transpose_bulk_action(tdset.all_tables['_grist_Tables'])) columns = list( actions.transpose_bulk_action( tdset.all_tables['_grist_Tables_column'])) # Maps tableRef to tableId. tables_map = {t.id: t.tableId for t in tables} # Maps tableRef to sets of colIds in the tables. Used to prevent repeated colIds. table_col_ids = { t.id: set(tdset.all_tables[t.tableId].columns.keys()) for t in tables } # Get the next sequential column row id. row_id = next_id(tdset, '_grist_Tables_column') for c in columns: # If a column is a reference with an unset display column, add a display column. if c.type.startswith('Ref:') and not c.displayCol: # Get visible_col_id. If not found, row id is used and no display col is necessary. visible_col_id = "" try: visible_col_id = json.loads(c.widgetOptions).get('visibleCol') if not visible_col_id: continue except Exception: continue # If invalid widgetOptions, skip this column. # Set formula to use the current visibleCol in widgetOptions. formula = ("$%s.%s" % (c.colId, visible_col_id)) # Get a unique colId for the display column, and add it to the set of used ids. used_col_ids = table_col_ids[c.parentId] display_col_id = identifiers.pick_col_ident('gristHelper_Display', avoid=used_col_ids) used_col_ids.add(display_col_id) # Add all actions to the list. doc_actions.append( add_column(tables_map[c.parentId], 'gristHelper_Display', 'Any', formula=formula, isFormula=True)) doc_actions.append( actions.AddRecord( '_grist_Tables_column', row_id, { 'parentPos': 1.0, 'label': 'gristHelper_Display', 'isFormula': True, 'parentId': c.parentId, 'colId': 'gristHelper_Display', 'formula': formula, 'widgetOptions': '', 'type': 'Any' })) doc_actions.append( actions.UpdateRecord('_grist_Tables_column', c.id, {'displayCol': row_id})) # Increment row id to the next unused. row_id += 1 return tdset.apply_doc_actions(doc_actions)
def check(label, ident): self.assertEqual(ident, identifiers.pick_table_ident(label)) self.assertEqual(ident, identifiers.pick_col_ident(label)) self.assertEqual(ident.lower(), identifiers.pick_col_ident(label.lower()))