func()

in memstore/schema.go [150:251]


func (m *memStoreImpl) applyTableSchema(newTable *metaCom.Table) {
	tableName := newTable.Name
	var newEnumColumns []string
	// default start watching from first enumCase
	startEnumID := 0
	defer func() {
		for _, column := range newEnumColumns {
			err := m.watchEnumCases(tableName, column, startEnumID)
			if err != nil {
				utils.GetLogger().With(
					"error", err.Error(),
					"table", tableName,
					"column", column).
					Panic("Failed to watch enum dict events")
			}
		}
	}()

	m.Lock()
	tableSchema, tableExist := m.TableSchemas[tableName]
	// new table
	if !tableExist {
		tableSchema = memCom.NewTableSchema(newTable)
		for columnID, column := range newTable.Columns {
			if !column.Deleted {
				if column.IsEnumBasedColumn() {
					var enumCases []string
					if column.DefaultValue != nil {
						enumCases = append(enumCases, *column.DefaultValue)
						// default value is already appended, start watching from 1
						startEnumID = 1
					}
					tableSchema.CreateEnumDict(column.Name, enumCases)
					newEnumColumns = append(newEnumColumns, column.Name)
				}
			}
			tableSchema.SetDefaultValue(columnID)
		}
		m.TableSchemas[newTable.Name] = tableSchema
		m.Unlock()
		return
	}
	m.Unlock()

	var columnsToDelete []int

	tableSchema.Lock()
	oldColumns := tableSchema.Schema.Columns
	tableSchema.SetTable(newTable)

	for columnID, column := range newTable.Columns {
		if column.Deleted {
			tableSchema.SetDefaultValue(columnID)
			if columnID < len(oldColumns) && !oldColumns[columnID].Deleted { // new deletions only
				delete(tableSchema.EnumDicts, column.Name)
				columnsToDelete = append(columnsToDelete, columnID)
			}
		} else {
			if column.IsEnumBasedColumn() {
				_, exist := tableSchema.EnumDicts[column.Name]
				if !exist {
					var enumCases []string
					if column.DefaultValue != nil {
						enumCases = append(enumCases, *column.DefaultValue)
						// default value is already appended, start watching from 1
						startEnumID = 1
					}
					tableSchema.CreateEnumDict(column.Name, enumCases)
					newEnumColumns = append(newEnumColumns, column.Name)
				}
			}
			// always set default value after enum map creation
			tableSchema.SetDefaultValue(columnID)
			var oldPreloadingDays int
			newPreloadingDays := column.Config.PreloadingDays
			// preloading will be triggered if
			// 1. this is a new column and PreloadingDays > 0
			// 2. this is a old column and PreloadingDays > oldPreloadingDays
			if columnID < len(oldColumns) {
				oldPreloadingDays = oldColumns[columnID].Config.PreloadingDays
			}
			m.HostMemManager.TriggerPreload(tableName, columnID, oldPreloadingDays, newPreloadingDays)
		}
	}
	tableSchema.Unlock()

	for _, columnID := range columnsToDelete {
		var shards []*TableShard
		m.RLock()
		for _, shard := range m.TableShards[tableName] {
			shard.Users.Add(1)
			shards = append(shards, shard)
		}
		m.RUnlock()

		for _, shard := range shards {
			// May block for extended amount of time during archiving
			shard.DeleteColumn(columnID)
			shard.Users.Done()
		}
	}
}