Browse Source

fix: manage project env

re #588

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/616/head
Pranav C 3 years ago
parent
commit
caa3e9bb33
  1. 6
      packages/nc-gui/components/ProjectTreeView.vue
  2. 6
      packages/nc-gui/components/ProjectTreeViewOld.vue
  3. 6
      packages/nc-gui/components/changeEnv.vue
  4. 18
      packages/nc-gui/components/createOrEditProject.vue
  5. 2
      packages/nc-gui/components/project/apiClientOld.vue
  6. 2
      packages/nc-gui/components/project/apiClientSwagger.vue
  7. 6
      packages/nc-gui/components/project/settings/env.vue
  8. 143
      packages/nc-gui/components/project/settings/xcMeta.vue
  9. 6
      packages/nc-gui/components/project/tableTabs/columns.vue
  10. 4
      packages/nc-gui/components/project/tableTabs/webhook/httpWebhook.vue
  11. 6
      packages/nc-gui/helpers/newProjectJson.js
  12. 32
      packages/nc-gui/layouts/default.vue
  13. 10
      packages/nc-gui/pages/project/id.vue
  14. 6
      packages/nc-gui/pages/projects/index.vue
  15. 2
      packages/nc-gui/plugins/ncApis/index.js
  16. 56
      packages/nc-gui/store/tabs.js
  17. 4
      packages/nocodb/src/__tests__/graphql.test.ts
  18. 4
      packages/nocodb/src/__tests__/rest.test.ts
  19. 4
      packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/mssql.template.ts
  20. 4
      packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/mysql.template.ts
  21. 4
      packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/pg.template.ts
  22. 4
      packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/sqlite.template.ts
  23. 15
      packages/nocodb/src/lib/noco/Noco.ts
  24. 6
      packages/nocodb/src/lib/noco/common/NcConnectionMgr.ts
  25. 3
      packages/nocodb/src/lib/noco/meta/NcMetaIO.ts
  26. 310
      packages/nocodb/src/lib/noco/meta/NcMetaIOImpl.ts
  27. 6
      packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts
  28. 96
      packages/nocodb/src/lib/noco/upgrader/NcUpgrader.ts
  29. 20
      packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectEnvUpgrader.ts
  30. 10
      packages/nocodb/src/lib/sqlMgr/SqlMgr.ts
  31. 69
      packages/nocodb/src/lib/utils/NcConfigFactory.ts

6
packages/nc-gui/components/ProjectTreeView.vue

@ -837,7 +837,7 @@ export default {
} else {
console.log('add app store tab');
let item = { name: 'App Store', key: `appStore` };
item._nodes = { env: 'dev' };
item._nodes = { env: '_noco' };
item._nodes.type = 'appStore';
this.$store.dispatch('tabs/ActAddTab', item);
}
@ -873,7 +873,7 @@ export default {
} else {
console.log('add roles tab');
let item = { name: 'Team & Auth ', key: `roles` };
item._nodes = { env: 'dev' };
item._nodes = { env: '_noco' };
item._nodes.type = 'roles';
this.$store.dispatch('tabs/ActAddTab', item);
}
@ -885,7 +885,7 @@ export default {
} else {
console.log('add acl tab');
let item = { name: 'Meta Management', key: `disableOrEnableModel` };
item._nodes = { env: 'dev' };
item._nodes = { env: '_noco' };
item._nodes.type = 'disableOrEnableModel';
this.$store.dispatch('tabs/ActAddTab', item);
}

6
packages/nc-gui/components/ProjectTreeViewOld.vue

@ -351,7 +351,7 @@ export default {
} else {
console.log('add roles tab');
let item = {name: 'Settings', key: `projectSettings`}
item._nodes = {env: 'dev'};
item._nodes = {env: '_noco'};
item._nodes.type = 'projectSettings';
this.$store.dispatch("tabs/ActAddTab", item);
}
@ -365,7 +365,7 @@ export default {
} else {
console.log('add roles tab');
let item = {name: 'Team & Auth ', key: `roles`}
item._nodes = {env: 'dev'};
item._nodes = {env: '_noco'};
item._nodes.type = 'roles';
this.$store.dispatch("tabs/ActAddTab", item);
}
@ -378,7 +378,7 @@ export default {
} else {
console.log('add acl tab');
let item = {name: 'Meta Management', key: `disableOrEnableModel`}
item._nodes = {env: 'dev'};
item._nodes = {env: '_noco'};
item._nodes.type = 'disableOrEnableModel';
this.$store.dispatch("tabs/ActAddTab", item);
}

6
packages/nc-gui/components/changeEnv.vue

