blob: df55748eabc12a6df94b453f5cfc7daab333fcaa [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { t } from '@superset-ui/core';
import getToastsFromPyFlashMessages from '../../messageToasts/utils/getToastsFromPyFlashMessages';
export default function getInitialState({
defaultDbId,
common,
active_tab: activeTab,
tab_state_ids: tabStateIds = [],
databases,
queries: queries_,
requested_query: requestedQuery,
user,
}) {
/**
* Before YYYY-MM-DD, the state for SQL Lab was stored exclusively in the
* browser's localStorage. The feature flag `SQLLAB_BACKEND_PERSISTENCE`
* moves the state to the backend instead, migrating it from local storage.
*
* To allow for a transparent migration, the initial state is a combination
* of the backend state (if any) with the browser state (if any).
*/
const queryEditors = [];
const defaultQueryEditor = {
id: null,
loaded: true,
title: t('Untitled query'),
sql: 'SELECT *\nFROM\nWHERE',
selectedText: null,
latestQueryId: null,
autorun: false,
templateParams: null,
dbId: defaultDbId,
functionNames: [],
queryLimit: common.conf.DEFAULT_SQLLAB_LIMIT,
validationResult: {
id: null,
errors: [],
completed: false,
},
queryCostEstimate: {
cost: null,
completed: false,
error: null,
},
};
/**
* Load state from the backend. This will be empty if the feature flag
* `SQLLAB_BACKEND_PERSISTENCE` is off.
*/
tabStateIds.forEach(({ id, label }) => {
let queryEditor;
if (activeTab && activeTab.id === id) {
queryEditor = {
id: id.toString(),
loaded: true,
title: activeTab.label,
sql: activeTab.sql,
selectedText: null,
latestQueryId: activeTab.latest_query
? activeTab.latest_query.id
: null,
autorun: activeTab.autorun,
templateParams: activeTab.template_params,
dbId: activeTab.database_id,
functionNames: [],
schema: activeTab.schema,
queryLimit: activeTab.query_limit,
validationResult: {
id: null,
errors: [],
completed: false,
},
};
} else {
// dummy state, actual state will be loaded on tab switch
queryEditor = {
...defaultQueryEditor,
id: id.toString(),
loaded: false,
title: label,
};
}
queryEditors.push(queryEditor);
});
const tabHistory = activeTab ? [activeTab.id.toString()] : [];
const tables = [];
if (activeTab) {
activeTab.table_schemas
.filter(tableSchema => tableSchema.description !== null)
.forEach(tableSchema => {
const {
columns,
selectStar,
primaryKey,
foreignKeys,
indexes,
dataPreviewQueryId,
} = tableSchema.description;
const table = {
dbId: tableSchema.database_id,
queryEditorId: tableSchema.tab_state_id.toString(),
schema: tableSchema.schema,
name: tableSchema.table,
expanded: tableSchema.expanded,
id: tableSchema.id,
isMetadataLoading: false,
isExtraMetadataLoading: false,
dataPreviewQueryId,
columns,
selectStar,
primaryKey,
foreignKeys,
indexes,
};
tables.push(table);
});
}
const queries = { ...queries_ };
/**
* If the `SQLLAB_BACKEND_PERSISTENCE` feature flag is off, or if the user
* hasn't used SQL Lab after it has been turned on, the state will be stored
* in the browser's local storage.
*/
if (
localStorage.getItem('redux') &&
JSON.parse(localStorage.getItem('redux')).sqlLab
) {
const { sqlLab } = JSON.parse(localStorage.getItem('redux'));
if (sqlLab.queryEditors.length === 0) {
// migration was successful
localStorage.removeItem('redux');
} else {
// add query editors and tables to state with a special flag so they can
// be migrated if the `SQLLAB_BACKEND_PERSISTENCE` feature flag is on
sqlLab.queryEditors.forEach(qe =>
queryEditors.push({
...qe,
inLocalStorage: true,
loaded: true,
}),
);
sqlLab.tables.forEach(table =>
tables.push({ ...table, inLocalStorage: true }),
);
Object.values(sqlLab.queries).forEach(query => {
queries[query.id] = { ...query, inLocalStorage: true };
});
tabHistory.push(...sqlLab.tabHistory);
}
}
return {
sqlLab: {
activeSouthPaneTab: 'Results',
alerts: [],
databases,
offline: false,
queries,
queryEditors,
tabHistory,
tables,
queriesLastUpdate: Date.now(),
user,
},
requestedQuery,
messageToasts: getToastsFromPyFlashMessages(
(common || {}).flash_messages || [],
),
localStorageUsageInKilobytes: 0,
common: {
flash_messages: common.flash_messages,
conf: common.conf,
},
};
}