@ -44,7 +44,7 @@ import axios from 'axios'
export default {
name: 'ChangeEnv',
data: () => ({
selectedEnv: 'dev',
selectedEnv: '_noco',
progressbar: false
}),
computed: {
@ -64,12 +64,12 @@ export default {
const unserializedList = this.$store.state.project.unserializedList
this.selectedEnv = (unserializedList[0] &&
unserializedList[0].projectJson &&
unserializedList[0].projectJson.workingEnv) || 'dev'
unserializedList[0].projectJson.workingEnv) || '_noco'
this.$store.watch((state) => {
const unserializedList = state.project.unserializedList
return (unserializedList[0] &&
unserializedList[0].projectJson &&
unserializedList[0].projectJson.workingEnv) || 'dev'
unserializedList[0].projectJson.workingEnv) || '_noco'
}, (value) => { this.selectedEnv = value })
},
methods: {

18
packages/nc-gui/components/createOrEditProject.vue

@ -982,20 +982,20 @@
</template>
<script>
import JSON5 from 'json5'
import readFile from '@/helpers/fileReader'
import { mapGetters, mapActions } from 'vuex'
import Vue from 'vue'
import { v4 as uuidv4 } from 'uuid'
import XBtn from './global/xBtn'
import dlgOk from './utils/dlgOk.vue'
import textDlgSubmitCancel from './utils/dlgTextSubmitCancel'
import MonacoJsonObjectEditor from '@/components/monaco/MonacoJsonObjectEditor'
import ApiOverlay from '@/components/apiOverlay'
import colors from '@/mixins/colors'
import DlgOkNew from '@/components/utils/dlgOkNew'
import XBtn from './global/xBtn'
import dlgOk from './utils/dlgOk.vue'
import textDlgSubmitCancel from './utils/dlgTextSubmitCancel'
import readFile from '@/helpers/fileReader'
const { uniqueNamesGenerator, starWars, adjectives, animals } = require('unique-names-generator')
@ -1088,7 +1088,7 @@ export default {
version: '0.6',
folder: homeDir,
envs: {
dev: {
_noco: {
db: [
{
client: 'pg',
@ -1133,10 +1133,10 @@ export default {
}
}
},
workingEnv: 'dev',
workingEnv: '_noco',
ui: {
envs: {
dev: {}
_noco: {}
}
},
meta: {
@ -1573,7 +1573,7 @@ export default {
p.ui = {
envs: {
dev: {}
_noco: {}
}
}
for (const env in p.envs) {
@ -1840,7 +1840,7 @@ export default {
if (
db.connection.host === 'localhost' &&
!this.edit &&
env === 'dev' &&
env === '_noco' &&
this.project.envs[env].db.length === 1 &&
this.project.envs[env].db[0].connection.user === 'postgres' &&
this.project.envs[env].db[0].connection.database ===

2
packages/nc-gui/components/project/apiClientOld.vue

@ -357,7 +357,7 @@
</splitpanes>
</pane>
</splitpanes>
<environment v-if="$store.getters['project/GtrProjectJson']" v-model="environmentDialog" env="dev" />
<environment v-if="$store.getters['project/GtrProjectJson']" v-model="environmentDialog" env="_noco" />
</v-container>
</template>
<script>

2
packages/nc-gui/components/project/apiClientSwagger.vue

@ -558,7 +558,7 @@
</splitpanes>
</pane>
</splitpanes>
<environment v-model="environmentDialog" env="dev" />
<environment v-model="environmentDialog" env="_noco" />
<v-dialog v-model="bookmarkApiDialog" max-width="500">
<v-card>

6
packages/nc-gui/components/project/settings/env.vue

@ -40,7 +40,7 @@ import axios from 'axios'
export default {
name: 'Env',
data: () => ({
selectedEnv: 'dev',
selectedEnv: '_noco',
progressbar: false
}),
computed: {
@ -52,12 +52,12 @@ export default {
const unserializedList = this.$store.state.project.unserializedList
this.selectedEnv = (unserializedList[0] &&
unserializedList[0].projectJson &&
unserializedList[0].projectJson.workingEnv) || 'dev'
unserializedList[0].projectJson.workingEnv) || '_noco'
this.$store.watch((state) => {
const unserializedList = state.project.unserializedList
return (unserializedList[0] &&
unserializedList[0].projectJson &&
unserializedList[0].projectJson.workingEnv) || 'dev'
unserializedList[0].projectJson.workingEnv) || '_noco'
}, (value) => { this.selectedEnv = value })
},
methods: {

143
packages/nc-gui/components/project/settings/xcMeta.vue

@ -12,52 +12,52 @@
<!-- </tr>-->
<!-- </thead>-->
<tbody>
<!-- <tr>-->
<!-- <td>-->
<!-- &lt;!&ndash; Export all metadata from the meta tables to meta directory. &ndash;&gt;-->
<!-- {{ $t('management.meta.export_to_file.desc') }}-->
<!-- </td>-->
<!-- <td>-->
<!-- <v-btn-->
<!-- min-width="150"-->
<!-- color="primary"-->
<!-- small-->
<!-- outlined-->
<!-- :loading="loading === 'export-file'"-->
<!-- @click="exportMeta"-->
<!-- >-->
<!-- <v-icon small>-->
<!-- mdi-export-->
<!-- </v-icon>&nbsp;-->
<!-- &lt;!&ndash; Export to file &ndash;&gt;-->
<!-- {{ $t('management.meta.export_to_file.title') }}-->
<!-- </v-btn>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>-->
<!-- &lt;!&ndash; Export all metadata from the meta tables to meta directory. &ndash;&gt;-->
<!-- {{ $t('management.meta.export_to_file.desc') }}-->
<!-- </td>-->
<!-- <td>-->
<!-- <v-btn-->
<!-- min-width="150"-->
<!-- color="primary"-->
<!-- small-->
<!-- outlined-->
<!-- :loading="loading === 'export-file'"-->
<!-- @click="exportMeta"-->
<!-- >-->
<!-- <v-icon small>-->
<!-- mdi-export-->
<!-- </v-icon>&nbsp;-->
<!-- &lt;!&ndash; Export to file &ndash;&gt;-->
<!-- {{ $t('management.meta.export_to_file.title') }}-->
<!-- </v-btn>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>-->
<!-- &lt;!&ndash; Import all metadata from the meta directory to meta tables. &ndash;&gt;-->
<!-- {{ $t('management.meta.import.desc') }}-->
<!-- </td>-->
<!-- <td>-->
<!-- <v-btn-->
<!-- :loading="loading === 'import-file'"-->
<!-- min-width="150"-->
<!-- color="info"-->
<!-- small-->
<!-- outlined-->
<!-- @click="importMeta"-->
<!-- >-->
<!-- <v-icon small>-->
<!-- mdi-import-->
<!-- </v-icon>&nbsp;-->
<!-- <tr>-->
<!-- <td>-->
<!-- &lt;!&ndash; Import all metadata from the meta directory to meta tables. &ndash;&gt;-->
<!-- {{ $t('management.meta.import.desc') }}-->
<!-- </td>-->
<!-- <td>-->
<!-- <v-btn-->
<!-- :loading="loading === 'import-file'"-->
<!-- min-width="150"-->
<!-- color="info"-->
<!-- small-->
<!-- outlined-->
<!-- @click="importMeta"-->
<!-- >-->
<!-- <v-icon small>-->
<!-- mdi-import-->
<!-- </v-icon>&nbsp;-->
<!-- &lt;!&ndash; Import &ndash;&gt;-->
<!-- {{ $t('management.meta.import.title') }}-->
<!-- </v-btn>-->
<!-- </td>-->
<!-- </tr>-->
<!-- &lt;!&ndash; Import &ndash;&gt;-->
<!-- {{ $t('management.meta.import.title') }}-->
<!-- </v-btn>-->
<!-- </td>-->
<!-- </tr>-->
<tr>
<td>
@ -112,28 +112,28 @@
>
</td>
</tr>
<!-- <tr>-->
<!-- <td>-->
<!-- &lt;!&ndash; Clear all metadata from meta tables. &ndash;&gt;-->
<!-- {{ $t('management.meta.reset.desc') }}-->
<!-- </td>-->
<!-- <td>-->
<!-- <v-btn-->
<!-- :loading="loading === 'reset-metadata'"-->
<!-- min-width="150"-->
<!-- color="error"-->
<!-- small-->
<!-- outlined-->
<!-- @click="resetMeta"-->
<!-- >-->
<!-- <v-icon small>-->
<!-- mdi-delete-variant-->
<!-- </v-icon>&nbsp;-->
<!-- &lt;!&ndash; Reset &ndash;&gt;-->
<!-- {{ $t('management.meta.reset.title') }}-->
<!-- </v-btn>-->
<!-- </td>-->
<!-- </tr>-->
<!-- <tr>-->
<!-- <td>-->
<!-- &lt;!&ndash; Clear all metadata from meta tables. &ndash;&gt;-->
<!-- {{ $t('management.meta.reset.desc') }}-->
<!-- </td>-->
<!-- <td>-->
<!-- <v-btn-->
<!-- :loading="loading === 'reset-metadata'"-->
<!-- min-width="150"-->
<!-- color="error"-->
<!-- small-->
<!-- outlined-->
<!-- @click="resetMeta"-->
<!-- >-->
<!-- <v-icon small>-->
<!-- mdi-delete-variant-->
<!-- </v-icon>&nbsp;-->
<!-- &lt;!&ndash; Reset &ndash;&gt;-->
<!-- {{ $t('management.meta.reset.title') }}-->
<!-- </v-btn>-->
<!-- </td>-->
<!-- </tr>-->
</tbody>
</v-simple-table>
@ -171,10 +171,11 @@ export default {
} else {
this.loading = 'export-file'
try {
// todo: set env based on `nodes` prop
await this.$store.dispatch('sqlMgr/ActSqlOp', [
{
// dbAlias: 'db',
env: 'dev'
env: '_noco'
},
'xcMetaTablesExportDbToLocalFs'
])
@ -200,7 +201,7 @@ export default {
data = await this.$store.dispatch('sqlMgr/ActSqlOp', [
{
// dbAlias: 'db',
env: 'dev'
env: '_noco'
},
'xcMetaTablesExportDbToZip',
null,
@ -236,7 +237,7 @@ export default {
await this.$store.dispatch('sqlMgr/ActSqlOp', [
{
// dbAlias: 'db',
env: 'dev'
env: '_noco'
},
'xcMetaTablesReset'
])
@ -261,7 +262,7 @@ export default {
try {
await this.$store.dispatch('sqlMgr/ActSqlOp', [
{
env: 'dev'
env: '_noco'
},
'xcMetaTablesImportLocalFsToDb'
])
@ -283,7 +284,7 @@ export default {
this.$refs.importFile.value = ''
await this.$store.dispatch('sqlMgr/ActUpload', [
{
env: 'dev'
env: '_noco'
},
'xcMetaTablesImportZipToLocalFsAndDb',
{

6
packages/nc-gui/components/project/tableTabs/columns.vue

@ -709,12 +709,12 @@
<script>
import { mapGetters, mapActions } from 'vuex'
import JSON5 from 'json5'
import uiTypes from '@/components/project/spreadsheet/helpers/uiTypes'
import addRelationDlg from '../dlgs/dlgAddRelation.vue'
import dlgLabelSubmitCancel from '../../utils/dlgLabelSubmitCancel.vue'
import { SqlUI } from '../../../helpers/sqlUi/SqlUiFactory'
import jsonToColumn from './columnActions/jsonToColumn'
import uiTypes from '@/components/project/spreadsheet/helpers/uiTypes'
// const {path} = require("electron").remote.require(
// "./libs"
@ -793,7 +793,7 @@ export default {
null,
'projectGenerateBackend',
{
env: 'dev',
env: '_noco',
tn: this.nodes.tn,
scaffold
}
@ -816,7 +816,7 @@ export default {
null,
'projectGenerateBackendGql',
{
env: 'dev',
env: '_noco',
tn: this.nodes.tn,
scaffold
}

4
packages/nc-gui/components/project/tableTabs/webhook/httpWebhook.vue

@ -118,8 +118,8 @@ export default {
color: 'info'
}
},
selectedEnv: 'dev',
environmentList: ['dev'],
selectedEnv: '_noco',
environmentList: ['_noco'],
// current api
api: {
method: 'GET',

6
packages/nc-gui/helpers/newProjectJson.js

@ -5,7 +5,7 @@ export default {
type: 'project',
children: [
{
name: 'dev',
name: '_noco',
type: 'env',
children: [
{
@ -41,7 +41,7 @@ export default {
type: 'project',
children: [
{
name: 'dev',
name: '_noco',
type: 'env',
children: [
{
@ -95,7 +95,7 @@ export default {
type: 'project',
children: [
{
name: 'dev',
name: '_noco',
type: 'env',
children: [
{

32
packages/nc-gui/layouts/default.vue

@ -607,10 +607,10 @@ export default {
error: null,
dialogErrorShow: false,
dialogDebug: false,
migrationsMenu: [
{ name: 'dev', children: [{ name: 'db-1' }, { name: 'db-2' }] },
{ name: 'test', children: [{ name: 'db-1' }, { name: 'db-2' }] }
],
// migrationsMenu: [
// { name: 'dev', children: [{ name: 'db-1' }, { name: 'db-2' }] },
// { name: 'test', children: [{ name: 'db-1' }, { name: 'db-2' }] }
// ],
clipped: false,
drawer: null,
fixed: false,
@ -801,7 +801,7 @@ export default {
} else {
console.log('add terminal tab')
const item = { name: 'API Client', key: 'apiClientDir' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'apiClientDir'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -817,7 +817,7 @@ export default {
} else {
console.log('add terminal tab')
const item = { name: 'API Client', key: 'apiClientSwaggerDir' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'apiClientSwaggerDir'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -832,7 +832,7 @@ export default {
} else {
console.log('add project info tab')
const item = { name: 'Info', key: 'projectInfo' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'projectInfo'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -844,7 +844,7 @@ export default {
this.changeActiveTab(tabIndex)
} else {
const item = { name: 'Meta', key: 'meta' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'meta'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -888,7 +888,7 @@ export default {
} else {
console.log('add grpc tab')
const item = { name: 'gRPC Client', key: 'grpcClient' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'grpcClient'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -900,7 +900,7 @@ export default {
} else {
console.log('add roles tab')
const item = { name: 'Team & Auth ', key: 'roles' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'roles'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -915,7 +915,7 @@ export default {
} else {
console.log('add roles tab')
const item = { name: 'Themes', key: 'projectSettings' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'projectSettings'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -927,7 +927,7 @@ export default {
} else {
console.log('add acl tab')
const item = { name: 'ACL', key: 'acl' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'acl'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -939,7 +939,7 @@ export default {
} else {
console.log('add acl tab')
const item = { name: 'Meta Management', key: 'disableOrEnableModel' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'disableOrEnableModel'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -951,7 +951,7 @@ export default {
} else {
console.log('add cron job tab')
const item = { name: 'Cron Jobs', key: 'cronJobs' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'cronJobs'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -963,7 +963,7 @@ export default {
} else {
console.log('add app store tab')
const item = { name: 'App Store', key: 'appStore' }
item._nodes = { env: 'dev' }
item._nodes = { env: '_noco' }
item._nodes.type = 'appStore'
this.$store.dispatch('tabs/ActAddTab', item)
}
@ -971,7 +971,7 @@ export default {
async codeGenerateMvc() {
try {
await this.sqlMgr.projectGenerateBackend({
env: 'dev'
env: '_noco'
})
this.$toast.success('Yay, REST APIs with MVC generated').goAway(4000)
} catch (e) {

10
packages/nc-gui/pages/project/id.vue

@ -671,7 +671,7 @@ export default {
title: '',
folder: homeDir,
envs: {
dev: {
_noco: {
db: [
{
client: 'pg',
@ -715,10 +715,10 @@ export default {
}
}
},
workingEnv: 'dev',
workingEnv: '_noco',
ui: {
envs: {
dev: {}
_noco: {}
}
},
@ -1031,7 +1031,7 @@ export default {
p.ui = {
envs: {
dev: {}
_noco: {}
}
}
for (const env in p.envs) {
@ -1306,7 +1306,7 @@ export default {
console.log(this.project.envs[env][0])
if (db.connection.host === 'localhost' &&
!this.edit &&
env === 'dev' &&
env === '_noco' &&
this.project.envs[env].db.length === 1 &&
this.project.envs[env].db[0].connection.user === 'postgres' &&
this.project.envs[env].db[0].connection.database === `${this.project.title}_${env}_${this.project.envs[env].length}`) {

6
packages/nc-gui/pages/projects/index.vue

@ -1039,7 +1039,7 @@ export default {
{
// dbAlias: 'db',
project_id: projectId,
env: 'dev'
env: '_noco'
},
'xcMetaTablesExportDbToZip',
null,
@ -1079,7 +1079,7 @@ export default {
await this.$store.dispatch('sqlMgr/ActSqlOp', [
{
// dbAlias: 'db',
env: 'dev',
env: '_noco',
project_id: projectId
},
'xcMetaTablesReset'
@ -1108,7 +1108,7 @@ export default {
{
// dbAlias: 'db',
project_id: projectId,
env: 'dev'
env: '_noco'
},
'xcMetaTablesImportZipToLocalFsAndDb',
{},

2
packages/nc-gui/plugins/ncApis/index.js

@ -5,7 +5,7 @@ export default function({ store: $store, $axios, ...rest }, inject) {
let projectId = null
inject('ncApis', {
get: ({ table, dbAlias = 'db', env = 'dev' }) => {
get: ({ table, dbAlias = 'db', env = '_noco' }) => {
if (!$store.state.meta.metas[table]) {
return
}

56
packages/nc-gui/store/tabs.js

@ -95,13 +95,13 @@ export const actions = {
switch (type) {
case 'table':
await dispatch('project/_loadTables', {
dbKey: '0.projectJson.envs.dev.db.0',
key: '0.projectJson.envs.dev.db.0.tables',
dbKey: '0.projectJson.envs._noco.db.0',
key: '0.projectJson.envs._noco.db.0.tables',
_nodes: {
dbAlias: dbalias,
// dbKey: "0.projectJson.envs.dev.db.0",
env: 'dev',
// key: "0.projectJson.envs.dev.db.0.tables",
// dbKey: "0.projectJson.envs._noco.db.0",
env: '_noco',
// key: "0.projectJson.envs._noco.db.0.tables",
type: 'tableDir'
}
}, { root: true })
@ -115,13 +115,13 @@ export const actions = {
break
case 'view':
await dispatch('project/_loadViews', {
dbKey: '0.projectJson.envs.dev.db.0',
key: '0.projectJson.envs.dev.db.0.views',
dbKey: '0.projectJson.envs._noco.db.0',
key: '0.projectJson.envs._noco.db.0.views',
_nodes: {
dbAlias: dbalias,
// dbKey: "0.projectJson.envs.dev.db.0",
env: 'dev',
// key: "0.projectJson.envs.dev.db.0.tables",
// dbKey: "0.projectJson.envs._noco.db.0",
env: '_noco',
// key: "0.projectJson.envs._noco.db.0.tables",
type: 'viewDir'
}
}, { root: true })
@ -135,13 +135,13 @@ export const actions = {
break
case 'function':
await dispatch('project/_loadFunctions', {
dbKey: '0.projectJson.envs.dev.db.0',
key: '0.projectJson.envs.dev.db.0.functions',
dbKey: '0.projectJson.envs._noco.db.0',
key: '0.projectJson.envs._noco.db.0.functions',
_nodes: {
dbAlias: dbalias,
// dbKey: "0.projectJson.envs.dev.db.0",
env: 'dev',
// key: "0.projectJson.envs.dev.db.0.tables",
// dbKey: "0.projectJson.envs._noco.db.0",
env: '_noco',
// key: "0.projectJson.envs._noco.db.0.tables",
type: 'functionDir'
}
}, { root: true })
@ -159,13 +159,13 @@ export const actions = {
break
case 'procedure':
await dispatch('project/_loadProcedures', {
dbKey: '0.projectJson.envs.dev.db.0',
key: '0.projectJson.envs.dev.db.0.procedures',
dbKey: '0.projectJson.envs._noco.db.0',
key: '0.projectJson.envs._noco.db.0.procedures',
_nodes: {
dbAlias: dbalias,
// dbKey: "0.projectJson.envs.dev.db.0",
env: 'dev',
// key: "0.projectJson.envs.dev.db.0.tables",
// dbKey: "0.projectJson.envs._noco.db.0",
env: '_noco',
// key: "0.projectJson.envs._noco.db.0.tables",
type: 'procedureDir'
}
}, { root: true })
@ -178,13 +178,13 @@ export const actions = {
break
case 'sequence':
await dispatch('project/_loadFunctions', {
dbKey: '0.projectJson.envs.dev.db.0',
key: '0.projectJson.envs.dev.db.0.sequences',
dbKey: '0.projectJson.envs._noco.db.0',
key: '0.projectJson.envs._noco.db.0.sequences',
_nodes: {
dbAlias: dbalias,
// dbKey: "0.projectJson.envs.dev.db.0",
env: 'dev',
// key: "0.projectJson.envs.dev.db.0.tables",
// dbKey: "0.projectJson.envs._noco.db.0",
env: '_noco',
// key: "0.projectJson.envs._noco.db.0.tables",
type: 'sequenceDir'
}
}, { root: true })
@ -213,7 +213,7 @@ export const actions = {
name: 'gRPC Client',
key: 'grpcClient',
_nodes: {
env: 'dev',
env: '_noco',
type: 'grpcClient'
}
}
@ -223,7 +223,7 @@ export const actions = {
name: 'Graphql Client',
key: 'graphqlClientDir',
_nodes: {
env: 'dev',
env: '_noco',
type: 'graphqlClientDir'
}
}
@ -234,7 +234,7 @@ export const actions = {
name: 'Team & Auth ',
key: 'roles',
_nodes: {
env: 'dev',
env: '_noco',
type: 'roles'
}
})

4
packages/nocodb/src/__tests__/graphql.test.ts

@ -19,13 +19,13 @@ const projectCreateReqBody = {
"title": "sebulba",
"version": "0.6",
"envs": {
"dev": {
"_noco": {
"db": [
dbConfig
], "apiClient": {"data": []}
}
},
"workingEnv": "dev",
"workingEnv": "_noco",
"meta": {
"version": "0.6",
"seedsFolder": "seeds",

4
packages/nocodb/src/__tests__/rest.test.ts

@ -19,7 +19,7 @@ const projectCreateReqBody = {
"title": "sebulba",
"version": "0.6",
"envs": {
"dev": {
"_noco": {
"db": [
dbConfig
// {
@ -42,7 +42,7 @@ const projectCreateReqBody = {
], "apiClient": {"data": []}
}
},
"workingEnv": "dev",
"workingEnv": "_noco",
"meta": {
"version": "0.6",
"seedsFolder": "seeds",

4
packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/mssql.template.ts

@ -3,7 +3,7 @@
module.exports = {
title: "default",
envs: {
dev: {
_noco: {
api:{},
db: [
{
@ -42,7 +42,7 @@ module.exports = {
]
}
},
workingEnv: "dev",
workingEnv: "_noco",
meta: {
version: '0.5',
seedsFolder: 'seeds',

4
packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/mysql.template.ts

@ -3,7 +3,7 @@
module.exports = {
title: "default",
envs: {
dev: {
_noco: {
db: [
{
client: "mysql2",
@ -41,7 +41,7 @@ module.exports = {
]
}
},
workingEnv: "dev",
workingEnv: "_noco",
meta: {
version: '0.5',
seedsFolder: 'seeds',

4
packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/pg.template.ts

@ -3,7 +3,7 @@ const {DOCKER_DB_HOST, DOCKER_DB_PORT} = process.env;
module.exports = {
title: "default",
envs: {
dev: {
_noco: {
db: [
{
client: "pg",
@ -40,7 +40,7 @@ module.exports = {
]
}
},
workingEnv: "dev",
workingEnv: "_noco",
meta: {
version: '0.5',
seedsFolder: 'seeds',

4
packages/nocodb/src/lib/migrator/SqlMigrator/lib/templates/sqlite.template.ts

@ -5,7 +5,7 @@ const {DOCKER_DB_FILE} = process.env;
module.exports = {
title: "default",
envs: {
dev: {
_noco: {
db: [
{
client: "sqlite3",
@ -47,7 +47,7 @@ module.exports = {
]
}
},
workingEnv: "dev",
workingEnv: "_noco",
meta: {
version: '0.5',
seedsFolder: 'seeds',

15
packages/nocodb/src/lib/noco/Noco.ts

@ -33,6 +33,7 @@ import RestAuthCtrlCE from "./rest/RestAuthCtrl";
import RestAuthCtrlEE from "./rest/RestAuthCtrlEE";
import mkdirp from 'mkdirp';
import MetaAPILogger from "./meta/MetaAPILogger";
import NcUpgrader from "./upgrader/NcUpgrader";
const log = debug('nc:app');
require('dotenv').config();
@ -45,8 +46,11 @@ export default class Noco {
public static get dashboardUrl(): string {
let siteUrl = `http://localhost:${process.env.PORT || 8080}`;
if (Noco._this?.config?.envs?.[Noco._this?.env]?.publicUrl) {
siteUrl = Noco._this?.config?.envs?.[Noco._this?.env]?.publicUrl;
// if (Noco._this?.config?.envs?.[Noco._this?.env]?.publicUrl) {
// siteUrl = Noco._this?.config?.envs?.[Noco._this?.env]?.publicUrl;
// }
if (Noco._this?.config?.envs?.['_noco']?.publicUrl) {
siteUrl = Noco._this?.config?.envs?.['_noco']?.publicUrl;
}
return `${siteUrl}${Noco._this?.config?.dashboardPath}`
@ -86,7 +90,7 @@ export default class Noco {
process.env.PORT = process.env.PORT || '8080';
// todo: move
process.env.NC_VERSION = '0009044';
process.env.NC_VERSION = '0011043';
this.router = express.Router();
this.projectRouter = express.Router();
@ -95,7 +99,7 @@ export default class Noco {
this.config = NcConfigFactory.make();
/******************* setup : start *******************/
this.env = process.env['NODE_ENV'] || this.config.workingEnv || 'dev';
this.env = '_noco';//process.env['NODE_ENV'] || this.config.workingEnv || 'dev';
this.config.workingEnv = this.env;
this.config.type = 'docker';
@ -152,6 +156,7 @@ export default class Noco {
log('Initializing app');
// create tool directory if missing
mkdirp.sync(this.config.toolDir);
@ -172,6 +177,8 @@ export default class Noco {
await this.readOrGenJwtSecret();
await NcUpgrader.upgrade({ncMeta: this.ncMeta})
if (args?.afterMetaMigrationInit) {
await args.afterMetaMigrationInit();
}

6
packages/nocodb/src/lib/noco/common/NcConnectionMgr.ts

@ -24,7 +24,7 @@ export default class NcConnectionMgr {
public static delete({
dbAlias = 'db',
env = 'dev',
env = '_noco',
projectId
}: {
dbAlias: string,
@ -45,7 +45,7 @@ export default class NcConnectionMgr {
public static get({
dbAlias = 'db',
env = 'dev',
env = '_noco',
config,
projectId
}: {
@ -120,7 +120,7 @@ export default class NcConnectionMgr {
public static getSqlClient({
projectId,
dbAlias = 'db',
env = 'dev',
env = '_noco',
config
}: {
dbAlias: string,

3
packages/nocodb/src/lib/noco/meta/NcMetaIO.ts

@ -1,5 +1,6 @@
import {NcConfig} from "../../../interface/config";
import Noco from "../Noco";
import {XKnex} from "../../dataMapper";
const META_TABLES = {
graphql: ['nc_models', 'nc_resolvers', 'nc_loaders', 'nc_store', 'nc_hooks', 'nc_roles', 'nc_acl', 'nc_api_tokens', 'nc_relations', 'nc_migrations',
@ -19,6 +20,8 @@ export default abstract class NcMetaIO {
protected app: Noco;
protected config: NcConfig;
public abstract get knexConnection(): XKnex ;
constructor(app: Noco, config: NcConfig) {
this.app = app;
this.config = config;

310
packages/nocodb/src/lib/noco/meta/NcMetaIOImpl.ts

@ -3,7 +3,6 @@ import {nanoid} from 'nanoid';
import {NcConfig} from "../../../interface/config";
import {Knex, XKnex} from "../../dataMapper";
import NcHelp from "../../utils/NcHelp";
import Noco from "../Noco";
import XcMigrationSource from "../common/XcMigrationSource";
@ -80,7 +79,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
NcConnectionMgr.setXcMeta(this);
}
private get knexConnection(): XKnex {
public get knexConnection(): XKnex {
return (this.trx || this.connection) as any;
}
@ -96,279 +95,6 @@ export default class NcMetaIOImpl extends NcMetaIO {
return true;
}
public async metaInitOld(): Promise<boolean> {
let freshlyStarted = false;
if (!(await this.knexConnection.schema.hasTable('nc_projects'))) {
await this.knexConnection.schema.createTable('nc_projects', table => {
table.increments();
table.string('title');
table.text('description');
table.text('meta');
table.timestamps();
})
}
if (!(await this.knexConnection.schema.hasTable('nc_roles'))) {
freshlyStarted = true;
await this.knexConnection.schema.createTable('nc_roles', table => {
table.increments();
table.string('project_id').defaultTo('default');
table.string('db_alias').defaultTo('db');
table.string('title');
table.string('type').defaultTo('CUSTOM');
table.string('description');
table.timestamps();
});
await this.knexConnection('nc_roles').insert([
{db_alias: '', title: 'owner', description: 'Super Admin user of the app', type: 'SYSTEM'},
{db_alias: '', title: 'creator', description: 'Admin user of the app', type: 'SYSTEM'},
{db_alias: '', title: 'editor', description: 'Registered app users', type: 'SYSTEM'},
{db_alias: '', title: 'guest', description: 'Unauthenticated public user', type: 'SYSTEM'},
])
}
if (!(await this.knexConnection.schema.hasTable('nc_hooks'))) {
await this.knexConnection.schema.createTable('nc_hooks', table => {
table.increments();
table.string('project_id').defaultTo('default');
table.string('db_alias').defaultTo('db')
table.string('title');
table.string('description', 255);
table.string('env').defaultTo('all');
table.string('tn');
table.string('event');
table.string('operation');
table.boolean('async').defaultTo(false);
table.boolean('payload').defaultTo(true);
table.text('url', 'text');
table.text('headers', 'text');
table.integer('retries').defaultTo(0);
table.integer('retry_interval').defaultTo(60000);
table.integer('timeout').defaultTo(60000);
table.boolean('active').defaultTo(true);
table.timestamps();
})
}
if (!(await this.knexConnection.schema.hasTable('nc_store'))) {
await this.knexConnection.schema.createTable('nc_store', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('key').index();
table.text('value', 'text');
table.string('type');
table.string('env');
table.string('tag');
table.timestamps();
})
await this.knexConnection('nc_store').insert({
key: 'NC_DEBUG',
value: JSON.stringify({
'nc:app': false,
'nc:api:rest': false,
'nc:api:base': false,
'nc:api:gql': false,
'nc:api:grpc': false,
'nc:migrator': false,
'nc:datamapper': false,
}),
db_alias: ''
})
}
if (!(await this.knexConnection.schema.hasTable('nc_cron'))) {
await this.knexConnection.schema.createTable('nc_cron', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('title');
table.string('description', 255);
table.string('env');
table.string('pattern');
table.string('webhook');
table.string('timezone').defaultTo('America/Los_Angeles');
table.boolean('active').defaultTo(true);
table.text('cron_handler');
table.text('payload');
table.text('headers');
table.integer('retries').defaultTo(0);
table.integer('retry_interval').defaultTo(60000);
table.integer('timeout').defaultTo(60000);
table.timestamps();
})
}
if (!(await this.knexConnection.schema.hasTable('nc_acl'))) {
await this.knexConnection.schema.createTable('nc_acl', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('tn');
table.text('acl');
table.string('type').defaultTo('table');
table.timestamps();
})
}
if (!(await this.knexConnection.schema.hasTable('nc_models'))) {
await this.knexConnection.schema.createTable('nc_models', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('title');
table.string('type').defaultTo('table');
table.text('meta', 'mediumtext');
table.text('schema', 'text');
table.text('schema_previous', 'text')
table.text('services', 'mediumtext');
table.text('messages', 'text');
table.boolean('enabled').defaultTo(true);
table.timestamps();
table.index(['db_alias', 'title'])
})
}
if (!(await this.knexConnection.schema.hasTable('nc_relations'))) {
await this.knexConnection.schema.createTable('nc_relations', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias')
table.string('tn');
table.string('rtn');
table.string('cn');
table.string('rcn');
table.string('referenced_db_alias');
table.string('type');
table.string('db_type');
table.string('ur');
table.string('dr');
table.timestamps();
table.index(['db_alias', 'tn'])
})
}
if (this.config.projectType === 'rest' || this.isRest) {
if (!(await this.knexConnection.schema.hasTable('nc_routes'))) {
await this.knexConnection.schema.createTable('nc_routes', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('title');
table.string('tn');
table.string('tnp');
table.string('tnc');
table.string('relation_type');
table.text('path', 'text');
table.string('type');
table.text('handler', 'text');
table.text('acl', 'text');
table.integer('order');
table.text('functions');
table.integer('handler_type').defaultTo(1);
table.boolean('is_custom');
// table.text('placeholder', 'longtext');
table.timestamps();
table.index(['db_alias', 'title', 'tn'])
})
}
}
if (this.config.projectType === 'graphql' || this.isGql) {
if (!(await this.knexConnection.schema.hasTable('nc_resolvers'))) {
await this.knexConnection.schema.createTable('nc_resolvers', (table) => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('title');
table.text('resolver', 'text');
table.string('type');
table.text('acl', 'text');
table.text('functions');
table.integer('handler_type').defaultTo(1);
// table.text('placeholder', 'text');
table.timestamps();
})
}
if (!(await this.knexConnection.schema.hasTable('nc_loaders'))) {
await this.knexConnection.schema.createTable('nc_loaders', table => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('title');
table.string('parent');
table.string('child');
table.string('relation');
table.string('resolver');
table.text('functions');
table.timestamps();
})
}
}
if (this.config.projectType === 'grpc' || this.isGrpc) {
if (!(await this.knexConnection.schema.hasTable('nc_rpc'))) {
await this.knexConnection.schema.createTable('nc_rpc', (table) => {
table.increments();
table.string('project_id').defaultTo('default')
table.string('db_alias').defaultTo('db')
table.string('title');
table.string('tn');
table.text('service', 'text');
table.string('tnp');
table.string('tnc');
table.string('relation_type');
table.integer('order');
table.string('type');
table.text('acl', 'text');
table.text('functions', 'text');
table.integer('handler_type').defaultTo(1);
// table.text('placeholder', 'text');
table.timestamps();
})
}
}
try {
const debugEnabled = await this.metaGet('', '', 'nc_store', {
key: 'NC_DEBUG'
});
NcHelp.enableOrDisableDebugLog(JSON.parse(debugEnabled.value));
} catch (_e) {
console.log(_e)
}
if (!freshlyStarted) {
freshlyStarted = !(await this.knexConnection('nc_models').first());
}
return freshlyStarted;
}
public async metaDelete(
project_id: string,
dbAlias: string,
@ -530,16 +256,16 @@ export default class NcMetaIOImpl extends NcMetaIO {
return !!data;
}
commit() {
async commit() {
if (this.trx) {
this.trx.commit();
await this.trx.commit();
}
this.trx = null;
}
rollback(e?) {
async rollback(e?) {
if (this.trx) {
this.trx.rollback(e);
await this.trx.rollback(e);
}
this.trx = null;
}
@ -579,7 +305,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
config: CryptoJS.AES.encrypt(JSON.stringify(config), this.config?.auth?.jwt?.secret).toString()
};
// todo: check project name used or not
await this.connection('nc_projects').insert({
await this.knexConnection('nc_projects').insert({
...project,
created_at: this.knexConnection?.fn?.now(),
updated_at: this.knexConnection?.fn?.now(),
@ -597,7 +323,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
config: CryptoJS.AES.encrypt(JSON.stringify(config, null, 2), this.config?.auth?.jwt?.secret).toString()
};
// todo: check project name used or not
await this.connection('nc_projects').update(project).where({
await this.knexConnection('nc_projects').update(project).where({
id: projectId
});
} catch (e) {
@ -606,14 +332,14 @@ export default class NcMetaIOImpl extends NcMetaIO {
}
public async projectList(): Promise<any[]> {
return (await this.connection('nc_projects').select()).map(p => {
return (await this.knexConnection('nc_projects').select()).map(p => {
p.config = CryptoJS.AES.decrypt(p.config, this.config?.auth?.jwt?.secret).toString(CryptoJS.enc.Utf8)
return p;
});
}
public async userProjectList(userId: any): Promise<any[]> {
return (await this.connection('nc_projects')
return (await this.knexConnection('nc_projects')
.innerJoin('nc_projects_users', 'nc_projects_users.project_id', 'nc_projects.id')
.select('nc_projects.*')
.where(`nc_projects_users.user_id`, userId)).map(p => {
@ -623,14 +349,14 @@ export default class NcMetaIOImpl extends NcMetaIO {
}
public async isUserHaveAccessToProject(projectId: string, userId: any): Promise<boolean> {
return !!(await this.connection('nc_projects_users').where({
return !!(await this.knexConnection('nc_projects_users').where({
project_id: projectId,
user_id: userId
}).first());
}
public async projectGet(projectName: string, encrypt ?): Promise<any> {
const project = await this.connection('nc_projects').where({
const project = await this.knexConnection('nc_projects').where({
title: projectName
}).first();
@ -641,7 +367,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
}
public async projectGetById(projectId: string, encrypt ?): Promise<any> {
const project = await this.connection('nc_projects').where({
const project = await this.knexConnection('nc_projects').where({
id: projectId
}).first();
if (project && !encrypt) {
@ -652,19 +378,19 @@ export default class NcMetaIOImpl extends NcMetaIO {
public projectDelete(title: string): Promise<any> {
return this.connection('nc_projects').where({
return this.knexConnection('nc_projects').where({
title
}).delete();
}
public projectDeleteById(id: string): Promise<any> {
return this.connection('nc_projects').where({
return this.knexConnection('nc_projects').where({
id
}).delete();
}
public async projectStatusUpdate(projectName: string, status: string): Promise<any> {
return this.connection('nc_projects').update({
return this.knexConnection('nc_projects').update({
status
}).where({
title: projectName
@ -672,13 +398,13 @@ export default class NcMetaIOImpl extends NcMetaIO {
}
public async projectAddUser(projectId: string, userId: any, roles: string): Promise<any> {
if (await this.connection('nc_projects_users').where({
if (await this.knexConnection('nc_projects_users').where({
user_id: userId,
project_id: projectId
}).first()) {
return {}
}
return this.connection('nc_projects_users').insert({
return this.knexConnection('nc_projects_users').insert({
user_id: userId,
project_id: projectId,
roles
@ -686,7 +412,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
}
public projectRemoveUser(projectId: string, userId: any): Promise<any> {
return this.connection('nc_projects_users').where({
return this.knexConnection('nc_projects_users').where({
user_id: userId,
project_id: projectId
}).delete();

6
packages/nocodb/src/lib/noco/meta/NcMetaMgr.ts

@ -2792,12 +2792,12 @@ export default class NcMetaMgr {
protected getDbClientType(project_id: string, dbAlias: string) {
const config = this.app?.projectBuilders?.find(pb => pb?.id === project_id)?.config;
return config?.envs?.[this.config?.workingEnv || 'dev']?.db?.find(db => db?.meta?.dbAlias === dbAlias)?.client;
return config?.envs?.[this.config?.workingEnv || '_noco']?.db?.find(db => db?.meta?.dbAlias === dbAlias)?.client;
}
protected getDbAliasList(project_id: string): string[] {
return this.projectConfigs?.[project_id]?.envs?.[this.config?.workingEnv || 'dev']?.db?.map(db => db?.meta?.dbAlias);
return this.projectConfigs?.[project_id]?.envs?.[this.config?.workingEnv || '_noco']?.db?.map(db => db?.meta?.dbAlias);
}
@ -3583,7 +3583,7 @@ export default class NcMetaMgr {
Arch: process.arch,
Platform: process.platform,
Docker: isDocker(),
Database: config.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]?.client,
Database: config.envs?.[process.env.NODE_ENV || '_noco']?.db?.[0]?.client,
'ProjectOnRootDB': !!config?.prefix,
'RootDB': this.config?.meta?.db?.client,
'PackageVersion': packageVersion

96
packages/nocodb/src/lib/noco/upgrader/NcUpgrader.ts

@ -0,0 +1,96 @@
import {NcConfig} from "../../../interface/config";
import debug from 'debug';
import NcMetaIO from "../meta/NcMetaIO";
import ncProjectEnvUpgrader from "./jobs/ncProjectEnvUpgrader";
const log = debug('nc:upgrader');
export interface NcUpgraderCtx {
ncMeta: NcMetaIO
}
export default class NcUpgrader {
private static STORE_KEY = 'NC_CONFIG_MAIN';
// Todo: transaction
public static async upgrade(ctx: NcUpgraderCtx): Promise<any> {
this.log(`upgrade :`,)
try {
await ctx.ncMeta.startTransaction();
const NC_VERSIONS: any[] = [
{name: '0009000', handler: null},
{name: '0009044', handler: null},
{name: '0011043', handler: ncProjectEnvUpgrader}
]
if (!await ctx.ncMeta.knexConnection?.schema?.hasTable?.('nc_store')) {
return;
}
this.log(`upgrade : Getting configuration from meta database`,)
const config = await ctx.ncMeta.metaGet('', '', 'nc_store', {key: this.STORE_KEY});
if (config) {
const configObj: NcConfig = JSON.parse(config.value);
if (configObj.version !== process.env.NC_VERSION) {
for (const version of NC_VERSIONS) {
// compare current version and old version
if (version.name > configObj.version) {
this.log(`upgrade : Upgrading '%s' => '%s'`, configObj.version, version.name)
await version?.handler?.(ctx);
// update version in meta after each upgrade
config.version = version.name;
await ctx.ncMeta.metaUpdate('', '', 'nc_store', {
value: JSON.stringify(config)
}, {
key: NcUpgrader.STORE_KEY,
});
// todo: backup data
}
if (version.name === process.env.NC_VERSION) {
break;
}
}
config.version = process.env.NC_VERSION;
await ctx.ncMeta.metaInsert('', '', 'nc_store', {
key: NcUpgrader.STORE_KEY,
value: JSON.stringify(config)
});
}
} else {
this.log(`upgrade : Inserting config to meta database`,)
const configObj: any = {};
const isOld = (await ctx.ncMeta.projectList())?.length;
configObj.version = isOld ? '0009000' : process.env.NC_VERSION;
await ctx.ncMeta.metaInsert('', '', 'nc_store', {
key: NcUpgrader.STORE_KEY,
value: JSON.stringify(configObj)
});
if (isOld) {
await this.upgrade(ctx);
}
}
await ctx.ncMeta.commit()
} catch (e) {
await ctx.ncMeta.rollback(e)
console.log('Error', e)
}
}
private static log(str, ...args): void {
log(`${str}`, ...args);
}
private
}

20
packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectEnvUpgrader.ts

@ -0,0 +1,20 @@
import {NcUpgraderCtx} from "../NcUpgrader";
export default async function (ctx: NcUpgraderCtx) {
const projects = await ctx.ncMeta.projectList();
for (const project of projects) {
const projectConfig = JSON.parse(project.config);
const envVal = projectConfig.envs?.dev;
projectConfig.workingEnv = '_noco'
if (envVal) {
projectConfig.envs._noco = envVal;
delete projectConfig.envs.dev;
}
await ctx.ncMeta.projectUpdate(project?.id, projectConfig)
}
}

10
packages/nocodb/src/lib/sqlMgr/SqlMgr.ts

@ -629,14 +629,14 @@ export default class SqlMgr {
const projectJson = {
title: '',
envs: {
"dev": {
"_noco": {
db: [],
apiClient: {
data: []
}
}
},
"workingEnv": "dev",
"workingEnv": "_noco",
meta: {
version: '0.5',
seedsFolder: 'seeds',
@ -667,7 +667,7 @@ export default class SqlMgr {
config.meta.dbAlias = i > 1 ? `secondary${i}` : `secondary`;
}
projectJson.envs.dev.db.push(config);
projectJson.envs._noco.db.push(config);
}
@ -921,12 +921,12 @@ export default class SqlMgr {
try {
const dbs = this.currentProjectJson.envs.dev.db;
const dbs = this.currentProjectJson.envs._noco.db;
const dbType = dbs[0].client;
console.time('Copy and delete auth user migrations');
const sqlClient = await this.projectGetSqlClient({env: 'dev', dbAlias: 'db'});
const sqlClient = await this.projectGetSqlClient({env: '_noco', dbAlias: 'db'});
const usersTableExists = await sqlClient.hasTable({tn: 'xc_users'});
if (usersTableExists && usersTableExists.data.value) {

69
packages/nocodb/src/lib/utils/NcConfigFactory.ts

@ -46,8 +46,8 @@ export default class NcConfigFactory implements NcConfig {
config.port = +(process?.env?.PORT ?? 8080);
config.env = process.env?.NODE_ENV || 'dev';
config.workingEnv = process.env?.NODE_ENV || 'dev';
config.env = '_noco'; // process.env?.NODE_ENV || 'dev';
config.workingEnv = '_noco'; // process.env?.NODE_ENV || 'dev';
config.toolDir = this.getToolDir();
config.projectType = config?.envs?.[config.workingEnv]?.db?.[0]?.meta?.api?.type || 'rest';
@ -87,7 +87,8 @@ export default class NcConfigFactory implements NcConfig {
if (process.env.NC_PUBLIC_URL) {
config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
config.envs['_noco'].publicUrl = process.env.NC_PUBLIC_URL;
// config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
config.publicUrl = process.env.NC_PUBLIC_URL;
}
@ -110,7 +111,8 @@ export default class NcConfigFactory implements NcConfig {
for (const key of dbUrls.sort()) {
const dbConfig = this.urlToDbConfig(process?.env?.[key], key.slice(9), config);
config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
config.envs['_noco'].db.push(dbConfig);
// config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
}
@ -124,10 +126,12 @@ export default class NcConfigFactory implements NcConfig {
config.auth = {
disabled: true
};
} else if (config?.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]) {
// } else if (config?.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]) {
} else if (config?.envs?.['_noco']?.db?.[0]) {
config.auth = {
jwt: {
dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs[process.env.NODE_ENV || 'dev'].db[0].meta.dbAlias,
// dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs[process.env.NODE_ENV || 'dev'].db[0].meta.dbAlias,
dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs['_noco'].db[0].meta.dbAlias,
secret: process.env.NC_AUTH_JWT_SECRET
}
};
@ -171,14 +175,17 @@ export default class NcConfigFactory implements NcConfig {
if (process.env.NC_PUBLIC_URL) {
config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
config.envs['_noco'].publicUrl = process.env.NC_PUBLIC_URL;
// config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
config.publicUrl = process.env.NC_PUBLIC_URL;
}
config.port = +(process?.env?.PORT ?? 8080);
config.env = process.env?.NODE_ENV || 'dev';
config.workingEnv = process.env?.NODE_ENV || 'dev';
// config.env = process.env?.NODE_ENV || 'dev';
// config.workingEnv = process.env?.NODE_ENV || 'dev';
config.env = '_noco';
config.workingEnv = '_noco';
config.toolDir = this.getToolDir();
config.projectType = config?.envs?.[config.workingEnv]?.db?.[0]?.meta?.api?.type || 'rest';
@ -196,9 +203,11 @@ export default class NcConfigFactory implements NcConfig {
public static makeFromUrls(urls: string[]): NcConfig {
const config = new NcConfigFactory();
config.envs[process.env.NODE_ENV || 'dev'].db = [];
// config.envs[process.env.NODE_ENV || 'dev'].db = [];
config.envs['_noco'].db = [];
for (const [i, url] of Object.entries(urls)) {
config.envs[process.env.NODE_ENV || 'dev'].db.push(this.urlToDbConfig(url, i));
// config.envs[process.env.NODE_ENV || 'dev'].db.push(this.urlToDbConfig(url, i));
config.envs['_noco'].db.push(this.urlToDbConfig(url, i));
}
return config;
@ -354,7 +363,8 @@ export default class NcConfigFactory implements NcConfig {
public static makeProjectConfigFromUrl(url, type?: string): NcConfig {
const config = new NcConfigFactory();
const dbConfig = this.urlToDbConfig(url, '', config, type);
config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
// config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
config.envs['_noco'].db.push(dbConfig);
if (process.env.NC_AUTH_ADMIN_SECRET) {
@ -367,10 +377,12 @@ export default class NcConfigFactory implements NcConfig {
config.auth = {
disabled: true
};
} else if (config?.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]) {
// } else if (config?.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]) {
} else if (config?.envs?.['_noco']?.db?.[0]) {
config.auth = {
jwt: {
dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs[process.env.NODE_ENV || 'dev'].db[0].meta.dbAlias,
// dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs[process.env.NODE_ENV || 'dev'].db[0].meta.dbAlias,
dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs['_noco'].db[0].meta.dbAlias,
secret: process.env.NC_AUTH_JWT_SECRET
}
};
@ -414,14 +426,17 @@ export default class NcConfigFactory implements NcConfig {
if (process.env.NC_PUBLIC_URL) {
config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
// config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
config.envs['_noco'].publicUrl = process.env.NC_PUBLIC_URL;
config.publicUrl = process.env.NC_PUBLIC_URL;
}
config.port = +(process?.env?.PORT ?? 8080);
config.env = process.env?.NODE_ENV || 'dev';
config.workingEnv = process.env?.NODE_ENV || 'dev';
// config.env = process.env?.NODE_ENV || 'dev';
// config.workingEnv = process.env?.NODE_ENV || 'dev';
config.env = '_noco';
config.workingEnv = '_noco';
config.toolDir = this.getToolDir();
config.projectType = type || config?.envs?.[config.workingEnv]?.db?.[0]?.meta?.api?.type || 'rest';
@ -464,7 +479,8 @@ export default class NcConfigFactory implements NcConfig {
})
config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
// config.envs[process.env.NODE_ENV || 'dev'].db.push(dbConfig);
config.envs['_noco'].db.push(dbConfig);
if (process.env.NC_AUTH_ADMIN_SECRET) {
@ -477,10 +493,12 @@ export default class NcConfigFactory implements NcConfig {
config.auth = {
disabled: true
};
} else if (config?.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]) {
// } else if (config?.envs?.[process.env.NODE_ENV || 'dev']?.db?.[0]) {
} else if (config?.envs?.['_noco']?.db?.[0]) {
config.auth = {
jwt: {
dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs[process.env.NODE_ENV || 'dev'].db[0].meta.dbAlias,
// dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs[process.env.NODE_ENV || 'dev'].db[0].meta.dbAlias,
dbAlias: process.env.NC_AUTH_JWT_DB_ALIAS || config.envs['_noco'].db[0].meta.dbAlias,
secret: process.env.NC_AUTH_JWT_SECRET
}
};
@ -524,14 +542,17 @@ export default class NcConfigFactory implements NcConfig {
if (process.env.NC_PUBLIC_URL) {
config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
// config.envs[process.env.NODE_ENV || 'dev'].publicUrl = process.env.NC_PUBLIC_URL;
config.envs['_noco'].publicUrl = process.env.NC_PUBLIC_URL;
config.publicUrl = process.env.NC_PUBLIC_URL;
}
config.port = +(process?.env?.PORT ?? 8080);
config.env = process.env?.NODE_ENV || 'dev';
config.workingEnv = process.env?.NODE_ENV || 'dev';
// config.env = process.env?.NODE_ENV || 'dev';
// config.workingEnv = process.env?.NODE_ENV || 'dev';
config.env = '_noco';
config.workingEnv = '_noco';
config.toolDir = process.env.NC_TOOL_DIR || process.cwd();
config.projectType = type || config?.envs?.[config.workingEnv]?.db?.[0]?.meta?.api?.type || 'rest';
@ -591,7 +612,7 @@ export default class NcConfigFactory implements NcConfig {
public dashboardPath = '/dashboard'
constructor() {
this.envs = {dev: {db: []}};
this.envs = {_noco: {db: []}};
}

Loading…
Cancel
Save