Browse Source

refactor: prettier nocodb

pull/2588/head
Wing-Kam Wong 2 years ago
parent
commit
488f429212
  1. 8
      packages/nocodb/src/__tests__/TemplateParser.test.ts
  2. 12
      packages/nocodb/src/__tests__/formula.test.ts
  3. 204
      packages/nocodb/src/__tests__/graphql.test.ts
  4. 24
      packages/nocodb/src/__tests__/noco/NcConfigFactory.test.ts
  5. 172
      packages/nocodb/src/__tests__/rest.test.ts
  6. 434
      packages/nocodb/src/__tests__/restv2.test.ts
  7. 144
      packages/nocodb/src/__tests__/template.ts
  8. 16
      packages/nocodb/src/__tests__/unit/lib/meta/api/dataApis/dataAliasApis.test.ts
  9. 6
      packages/nocodb/src/interface/config.ts
  10. 28
      packages/nocodb/src/lib/Noco.ts
  11. 16
      packages/nocodb/src/lib/cache/RedisCacheMgr.ts
  12. 16
      packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts
  13. 206
      packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts
  14. 26
      packages/nocodb/src/lib/db/sql-client/lib/data.helper.ts
  15. 142
      packages/nocodb/src/lib/db/sql-client/lib/mssql/MssqlClient.ts
  16. 2
      packages/nocodb/src/lib/db/sql-client/lib/mssql/mssql.queries.ts
  17. 161
      packages/nocodb/src/lib/db/sql-client/lib/mysql/MysqlClient.ts
  18. 2
      packages/nocodb/src/lib/db/sql-client/lib/mysql/TidbClient.ts
  19. 2
      packages/nocodb/src/lib/db/sql-client/lib/mysql/VitessClient.ts
  20. 282
      packages/nocodb/src/lib/db/sql-client/lib/mysql/fakerFunctionList.ts
  21. 2
      packages/nocodb/src/lib/db/sql-client/lib/mysql/findDataTypeMapping.ts
  22. 110
      packages/nocodb/src/lib/db/sql-client/lib/mysql/mysql.queries.ts
  23. 25
      packages/nocodb/src/lib/db/sql-client/lib/oracle/OracleClient.ts
  24. 2
      packages/nocodb/src/lib/db/sql-client/lib/oracle/oracle.queries.ts
  25. 139
      packages/nocodb/src/lib/db/sql-client/lib/pg/PgClient.ts
  26. 102
      packages/nocodb/src/lib/db/sql-client/lib/pg/pg.queries.ts
  27. 71
      packages/nocodb/src/lib/db/sql-client/lib/sqlite/SqliteClient.ts
  28. 2
      packages/nocodb/src/lib/db/sql-client/lib/sqlite/sqlite.queries.ts
  29. 129
      packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts
  30. 220
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts
  31. 225
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts
  32. 6
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts
  33. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/customValidators.ts
  34. 20
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulaQueryBuilderFromString.ts
  35. 109
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts
  36. 14
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/commonFns.ts
  37. 22
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts
  38. 2
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mysql.ts
  39. 7
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  40. 18
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts
  41. 8
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelect.ts
  42. 11
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelectv2.ts
  43. 16
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/helpers/getAst.ts
  44. 48
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts
  45. 108
      packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts
  46. 6
      packages/nocodb/src/lib/db/sql-mgr/code/BaseRender.ts
  47. 60
      packages/nocodb/src/lib/db/sql-mgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts
  48. 6
      packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts
  49. 4
      packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/schemaHelp.ts
  50. 20
      packages/nocodb/src/lib/db/sql-mgr/code/models/xc/BaseModelXcMeta.ts
  51. 12
      packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaMssql.ts
  52. 12
      packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaMysql.ts
  53. 12
      packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaOracle.ts
  54. 12
      packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaPg.ts
  55. 12
      packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaSqlite.ts
  56. 38
      packages/nocodb/src/lib/db/sql-mgr/code/policies/xc/ExpressXcPolicy.ts
  57. 1314
      packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXc.ts
  58. 39
      packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXcBt.ts
  59. 814
      packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXcHm.ts
  60. 104
      packages/nocodb/src/lib/db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutes.ts
  61. 8
      packages/nocodb/src/lib/db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutesBt.ts
  62. 56
      packages/nocodb/src/lib/db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutesHm.ts
  63. 72
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigrator.ts
  64. 68
      packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts
  65. 26
      packages/nocodb/src/lib/db/sql-migrator/lib/templates/mssql.template.ts
  66. 26
      packages/nocodb/src/lib/db/sql-migrator/lib/templates/mysql.template.ts
  67. 26
      packages/nocodb/src/lib/db/sql-migrator/lib/templates/pg.template.ts
  68. 30
      packages/nocodb/src/lib/db/sql-migrator/lib/templates/sqlite.template.ts
  69. 20
      packages/nocodb/src/lib/db/util/Debug.ts
  70. 12
      packages/nocodb/src/lib/db/util/DebugMgr.ts
  71. 4
      packages/nocodb/src/lib/db/util/FileCollection.ts
  72. 6
      packages/nocodb/src/lib/db/util/file.help.ts
  73. 4
      packages/nocodb/src/lib/jobs/EmitteryJobsMgr.ts
  74. 6
      packages/nocodb/src/lib/jobs/JobsMgr.ts
  75. 4
      packages/nocodb/src/lib/jobs/RedisJobsMgr.ts
  76. 16
      packages/nocodb/src/lib/meta/MetaAPILogger.ts
  77. 8
      packages/nocodb/src/lib/meta/NcMetaIO.ts
  78. 66
      packages/nocodb/src/lib/meta/NcMetaIOImpl.ts
  79. 1012
      packages/nocodb/src/lib/meta/NcMetaMgr.ts
  80. 94
      packages/nocodb/src/lib/meta/NcMetaMgrEE.ts
  81. 34
      packages/nocodb/src/lib/meta/NcMetaMgrv2.ts
  82. 32
      packages/nocodb/src/lib/meta/api/attachmentApis.ts
  83. 8
      packages/nocodb/src/lib/meta/api/auditApis.ts
  84. 2
      packages/nocodb/src/lib/meta/api/cacheApis.ts
  85. 219
      packages/nocodb/src/lib/meta/api/columnApis.ts
  86. 10
      packages/nocodb/src/lib/meta/api/dataApis/bulkDataAliasApis.ts
  87. 22
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts
  88. 4
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasExportApis.ts
  89. 50
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts
  90. 114
      packages/nocodb/src/lib/meta/api/dataApis/dataApis.ts
  91. 37
      packages/nocodb/src/lib/meta/api/dataApis/helpers.ts
  92. 2
      packages/nocodb/src/lib/meta/api/dataApis/index.ts
  93. 22
      packages/nocodb/src/lib/meta/api/dataApis/oldDataApis.ts
  94. 2
      packages/nocodb/src/lib/meta/api/exportApis.ts
  95. 10
      packages/nocodb/src/lib/meta/api/filterApis.ts
  96. 2
      packages/nocodb/src/lib/meta/api/formViewApis.ts
  97. 2
      packages/nocodb/src/lib/meta/api/galleryViewApis.ts
  98. 2
      packages/nocodb/src/lib/meta/api/gridViewApis.ts
  99. 4
      packages/nocodb/src/lib/meta/api/hookApis.ts
  100. 8
      packages/nocodb/src/lib/meta/api/hookFilterApis.ts
  101. Some files were not shown because too many files have changed in this diff Show More

8
packages/nocodb/src/__tests__/TemplateParser.test.ts

@ -5,16 +5,16 @@ import template from './template';
describe('Template parser', () => {
// Called once before any of the tests in this block begin.
before(function(done) {
before(function (done) {
done();
});
after(done => {
after((done) => {
done();
});
describe('Parse blog templates', function() {
it('Simple formula', function() {
describe('Parse blog templates', function () {
it('Simple formula', function () {
const parser = new NcTemplateParser({ client: 'mysql', template });
const { tables } = parser.parse();

12
packages/nocodb/src/__tests__/formula.test.ts

@ -12,7 +12,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
let knexSqliteRef;
// Called once before any of the tests in this block begin.
before(function(done) {
before(function (done) {
knexMysqlRef = knex({ client: 'mysql2' });
knexMssqlRef = knex({ client: 'mssql' });
knexPgRef = knex({ client: 'pg' });
@ -20,12 +20,12 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
done();
});
after(done => {
after((done) => {
done();
});
describe('Formulas', function() {
it('Simple formula', function(done) {
describe('Formulas', function () {
it('Simple formula', function (done) {
expect(
formulaQueryBuilderFromString(
"concat(city, ' _ ',city_id+country_id)",
@ -56,7 +56,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
).eq("`city` || ' _ ' || (`city_id` + `country_id`) as a");
done();
});
it('Addition', function(done) {
it('Addition', function (done) {
expect(
formulaQueryBuilderFromString(
'ADD(city_id,country_id,2,3,4,5,4)',
@ -87,7 +87,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
).eq('`city_id` + `country_id` + 2 + 3 + 4 + 5 + 4 as a');
done();
});
it('Average', function(done) {
it('Average', function (done) {
expect(
formulaQueryBuilderFromString(
'AVG(city_id,country_id,2,3,4,5,4)',

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

@ -25,8 +25,8 @@ const projectCreateReqBody = {
envs: {
_noco: {
db: [dbConfig],
apiClient: { data: [] }
}
apiClient: { data: [] },
},
},
workingEnv: '_noco',
meta: {
@ -37,7 +37,7 @@ const projectCreateReqBody = {
projectType: 'graphql',
type: 'mvc',
language: 'ts',
db: { client: 'sqlite3', connection: { filename: 'noco.db' } }
db: { client: 'sqlite3', connection: { filename: 'noco.db' } },
},
seedsFolder: 'seeds',
queriesFolder: 'queries',
@ -47,10 +47,10 @@ const projectCreateReqBody = {
language: 'ts',
apiClient: { data: [] },
auth: {
jwt: { secret: 'b8ed266d-4475-4028-8c3d-590f58bee867', dbAlias: 'db' }
}
}
}
jwt: { secret: 'b8ed266d-4475-4028-8c3d-590f58bee867', dbAlias: 'db' },
},
},
},
};
describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
@ -59,7 +59,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
let projectId;
// Called once before any of the tests in this block begin.
before(function(done) {
before(function (done) {
this.timeout(10000);
(async () => {
const server = express();
@ -71,7 +71,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.catch(done);
});
after(done => {
after((done) => {
done();
// process.exit();
});
@ -234,12 +234,12 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
// /**** Authentication : END ****/
/**************** START : Auth ****************/
describe('Authentication', function() {
describe('Authentication', function () {
this.timeout(10000);
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
it('Signup with valid email', function(done) {
it('Signup with valid email', function (done) {
this.timeout(20000);
request(app)
.post('/auth/signup')
@ -255,18 +255,18 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('Signup with invalid email', done => {
it('Signup with invalid email', (done) => {
request(app)
.post('/auth/signup')
.send({ email: 'test', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with valid credentials', function(done) {
it('Signin with valid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function(err, res) {
.expect(200, async function (err, res) {
if (err) {
return done(err);
}
@ -280,11 +280,11 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('me', function(done) {
it('me', function (done) {
request(app)
.get('/user/me')
.set('xc-auth', token)
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) {
return done(err);
}
@ -294,7 +294,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('Change password', function(done) {
it('Change password', function (done) {
request(app)
.post('/user/password/change')
.set('xc-auth', token)
@ -302,38 +302,38 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.expect(400, done);
});
it('Change password - after logout', function(done) {
it('Change password - after logout', function (done) {
// todo:
request(app)
.post('/user/password/change')
.send({ currentPassword: 'password', newPassword: 'password' })
.expect(500, function(_err, _res) {
.expect(500, function (_err, _res) {
done();
});
});
it('Signin with invalid credentials', function(done) {
it('Signin with invalid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: 'abc@abc.com', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with invalid password', function(done) {
it('Signin with invalid password', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: 'wrongPassword' })
.expect(400, done);
});
it('Forgot password with a non-existing email id', function(done) {
it('Forgot password with a non-existing email id', function (done) {
request(app)
.post('/auth/password/forgot')
.send({ email: 'abc@abc.com' })
.expect(200, done);
});
it('Forgot password with an existing email id', function(done) {
it('Forgot password with an existing email id', function (done) {
this.timeout(10000);
request(app)
.post('/auth/password/forgot')
@ -341,14 +341,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.expect(200, done);
});
it('Email validate with an invalid token', function(done) {
it('Email validate with an invalid token', function (done) {
request(app)
.post('/auth/email/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Email validate with a valid token', function(done) {
it('Email validate with a valid token', function (done) {
console.log('eeee');
// todo :
@ -360,14 +360,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
// .expect(500, done);
});
it('Forgot password validate with an invalid token', function(done) {
it('Forgot password validate with an invalid token', function (done) {
request(app)
.post('/auth/token/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Forgot password validate with a valid token', function(done) {
it('Forgot password validate with a valid token', function (done) {
// todo
done();
@ -378,14 +378,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
// .expect(500, done);
});
it('Reset Password with an invalid token', function(done) {
it('Reset Password with an invalid token', function (done) {
request(app)
.post('/auth/password/reset/someRandomValue')
.send({ password: 'anewpassword' })
.expect(400, done);
});
it('Reset Password with an valid token', function(done) {
it('Reset Password with an valid token', function (done) {
//todo
done();
@ -396,16 +396,16 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
describe('Project', function() {
describe('Project', function () {
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
before(function(done) {
before(function (done) {
this.timeout(120000);
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function(_err, res) {
.expect(200, async function (_err, res) {
token = res.body.token;
request(app)
.post('/dashboard')
@ -421,16 +421,16 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
/**** country : START ****/
describe('country', function() {
describe('country', function () {
/**** Query : START ****/
it('countryList', function(done) {
it('countryList', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(limit:5){ country_id country } }`
query: `{ countryList(limit:5){ country_id country } }`,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list).length.to.be.most(5);
@ -439,7 +439,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryList - with sort', function(done) {
it('countryList - with sort', function (done) {
// todo: order -> sort
request(app)
@ -447,14 +447,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.set('xc-auth', token)
.send({
query: `{ countryList(sort:"-country_id"){ country_id country } }`
query: `{ countryList(sort:"-country_id"){ country_id country } }`,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys(['country_id', 'country']);
expect(list).satisfy(array => {
expect(list).satisfy((array) => {
let i = array.length;
while (--i) {
if (array[i].country_id > array[i - 1].country_id) return false;
@ -466,15 +466,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryList - with limit', function(done) {
it('countryList - with limit', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(limit:6){ country_id country } }`
query: `{ countryList(limit:6){ country_id country } }`,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys(['country_id', 'country']);
@ -483,15 +483,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryList - with offset', function(done) {
it('countryList - with offset', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList(offset:0,limit:6){ country_id country } }`
query: `{ countryList(offset:0,limit:6){ country_id country } }`,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const list1 = res.body.data.countryList;
expect(list1[0]).to.have.all.keys(['country_id', 'country']);
@ -500,14 +500,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.set('xc-auth', token)
.send({
query: `{ countryList(offset:1,limit:5){ country_id country } }`
query: `{ countryList(offset:1,limit:5){ country_id country } }`,
})
.expect(200, function(err, res1) {
.expect(200, function (err, res1) {
if (err) done(err);
const list2 = res1.body.data.countryList;
expect(list2[0]).to.have.all.keys(['country_id', 'country']);
expect(list2).satisfy(
arr =>
(arr) =>
arr.every(
({ country, country_id }, i) =>
country === list1[i + 1].country &&
@ -521,21 +521,21 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryList - nested count', function(done) {
it('countryList - nested count', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList{ country_id country cityCount} }`
query: `{ countryList{ country_id country cityCount} }`,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys([
'country_id',
'country',
'cityCount'
'cityCount',
]);
expect(list[0].cityCount).to.be.a('number');
expect(list[0].cityCount % 1).to.be.equal(0);
@ -543,28 +543,28 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryList - nested cityList', function(done) {
it('countryList - nested cityList', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryList{ country_id country cityList { city country_id }} }`
query: `{ countryList{ country_id country cityList { city country_id }} }`,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const list = res.body.data.countryList;
expect(list[0]).to.have.all.keys([
'country_id',
'country',
'cityList'
'cityList',
]);
expect(list[0].cityList).to.be.a('Array');
if (dbConfig.client !== 'mssql') {
expect(list[0].cityList[0]).to.be.a('object');
expect(list[0].cityList[0]).to.have.all.keys([
'country_id',
'city'
'city',
]);
expect(Object.keys(list[0].cityList[0])).to.have.length(2);
expect(list[0].cityList[0].country_id).to.be.equal(
@ -575,15 +575,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryRead', function(done) {
it('countryRead', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryRead(id: "1"){ country_id country } } `
query: `{ countryRead(id: "1"){ country_id country } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryRead;
expect(data).to.be.a('object');
@ -593,15 +593,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryExists', function(done) {
it('countryExists', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryExists(id: "1") } `
query: `{ countryExists(id: "1") } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryExists;
expect(data).to.be.a('boolean');
@ -610,15 +610,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryExists - with non-existing id', function(done) {
it('countryExists - with non-existing id', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryExists(id: "30000") } `
query: `{ countryExists(id: "30000") } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryExists;
expect(data).to.be.a('boolean');
@ -627,15 +627,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryFindOne', function(done) {
it('countryFindOne', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryFindOne (where: "(country_id,eq,1)"){ country country_id } } `
query: `{ countryFindOne (where: "(country_id,eq,1)"){ country country_id } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryFindOne;
expect(data).to.be.a('object');
@ -645,15 +645,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryCount - filter by id', function(done) {
it('countryCount - filter by id', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryCount (where: "(country_id,eq,1)") } `
query: `{ countryCount (where: "(country_id,eq,1)") } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryCount;
expect(data).to.be.a('number');
@ -662,15 +662,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryDistinct', function(done) {
it('countryDistinct', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryDistinct(column_name: "last_update") { last_update } } `
query: `{ countryDistinct(column_name: "last_update") { last_update } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryDistinct;
expect(data).to.be.a('array');
@ -682,15 +682,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
if (dbConfig.client !== 'mssql') {
it('countryGroupBy', function(done) {
it('countryGroupBy', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryGroupBy(fields: "last_update",limit:5) { last_update count } } `
query: `{ countryGroupBy(fields: "last_update",limit:5) { last_update count } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryGroupBy;
expect(data.length).to.be.most(5);
@ -701,15 +701,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryGroupBy - Multiple', function(done) {
it('countryGroupBy - Multiple', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryGroupBy(fields: "last_update,country",limit:5) { last_update country count } } `
query: `{ countryGroupBy(fields: "last_update,country",limit:5) { last_update country count } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryGroupBy;
expect(data.length).to.be.most(5);
@ -721,15 +721,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryAggregate', function(done) {
it('countryAggregate', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryAggregate(func: "sum,avg,min,max,count", column_name : "country_id") { sum avg min max count } } `
query: `{ countryAggregate(func: "sum,avg,min,max,count", column_name : "country_id") { sum avg min max count } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryAggregate;
expect(data).to.be.a('array');
@ -741,7 +741,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
expect(data[0].count)
.to.be.a('number')
.and.satisfy(
num => num === parseInt(num),
(num) => num === parseInt(num),
'count should be an integer'
);
expect(Object.keys(data[0]).length).to.be.equal(5);
@ -750,21 +750,21 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryDistribution', function(done) {
it('countryDistribution', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `{ countryDistribution(column_name : "country_id") { range count } } `
query: `{ countryDistribution(column_name : "country_id") { range count } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryDistribution;
expect(data).to.be.a('array');
expect(data[0].count).to.be.a('number');
expect(data[0].count).satisfies(
num => num === parseInt(num) && num >= 0,
(num) => num === parseInt(num) && num >= 0,
'should be a positive integer'
);
expect(data[0].range).to.be.a('string');
@ -779,12 +779,12 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
/**** Query : END ****/
/**** Mutation : START ****/
describe('Mutation', function() {
describe('Mutation', function () {
const COUNTRY_ID = 9999;
// const COUNTRY_CREATE_ID = 9998;
// const COUNTRY_NAME = 'test-name';
before(function(done) {
before(function (done) {
// create table entry for update and delete
// let db = knex(config.envs.dev.db[0])('country');
// db.insert({
@ -794,7 +794,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
done();
});
after(function(done) {
after(function (done) {
// delete table entries which is created for the test
// let db = knex(config.envs.dev.db[0])('country');
// db.whereIn('country_id', [COUNTRY_ID, COUNTRY_CREATE_ID])
@ -803,16 +803,16 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
done();
});
it('countryCreate', function(done) {
it('countryCreate', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `mutation{ countryCreate( data : { country: "abcd" ${
dbConfig.client === 'sqlite3' ? ' country_id : 999 ' : ''
} }) { country_id country } } `
} }) { country_id country } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryCreate;
expect(data).to.be.a('object');
@ -822,15 +822,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryUpdate', function(done) {
it('countryUpdate', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `mutation{ countryUpdate( id : "${COUNTRY_ID}", data : { country: "abcd" }){ country } } `
query: `mutation{ countryUpdate( id : "${COUNTRY_ID}", data : { country: "abcd" }){ country } } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryUpdate;
expect(data).to.be.a('object');
@ -839,15 +839,15 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('countryDelete', function(done) {
it('countryDelete', function (done) {
request(app)
.post(`/nc/${projectId}/v1/graphql`)
.set('xc-auth', token)
.send({
query: `mutation{ countryDelete( id : "${COUNTRY_ID}") } `
query: `mutation{ countryDelete( id : "${COUNTRY_ID}") } `,
})
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) done(err);
const data = res.body.data.countryDelete;
expect(data).to.be.a('number');

24
packages/nocodb/src/__tests__/noco/NcConfigFactory.test.ts

@ -13,24 +13,24 @@ describe('Config Factory Tests', () => {
port: 5432,
},
ssl: {
rejectUnauthorized: false
rejectUnauthorized: false,
},
pool: {
min: 1,
max: 2
max: 2,
},
acquireConnectionTimeout: 600000
acquireConnectionTimeout: 600000,
};
before(function(done) {
before(function (done) {
done();
});
after(done => {
after((done) => {
done();
});
it('Generate config from string', function(done) {
it('Generate config from string', function (done) {
const dbConfig = NcConfigFactory.metaUrlToDbConfig(
`pg://localhost:5432?u=postgres&p=xgene&d=abcde`
);
@ -38,7 +38,7 @@ describe('Config Factory Tests', () => {
expect(dbConfig).to.deep.equal(rest);
done();
});
it('Connection string with nested property', function(done) {
it('Connection string with nested property', function (done) {
const dbConfig = NcConfigFactory.metaUrlToDbConfig(
`pg://localhost:5432?u=postgres&p=xgene&d=abcde&pool.min=1&pool.max=2&ssl.rejectUnauthorized=false`
);
@ -46,12 +46,12 @@ describe('Config Factory Tests', () => {
done();
});
it('Allow creating config from JSON string', function(done) {
it('Allow creating config from JSON string', function (done) {
try {
process.env.NC_DB_JSON = JSON.stringify(storedDbConfig);
const {
meta: { db: dbConfig }
meta: { db: dbConfig },
} = NcConfigFactory.make();
expect(dbConfig).to.deep.equal(storedDbConfig);
@ -61,14 +61,14 @@ describe('Config Factory Tests', () => {
}
});
it('Allow creating config from JSON file', function(done) {
it('Allow creating config from JSON file', function (done) {
try {
process.env.NC_DB_JSON_FILE = `${__dirname}/dbConfig.json`;
const {
meta: { db: dbConfig }
meta: { db: dbConfig },
} = NcConfigFactory.make();
expect(dbConfig).to.deep.equal(storedDbConfig);
done();
} finally {

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

@ -23,7 +23,7 @@ const projectCreateReqBody = {
envs: {
_noco: {
db: [
dbConfig
dbConfig,
// {
// "client": "mysql2",
// "connection": {
@ -42,8 +42,8 @@ const projectCreateReqBody = {
// }
// }
],
apiClient: { data: [] }
}
apiClient: { data: [] },
},
},
workingEnv: '_noco',
meta: {
@ -54,7 +54,7 @@ const projectCreateReqBody = {
projectType: 'rest',
type: 'mvc',
language: 'ts',
db: { client: 'sqlite3', connection: { filename: 'noco.db' } }
db: { client: 'sqlite3', connection: { filename: 'noco.db' } },
},
seedsFolder: 'seeds',
queriesFolder: 'queries',
@ -64,10 +64,10 @@ const projectCreateReqBody = {
language: 'ts',
apiClient: { data: [] },
auth: {
jwt: { secret: 'b8ed266d-4475-4028-8c3d-590f58bee867', dbAlias: 'db' }
}
}
}
jwt: { secret: 'b8ed266d-4475-4028-8c3d-590f58bee867', dbAlias: 'db' },
},
},
},
};
// console.log(JSON.stringify(dbConfig, null, 2));
@ -76,7 +76,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
let app;
// Called once before any of the tests in this block begin.
before(function(done) {
before(function (done) {
this.timeout(200000);
(async () => {
@ -87,23 +87,23 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
// await knex(config.envs[process.env.NODE_ENV || 'dev'].db[0])('xc_users').del();
})()
.then(done)
.catch(e => {
.catch((e) => {
done(e);
});
});
after(done => {
after((done) => {
done();
// process.exit();
});
/**************** START : Auth ****************/
describe('Authentication', function() {
describe('Authentication', function () {
this.timeout(10000);
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
it('Signup with valid email', function(done) {
it('Signup with valid email', function (done) {
this.timeout(60000);
request(app)
.post('/auth/signup')
@ -119,18 +119,18 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('Signup with invalid email', done => {
it('Signup with invalid email', (done) => {
request(app)
.post('/auth/signup')
.send({ email: 'test', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with valid credentials', function(done) {
it('Signin with valid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function(err, res) {
.expect(200, async function (err, res) {
if (err) {
return done(err);
}
@ -144,11 +144,11 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('me', function(done) {
it('me', function (done) {
request(app)
.get('/user/me')
.set('xc-auth', token)
.expect(200, function(err, res) {
.expect(200, function (err, res) {
if (err) {
return done(err);
}
@ -158,7 +158,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('Change password', function(done) {
it('Change password', function (done) {
request(app)
.post('/user/password/change')
.set('xc-auth', token)
@ -166,31 +166,31 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.expect(400, done);
});
it('Change password - after logout', function(done) {
it('Change password - after logout', function (done) {
// todo:
request(app)
.post('/user/password/change')
.send({ currentPassword: 'password', newPassword: 'password' })
.expect(500, function(_err, _res) {
.expect(500, function (_err, _res) {
done();
});
});
it('Signin with invalid credentials', function(done) {
it('Signin with invalid credentials', function (done) {
request(app)
.post('/auth/signin')
.send({ email: 'abc@abc.com', password: VALID_PASSWORD })
.expect(400, done);
});
it('Signin with invalid password', function(done) {
it('Signin with invalid password', function (done) {
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: 'wrongPassword' })
.expect(400, done);
});
it('Signup without email and password', done => {
it('Signup without email and password', (done) => {
request(app)
.post('/auth/signin')
// pass empty data in request
@ -198,14 +198,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.expect(400, done);
});
it('Forgot password with a non-existing email id', function(done) {
it('Forgot password with a non-existing email id', function (done) {
request(app)
.post('/auth/password/forgot')
.send({ email: 'abc@abc.com' })
.expect(200, done);
});
it('Forgot password with an existing email id', function(done) {
it('Forgot password with an existing email id', function (done) {
this.timeout(10000);
request(app)
.post('/auth/password/forgot')
@ -213,14 +213,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.expect(200, done);
});
it('Email validate with an invalid token', function(done) {
it('Email validate with an invalid token', function (done) {
request(app)
.post('/auth/email/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Email validate with a valid token', function(done) {
it('Email validate with a valid token', function (done) {
console.log('eeee');
// todo :
@ -232,14 +232,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
// .expect(500, done);
});
it('Forgot password validate with an invalid token', function(done) {
it('Forgot password validate with an invalid token', function (done) {
request(app)
.post('/auth/token/validate/someRandomValue')
.send({ email: EMAIL_ID })
.expect(400, done);
});
it('Forgot password validate with a valid token', function(done) {
it('Forgot password validate with a valid token', function (done) {
// todo
done();
@ -250,14 +250,14 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
// .expect(500, done);
});
it('Reset Password with an invalid token', function(done) {
it('Reset Password with an invalid token', function (done) {
request(app)
.post('/auth/password/reset/someRandomValue')
.send({ password: 'anewpassword' })
.expect(400, done);
});
it('Reset Password with an valid token', function(done) {
it('Reset Password with an valid token', function (done) {
//todo
done();
@ -268,16 +268,16 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
describe('Project', function() {
describe('Project', function () {
const EMAIL_ID = 'abc@g.com';
const VALID_PASSWORD = '1234566778';
before(function(done) {
before(function (done) {
this.timeout(120000);
request(app)
.post('/auth/signin')
.send({ email: EMAIL_ID, password: VALID_PASSWORD })
.expect(200, async function(_err, res) {
.expect(200, async function (_err, res) {
token = res.body.token;
request(app)
.post('/dashboard')
@ -294,13 +294,13 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
/**************** START : CRUD ****************/
describe('CRUD', function() {
describe('CRUD', function () {
let COUNTRY_ID_RET;
const COUNTRY_ID = 9999;
const COUNTRY_NAME = 'IN';
this.timeout(5000);
it('list + limit : GET - /api/v1/country?limit=6', function(done) {
it('list + limit : GET - /api/v1/country?limit=6', function (done) {
console.log(`/nc/${projectId}/api/v1/country?limit=6`);
request(app)
.get(`/nc/${projectId}/api/v1/country?limit=6`)
@ -312,7 +312,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('list + where : GET - /api/v1/country?where=(country,like,b%)', function(done) {
it('list + where : GET - /api/v1/country?where=(country,like,b%)', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?where=(country,like,b%)`)
.set('xc-auth', token)
@ -322,21 +322,21 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
if (res.body.length)
expect(res.body[0].country.toLowerCase())
.to.be.a('string')
.and.satisfy(msg => {
.and.satisfy((msg) => {
return msg.startsWith('b');
}, 'Should start with "b"');
done();
});
});
it('list + sort : GET - /api/v1/country?sort=-country_id', function(done) {
it('list + sort : GET - /api/v1/country?sort=-country_id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?sort=-country_id`)
.set('xc-auth', token)
.expect(200, (err, res) => {
if (err) done(err);
expect(res.body).to.be.a('array');
expect(res.body).satisfy(array => {
expect(res.body).satisfy((array) => {
let i = array.length;
while (--i) {
if (array[i].country_id > array[i - 1].country_id) return false;
@ -347,7 +347,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('list + fields : GET - /api/v1/country?fields=country,country_id', function(done) {
it('list + fields : GET - /api/v1/country?fields=country,country_id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?fields=country,country_id`)
.set('xc-auth', token)
@ -364,7 +364,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('list + offset : GET - /api/v1/country?offset=0', function(done) {
it('list + offset : GET - /api/v1/country?offset=0', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country?offset=0&limit=6`)
.set('xc-auth', token)
@ -376,7 +376,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.expect(200, (err, res2) => {
if (err) done(err);
expect(res2.body).satisfy(
arr =>
(arr) =>
arr.every(
({ country, country_id }, i) =>
country === res1.body[i + 1].country &&
@ -389,8 +389,8 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
describe('CRUD', function() {
it('create - POST - /api/v1/country', function(done) {
describe('CRUD', function () {
it('create - POST - /api/v1/country', function (done) {
request(app)
.delete(`/nc/${projectId}/api/v1/country/` + COUNTRY_ID)
.set('xc-auth', token)
@ -404,7 +404,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
country: COUNTRY_NAME,
...(dbConfig.client === 'mssql'
? {}
: { country_id: COUNTRY_ID })
: { country_id: COUNTRY_ID }),
})
.expect(200, (err, res) => {
if (err) done(err);
@ -416,7 +416,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('read - GET - /api/v1/country/:id', function(done) {
it('read - GET - /api/v1/country/:id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1`)
.set('xc-auth', token)
@ -429,7 +429,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('update - PUT - /api/v1/country/:id', function(done) {
it('update - PUT - /api/v1/country/:id', function (done) {
request(app)
.put(
`/nc/${projectId}/api/v1/country/` +
@ -456,7 +456,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('exists - GET - /api/v1/country/:id/exists', function(done) {
it('exists - GET - /api/v1/country/:id/exists', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/exists`)
.set('xc-auth', token)
@ -467,11 +467,12 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('findOne - GET - /api/v1/country/findOne', function(done) {
it('findOne - GET - /api/v1/country/findOne', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/findOne?where=(country,eq,${COUNTRY_NAME +
'a'})`
`/nc/${projectId}/api/v1/country/findOne?where=(country,eq,${
COUNTRY_NAME + 'a'
})`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
@ -482,7 +483,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('delete - DELETE - /api/v1/country/:id', function(done) {
it('delete - DELETE - /api/v1/country/:id', function (done) {
request(app)
.delete(
`/nc/${projectId}/api/v1/country/` +
@ -510,7 +511,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
if (dbConfig.client !== 'mssql') {
it('groupBy - GET - /api/v1/country/groupby/:cn', function(done) {
it('groupBy - GET - /api/v1/country/groupby/:cn', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/groupby/country?limit=5`)
.set('xc-auth', token)
@ -527,7 +528,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('groupBy multiple - GET - /api/v1/country/groupby/:cn', function(done) {
it('groupBy multiple - GET - /api/v1/country/groupby/:cn', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/groupby/country?fields=country_id&limit=5`
@ -548,7 +549,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
// todo: change distribute => distribution
it('distribution - GET - /api/v1/country/distribute', function(done) {
it('distribution - GET - /api/v1/country/distribute', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/distribute?column_name=country_id&steps=1,34,50`
@ -559,7 +560,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
expect(res.body).to.be.a('array');
expect(+res.body[0].count).to.be.a('number');
expect(+res.body[0].count).satisfies(
num => num === parseInt(num) && num >= 0,
(num) => num === parseInt(num) && num >= 0,
'should be a positive integer'
);
expect(res.body[0].range).to.be.a('string');
@ -571,7 +572,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('distinct - GET - /api/v1/country/distinct', function(done) {
it('distinct - GET - /api/v1/country/distinct', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/distinct?cn=country&limit=5`)
.set('xc-auth', token)
@ -587,7 +588,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('distinct multiple - GET - /api/v1/country/distinct/:cn', function(done) {
it('distinct multiple - GET - /api/v1/country/distinct/:cn', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/distinct?cn=country&fields=country_id&limit=5`
@ -605,7 +606,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('aggregate - GET - /api/v1/country/aggregate', function(done) {
it('aggregate - GET - /api/v1/country/aggregate', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/aggregate?column_name=country_id&func=sum,avg,min,max,count`
@ -618,17 +619,17 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
expect(+res.body[0].min).to.be.a('number');
expect(+res.body[0].max).to.be.a('number');
expect(+res.body[0].avg).to.be.satisfy(
num => !isNaN(parseInt(num)),
(num) => !isNaN(parseInt(num)),
'count should be an number'
);
expect(+res.body[0].sum).to.be.satisfy(
num => !isNaN(parseInt(num)),
(num) => !isNaN(parseInt(num)),
'count should be an number'
);
expect(+res.body[0].count)
.to.be.a('number')
.and.satisfy(
num => num === parseInt(num),
(num) => num === parseInt(num),
'count should be an integer'
);
// expect(Object.keys(res.body[0]).length).to.be.equal(7);
@ -638,7 +639,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('count - GET - /api/v1/country/count', function(done) {
it('count - GET - /api/v1/country/count', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/count`)
.set('xc-auth', token)
@ -648,7 +649,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
expect(+res.body.count)
.to.be.a('number')
.and.satisfy(
num => num === parseInt(num),
(num) => num === parseInt(num),
'count should be an integer'
);
done();
@ -656,7 +657,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
if (dbConfig.client !== 'sqlite3') {
it('bulk insert - POST - /api/v1/country/bulk', function(done) {
it('bulk insert - POST - /api/v1/country/bulk', function (done) {
request(app)
.post(`/nc/${projectId}/api/v1/country/bulk`)
.set('xc-auth', token)
@ -665,7 +666,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
{ country: 'b' },
{ country: 'c' },
{ country: 'd' },
{ country: 'e' }
{ country: 'e' },
])
.expect(200, (err, res) => {
if (err) done(err);
@ -687,7 +688,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('bulk update - PUT - /api/v1/country/bulk', function(done) {
it('bulk update - PUT - /api/v1/country/bulk', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country?sort=-country_id&limit=5`)
@ -705,7 +706,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
.send(
res.body.map(({ country, country_id }) => ({
country_id,
country: country + 1
country: country + 1,
}))
)
.expect(200, (err, res) => {
@ -718,7 +719,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
});
it('bulk delete - DELETE - /api/v1/country/bulk', function(done) {
it('bulk delete - DELETE - /api/v1/country/bulk', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country?sort=-country_id&limit=5`)
@ -751,11 +752,11 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
if (dbConfig.client !== 'mssql' && dbConfig.client !== 'sqlite3') {
/**************** START : hasMany ****************/
describe('Country HasMany City Api', function() {
describe('Country HasMany City Api', function () {
const CITY_NAME = 'testCity',
CITY_ID = '9999';
it('has city - GET - /api/v1/country/has/city(:childs)?', function(done) {
it('has city - GET - /api/v1/country/has/city(:childs)?', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country/has/city`)
@ -772,7 +773,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('cities under a single parent - GET - /api/v1/country/:parentId/city', function(done) {
it('cities under a single parent - GET - /api/v1/country/:parentId/city', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city?limit=5`)
@ -787,7 +788,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('create - POST - /api/v1/country/:parentId/city/:id', function(done) {
it('create - POST - /api/v1/country/:parentId/city/:id', function (done) {
request(app)
.delete(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
@ -807,7 +808,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('get city by id - GET - /api/v1/country/:parentId/city/:id', function(done) {
it('get city by id - GET - /api/v1/country/:parentId/city/:id', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
@ -820,7 +821,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('get count - GET - /api/v1/country/:parentId/city/count', function(done) {
it('get count - GET - /api/v1/country/:parentId/city/count', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/count`)
.set('xc-auth', token)
@ -832,7 +833,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('update - PUT - /api/v1/country/:parentId/city/:id', function(done) {
it('update - PUT - /api/v1/country/:parentId/city/:id', function (done) {
request(app)
.put(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
.set('xc-auth', token)
@ -853,11 +854,12 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('findOne city - GET - /api/v1/country/:parentId/city/findOne', function(done) {
it('findOne city - GET - /api/v1/country/:parentId/city/findOne', function (done) {
request(app)
.get(
`/nc/${projectId}/api/v1/country/1/city/findOne?where=(city,eq,${CITY_NAME +
'a'})`
`/nc/${projectId}/api/v1/country/1/city/findOne?where=(city,eq,${
CITY_NAME + 'a'
})`
)
.set('xc-auth', token)
.expect(200, (err, res) => {
@ -869,7 +871,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('exists city - GET - /api/v1/country/1/city/${CITY_ID}/exists', function(done) {
it('exists city - GET - /api/v1/country/1/city/${CITY_ID}/exists', function (done) {
request(app)
.get(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}/exists`)
.set('xc-auth', token)
@ -880,7 +882,7 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
});
});
it('delete - DELETE - /api/v1/country/:parentId/city', function(done) {
it('delete - DELETE - /api/v1/country/:parentId/city', function (done) {
this.timeout(10000);
request(app)
.delete(`/nc/${projectId}/api/v1/country/1/city/${CITY_ID}`)
@ -895,8 +897,8 @@ describe('{Auth, CRUD, HasMany, Belongs} Tests', () => {
/**************** END : hasMany ****************/
/**************** START : belongsTo ****************/
describe('City BelngsTo Country Api', function() {
it('city belongs to country - GET - /api/v1/city/belongs/country', function(done) {
describe('City BelngsTo Country Api', function () {
it('city belongs to country - GET - /api/v1/city/belongs/country', function (done) {
// get last inserted 5 entry by sorting db data in reverse order based on id
request(app)
.get(`/nc/${projectId}/api/v1/city/belongs/country?limit=10`)

434
packages/nocodb/src/__tests__/restv2.test.ts

File diff suppressed because it is too large Load Diff

144
packages/nocodb/src/__tests__/template.ts

@ -6,43 +6,43 @@ export default {
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
uidt: 'SingleLineText',
},
{
cn: 'body',
uidt: 'LongText'
}
uidt: 'LongText',
},
],
hasMany: [
{
tn: 'comment'
}
tn: 'comment',
},
],
manyToMany: [
{
rtn: 'tag'
}
]
rtn: 'tag',
},
],
},
{
tn: 'comment',
columns: [
{
cn: 'body',
uidt: 'LongText'
}
]
uidt: 'LongText',
},
],
},
{
tn: 'tag',
columns: [
{
cn: 'title',
uidt: 'SingleLineText'
}
]
}
]
uidt: 'SingleLineText',
},
],
},
],
};
export const blog = {
@ -53,7 +53,7 @@ export const blog = {
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'id',
_cn: 'Id',
@ -76,13 +76,13 @@ export const blog = {
ns: 0,
dtxp: '11',
dtxs: '',
tn: 'blog'
tn: 'blog',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'title',
_cn: 'Title',
@ -106,13 +106,13 @@ export const blog = {
dtxp: '45',
dtxs: '',
pv: true,
alias: 'Title'
alias: 'Title',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'created_at',
_cn: 'CreatedAt',
@ -136,13 +136,13 @@ export const blog = {
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP'
columnDefault: 'CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'updated_at',
_cn: 'UpdatedAt',
@ -166,13 +166,13 @@ export const blog = {
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'body',
_cn: 'body',
@ -197,8 +197,8 @@ export const blog = {
dtxs: ' ',
cno: 'title5',
tn: 'blog',
alias: 'body'
}
alias: 'body',
},
],
pks: [],
hasMany: [
@ -222,7 +222,7 @@ export const blog = {
created_at: '2021-10-29 07:28:12',
updated_at: '2021-10-29 07:28:12',
fkn: 'tag_blo_Dneo90_c_fk',
enabled: true
enabled: true,
},
{
id: 1,
@ -244,8 +244,8 @@ export const blog = {
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true
}
enabled: true,
},
],
belongsTo: [],
type: 'table',
@ -271,9 +271,9 @@ export const blog = {
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true
enabled: true,
},
_cn: 'blog => comment'
_cn: 'blog => comment',
},
{
mm: {
@ -287,10 +287,10 @@ export const blog = {
_tn: 'blog',
_cn: null,
_rtn: 'tag',
_rcn: null
_rcn: null,
},
_cn: 'blog <=> tag'
}
_cn: 'blog <=> tag',
},
],
manyToMany: [
{
@ -304,9 +304,9 @@ export const blog = {
_tn: 'blog',
_cn: null,
_rtn: 'tag',
_rcn: null
}
]
_rcn: null,
},
],
};
export const comment = {
@ -317,7 +317,7 @@ export const comment = {
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'id',
_cn: 'Id',
@ -340,13 +340,13 @@ export const comment = {
ns: 0,
dtxp: '11',
dtxs: '',
tn: 'comment'
tn: 'comment',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'created_at',
_cn: 'CreatedAt',
@ -371,13 +371,13 @@ export const comment = {
dtxs: '',
default: 'CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP',
pv: true
pv: true,
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'updated_at',
_cn: 'UpdatedAt',
@ -401,13 +401,13 @@ export const comment = {
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'body',
_cn: 'body',
@ -432,13 +432,13 @@ export const comment = {
dtxs: ' ',
cno: 'title4',
tn: 'comment',
alias: 'body'
alias: 'body',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'title5',
_cn: 'title5',
@ -462,8 +462,8 @@ export const comment = {
dtxp: '11',
dtxs: '',
cno: 'title5',
tn: 'comment'
}
tn: 'comment',
},
],
pks: [],
hasMany: [],
@ -488,8 +488,8 @@ export const comment = {
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true
}
enabled: true,
},
],
type: 'table',
v: [
@ -514,11 +514,11 @@ export const comment = {
created_at: '2021-10-29 07:27:54',
updated_at: '2021-10-29 07:27:54',
fkn: null,
enabled: true
enabled: true,
},
_cn: 'blog <= comment'
}
]
_cn: 'blog <= comment',
},
],
};
export const tag = {
@ -529,7 +529,7 @@ export const tag = {
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'id',
_cn: 'Id',
@ -551,13 +551,13 @@ export const tag = {
np: 11,
ns: 0,
dtxp: '11',
dtxs: ''
dtxs: '',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'title',
_cn: 'Title',
@ -581,13 +581,13 @@ export const tag = {
dtxp: '45',
dtxs: '',
pv: true,
alias: 'Title'
alias: 'Title',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'created_at',
_cn: 'CreatedAt',
@ -611,13 +611,13 @@ export const tag = {
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP'
columnDefault: 'CURRENT_TIMESTAMP',
},
{
validate: {
func: [],
args: [],
msg: []
msg: [],
},
cn: 'updated_at',
_cn: 'UpdatedAt',
@ -641,8 +641,8 @@ export const tag = {
dtxp: '',
dtxs: '',
default: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP'
}
columnDefault: 'CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP',
},
],
pks: [],
hasMany: [
@ -666,8 +666,8 @@ export const tag = {
created_at: '2021-10-29 07:28:11',
updated_at: '2021-10-29 07:28:11',
fkn: 'tag_blo_rKb7Gq_p_fk',
enabled: true
}
enabled: true,
},
],
belongsTo: [],
type: 'table',
@ -684,10 +684,10 @@ export const tag = {
_tn: 'tag',
_cn: null,
_rtn: 'blog',
_rcn: null
_rcn: null,
},
_cn: 'tag <=> blog'
}
_cn: 'tag <=> blog',
},
],
manyToMany: [
{
@ -701,7 +701,7 @@ export const tag = {
_tn: 'tag',
_cn: null,
_rtn: 'blog',
_rcn: null
}
]
_rcn: null,
},
],
};

16
packages/nocodb/src/__tests__/unit/lib/meta/api/dataApis/dataAliasApis.test.ts

@ -16,20 +16,20 @@ const getFindOne = dataAliasApis.__get__('getFindOne');
describe('getFindOne', () => {
const model = {
id: 'modelId',
base_id: 'baseId'
base_id: 'baseId',
};
const view = {
id: 'viewId'
id: 'viewId',
};
const base = {
id: 'baseId'
id: 'baseId',
};
const dbDriver = {
id: 'dbDriverId'
id: 'dbDriverId',
};
const req = { query: {} };
const baseModel = {
findOne: sinon.fake.returns(undefined)
findOne: sinon.fake.returns(undefined),
};
const baseGetFake = sinon.replace(Base, 'get', sinon.fake.returns(base));
const baseModelFake = sinon.replace(
@ -52,7 +52,7 @@ describe('getFindOne', () => {
baseModelFake.calledWith({
id: model.id,
viewId: view.id,
dbDriver: dbDriver
dbDriver: dbDriver,
})
).to.be.true;
});
@ -71,10 +71,10 @@ describe('getFindOne', () => {
describe('when data is found', () => {
it('returns data', async () => {
const findOneResult = {
id: 'dataId'
id: 'dataId',
};
baseModel.findOne = sinon.fake.returns(findOneResult);
expect(await getFindOne(model, view, req)).eql(findOneResult);
});
});
});
});

6
packages/nocodb/src/interface/config.ts

@ -20,7 +20,7 @@ export enum RouteType {
PATCH = 'patch',
DELETE = 'delete',
HEAD = 'head',
OPTIONS = 'options'
OPTIONS = 'options',
}
type InflectionTypes =
@ -259,7 +259,7 @@ export enum ServerlessType {
ALIYUN = 'ALIYUN',
ZEIT = 'ZEIT',
LYRID = 'LYRID',
SERVERLESS = 'SERVERLESS'
SERVERLESS = 'SERVERLESS',
}
export class Result {
@ -281,7 +281,7 @@ enum HTTPType {
DELETE = 'delete',
PATCH = 'patch',
HEAD = 'head',
OPTIONS = 'options'
OPTIONS = 'options',
}
export interface XcRoute {

28
packages/nocodb/src/lib/Noco.ts

@ -163,7 +163,7 @@ export default class Noco {
) {
// @ts-ignore
const {
progressCallback
progressCallback,
// registerRoutes,
// registerContext,
// registerGql
@ -213,7 +213,7 @@ export default class Noco {
this.router.use(cookieParser());
this.router.use(
bodyParser.json({
limit: process.env.NC_REQUEST_BODY_SIZE || '50mb'
limit: process.env.NC_REQUEST_BODY_SIZE || '50mb',
})
);
this.router.use(morgan('tiny'));
@ -266,7 +266,7 @@ export default class Noco {
next();
});
Tele.init({
instance: getInstance
instance: getInstance,
});
Tele.emit('evt_app_started', await User.count());
weAreHiring();
@ -333,7 +333,7 @@ export default class Noco {
await builder.init(true);
} else {
const projectBuilder = this.projectBuilders.find(
pb => pb.id == data.req?.project_id
(pb) => pb.id == data.req?.project_id
);
return projectBuilder?.handleRunTimeChanges(data);
}
@ -347,7 +347,7 @@ export default class Noco {
data?.req?.project_id
);
const projectBuilder = this.projectBuilders.find(
pb => pb.id === projectId
(pb) => pb.id === projectId
);
projectBuilder.updateConfig(project.config);
@ -364,7 +364,7 @@ export default class Noco {
Noco._ncMeta.setConfig(this.config);
this.metaMgr.setConfig(this.config);
Object.assign(process.env, {
NODE_ENV: this.env = this.config.workingEnv
NODE_ENV: (this.env = this.config.workingEnv),
});
this.router.stack.splice(0, this.router.stack.length);
this.ncToolApi.destroy();
@ -377,7 +377,7 @@ export default class Noco {
default: {
const projectBuilder = this.projectBuilders.find(
pb => pb.id == data.req?.project_id
(pb) => pb.id == data.req?.project_id
);
return projectBuilder?.handleRunTimeChanges(data);
}
@ -453,14 +453,14 @@ export default class Noco {
await migrator.init({
folder: this.config?.toolDir,
env: this.env,
dbAlias: connectionConfig.meta.dbAlias
dbAlias: connectionConfig.meta.dbAlias,
});
}
await migrator.sync({
folder: this.config?.toolDir,
env: this.env,
dbAlias: connectionConfig.meta.dbAlias
dbAlias: connectionConfig.meta.dbAlias,
});
await migrator.migrationsUp({
@ -468,7 +468,7 @@ export default class Noco {
env: this.env,
dbAlias: connectionConfig.meta.dbAlias,
migrationSteps: 99999,
sqlContentMigrate: 1
sqlContentMigrate: 1,
});
log(
@ -494,13 +494,13 @@ export default class Noco {
if (!this.config.auth.jwt.secret) {
let secret = (
await Noco._ncMeta.metaGet('', '', 'nc_store', {
key: 'nc_auth_jwt_secret'
key: 'nc_auth_jwt_secret',
})
)?.value;
if (!secret) {
await Noco._ncMeta.metaInsert('', '', 'nc_store', {
key: 'nc_auth_jwt_secret',
value: secret = uuidv4()
value: (secret = uuidv4()),
});
}
this.config.auth.jwt.secret = secret;
@ -514,13 +514,13 @@ export default class Noco {
}
let serverId = (
await Noco._ncMeta.metaGet('', '', 'nc_store', {
key: 'nc_server_id'
key: 'nc_server_id',
})
)?.value;
if (!serverId) {
await Noco._ncMeta.metaInsert('', '', 'nc_store', {
key: 'nc_server_id',
value: serverId = Tele.id
value: (serverId = Tele.id),
});
}
process.env.NC_SERVER_UUID = serverId;

16
packages/nocodb/src/lib/cache/RedisCacheMgr.ts vendored

@ -98,7 +98,7 @@ export default class RedisCacheMgr extends CacheMgr {
);
return Promise.all(
keys.map(
async k =>
async (k) =>
await this.deepDel(scope, k, CacheDelDirection.CHILD_TO_PARENT)
)
);
@ -106,7 +106,7 @@ export default class RedisCacheMgr extends CacheMgr {
async getList(scope: string, subKeys: string[]): Promise<any[]> {
// remove null from arrays
subKeys = subKeys.filter(k => k);
subKeys = subKeys.filter((k) => k);
// e.g. key = <scope>:<project_id_1>:<base_id_1>:list
const key =
subKeys.length === 0
@ -116,7 +116,7 @@ export default class RedisCacheMgr extends CacheMgr {
const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || [];
log(`RedisCacheMgr::getList: getting list with key ${key}`);
return Promise.all(
arr.map(async k => await this.get(k, CacheGetType.TYPE_OBJECT))
arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT))
);
}
@ -126,7 +126,7 @@ export default class RedisCacheMgr extends CacheMgr {
list: any[]
): Promise<boolean> {
// remove null from arrays
subListKeys = subListKeys.filter(k => k);
subListKeys = subListKeys.filter((k) => k);
// construct key for List
// e.g. <scope>:<project_id_1>:<base_id_1>:list
const listKey =
@ -175,7 +175,7 @@ export default class RedisCacheMgr extends CacheMgr {
continue;
}
// remove target Key
list = list.filter(k => k !== key);
list = list.filter((k) => k !== key);
// delete list
log(`RedisCacheMgr::deepDel: remove listKey ${listKey}`);
await this.del(listKey);
@ -192,7 +192,7 @@ export default class RedisCacheMgr extends CacheMgr {
// given a list key, delete all the children
const listOfChildren = await this.get(key, CacheGetType.TYPE_ARRAY);
// delete each child key
await Promise.all(listOfChildren.map(async k => await this.del(k)));
await Promise.all(listOfChildren.map(async (k) => await this.del(k)));
// delete list key
return await this.del(key);
} else {
@ -207,7 +207,7 @@ export default class RedisCacheMgr extends CacheMgr {
key: string
): Promise<boolean> {
// remove null from arrays
subListKeys = subListKeys.filter(k => k);
subListKeys = subListKeys.filter((k) => k);
// e.g. key = <scope>:<project_id_1>:<base_id_1>:list
const listKey =
subListKeys.length === 0
@ -229,7 +229,7 @@ export default class RedisCacheMgr extends CacheMgr {
const data = await this.client.keys('*');
const res = {};
return await Promise.all(
data.map(async k => {
data.map(async (k) => {
res[k] = await this.get(
k,
k.slice(-4) === 'list'

16
packages/nocodb/src/lib/cache/RedisMockCacheMgr.ts vendored

@ -98,7 +98,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
);
return Promise.all(
keys.map(
async k =>
async (k) =>
await this.deepDel(scope, k, CacheDelDirection.CHILD_TO_PARENT)
)
);
@ -106,7 +106,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
async getList(scope: string, subKeys: string[]): Promise<any[]> {
// remove null from arrays
subKeys = subKeys.filter(k => k);
subKeys = subKeys.filter((k) => k);
// e.g. key = <scope>:<project_id_1>:<base_id_1>:list
const key =
subKeys.length === 0
@ -116,7 +116,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
const arr = (await this.get(key, CacheGetType.TYPE_ARRAY)) || [];
log(`RedisMockCacheMgr::getList: getting list with key ${key}`);
return Promise.all(
arr.map(async k => await this.get(k, CacheGetType.TYPE_OBJECT))
arr.map(async (k) => await this.get(k, CacheGetType.TYPE_OBJECT))
);
}
@ -126,7 +126,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
list: any[]
): Promise<boolean> {
// remove null from arrays
subListKeys = subListKeys.filter(k => k);
subListKeys = subListKeys.filter((k) => k);
// construct key for List
// e.g. <scope>:<project_id_1>:<base_id_1>:list
const listKey =
@ -177,7 +177,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
continue;
}
// remove target Key
list = list.filter(k => k !== key);
list = list.filter((k) => k !== key);
// delete list
log(`RedisMockCacheMgr::deepDel: remove listKey ${listKey}`);
await this.del(listKey);
@ -194,7 +194,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
// given a list key, delete all the children
const listOfChildren = await this.get(key, CacheGetType.TYPE_ARRAY);
// delete each child key
await Promise.all(listOfChildren.map(async k => await this.del(k)));
await Promise.all(listOfChildren.map(async (k) => await this.del(k)));
// delete list key
return await this.del(key);
} else {
@ -209,7 +209,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
key: string
): Promise<boolean> {
// remove null from arrays
subListKeys = subListKeys.filter(k => k);
subListKeys = subListKeys.filter((k) => k);
// e.g. key = <scope>:<project_id_1>:<base_id_1>:list
const listKey =
subListKeys.length === 0
@ -231,7 +231,7 @@ export default class RedisMockCacheMgr extends CacheMgr {
const data = await this.client.keys('*');
const res = {};
return await Promise.all(
data.map(async k => {
data.map(async (k) => {
res[k] = await this.get(
k,
k.slice(-4) === 'list'

206
packages/nocodb/src/lib/db/sql-client/lib/KnexClient.ts

@ -33,7 +33,7 @@ const strTypes = [
'raw',
'long raw',
'bfile',
'nclob'
'nclob',
];
const intTypes = [
'integer',
@ -49,7 +49,7 @@ const intTypes = [
'serial',
'bigserial',
'smallserial',
'number'
'number',
];
const floatTypes = [
'float',
@ -61,7 +61,7 @@ const floatTypes = [
'real',
'money',
'smallmoney',
'dec'
'dec',
];
const dateTypes = [
'date',
@ -76,7 +76,7 @@ const dateTypes = [
'smalldatetime',
'datetimeoffset',
'interval year',
'interval day'
'interval day',
];
const _enumTypes = ['enum', 'set'];
const yearTypes = ['year'];
@ -244,7 +244,7 @@ function renameColumn(_knexClient, connectionConfig, _table, o, n): any {
const obj = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
// console.log(obj);
@ -642,7 +642,7 @@ class KnexClient extends SqlClient {
Tele.emit('evt', {
evt_type: 'project:external',
payload: null,
check: true
check: true,
});
}
} catch (e) {}
@ -661,7 +661,7 @@ class KnexClient extends SqlClient {
sqlite3: 0,
rest: 0,
graphql: 0,
...data
...data,
});
}
@ -702,7 +702,7 @@ class KnexClient extends SqlClient {
if (tableObj.primaryKeys.length > 1) {
if (
lodash.findIndex(tableObj.primaryKeys, {
cn: columnObj.cn
cn: columnObj.cn,
}) > 0
) {
return false;
@ -719,7 +719,7 @@ class KnexClient extends SqlClient {
tinyint: 127,
smallint: 32767,
mediumint: 8388607,
bigint: 2 ^ (63 - 1)
bigint: 2 ^ (63 - 1),
};
const maxUnsigned = {
@ -727,7 +727,7 @@ class KnexClient extends SqlClient {
tinyint: 255,
smallint: 65535,
mediumint: 16777215,
bigint: 2 ^ (64 - 1)
bigint: 2 ^ (64 - 1),
};
if (columnObject.un) {
@ -742,7 +742,7 @@ class KnexClient extends SqlClient {
tinyint: 127,
smallint: 32767,
mediumint: 8388607,
bigint: 2 ^ (63 - 1)
bigint: 2 ^ (63 - 1),
};
const maxUnsigned = {
@ -750,7 +750,7 @@ class KnexClient extends SqlClient {
tinyint: 255,
smallint: 65535,
mediumint: 16777215,
bigint: 2 ^ (64 - 1)
bigint: 2 ^ (64 - 1),
};
if (columnObject.un) {
@ -766,7 +766,7 @@ class KnexClient extends SqlClient {
if (tableObj.primaryKeys.length) {
const dt = this.getKnexDataTypeMock(pk.ct);
const col = lodash.find(tableObj.columns, {
cn: pk.cn
cn: pk.cn,
});
if (dt === 'integer') {
@ -949,7 +949,7 @@ class KnexClient extends SqlClient {
let fakerColumns: any = await this.fakerColumnsList({
seedsFolder: args.seedsFolder,
tn: tn
tn: tn,
});
fakerColumns = fakerColumns.data.list;
@ -1023,7 +1023,9 @@ class KnexClient extends SqlClient {
for (let j = 0; j < this.metaDb.tables[tn].columns.length; ++j) {
const colObj = this.metaDb.tables[tn].columns[j];
const colUiObj = this.metaDb.tables[tn].uiModel.columns[j];
const fakerColObj = fakerColumns.find(col => col.cn === colObj.cn);
const fakerColObj = fakerColumns.find(
(col) => col.cn === colObj.cn
);
console.log(
'\tColumn: ',
@ -1051,7 +1053,7 @@ class KnexClient extends SqlClient {
{
const enums = fakerColObj.dtxp
.split(',')
.map(v => v.slice(1, -1));
.map((v) => v.slice(1, -1));
const enumIndex = Math.floor(Math.random() * enums.length);
rows[k][colObj.cn] = enums[enumIndex];
}
@ -1171,7 +1173,7 @@ class KnexClient extends SqlClient {
case 'json':
rows[k][colObj.cn] = JSON.stringify({
name: faker.name.firstName(),
suffix: faker.name.suffix()
suffix: faker.name.suffix(),
});
break;
case 'bit':
@ -1192,7 +1194,7 @@ class KnexClient extends SqlClient {
} else {
while (1) {
const fakerColumn = fakerColumns.find(
col => col.cn === colObj.cn
(col) => col.cn === colObj.cn
);
const fakerFuncs = fakerColumn.fakerFunction
@ -1276,7 +1278,7 @@ class KnexClient extends SqlClient {
universalQuery = dataHelp.getMysqlSchemaQuery();
const results = await this.knex.raw(universalQuery, [
this.connectionConfig.connection.database
this.connectionConfig.connection.database,
]);
if (results.length) {
@ -1531,7 +1533,7 @@ class KnexClient extends SqlClient {
log.api(data);
evt.evt.emit('UI', {
status: 0,
data: `SQL : ${data}`
data: `SQL : ${data}`,
});
}
@ -1539,7 +1541,7 @@ class KnexClient extends SqlClient {
log.warn(data);
evt.evt.emit('UI', {
status: 1,
data: `SQL : ${data}`
data: `SQL : ${data}`,
});
}
@ -1547,7 +1549,7 @@ class KnexClient extends SqlClient {
log.error(data);
evt.evt.emit('UI', {
status: -1,
data: `SQL : ${data}`
data: `SQL : ${data}`,
});
}
@ -1630,25 +1632,19 @@ class KnexClient extends SqlClient {
async update(args) {
const { tn, data, whereConditions } = args;
const res = await this.sqlClient(tn)
.where(whereConditions)
.update(data);
const res = await this.sqlClient(tn).where(whereConditions).update(data);
return res;
}
async delete(args) {
const { tn, whereConditions } = args;
const res = await this.sqlClient(tn)
.where(whereConditions)
.del();
const res = await this.sqlClient(tn).where(whereConditions).del();
log.debug(res);
return res;
}
async remove(tn, where) {
await this.sqlClient(tn)
.del()
.where(where);
await this.sqlClient(tn).del().where(where);
}
hasTable(_tn) {}
@ -1719,7 +1715,7 @@ class KnexClient extends SqlClient {
'multilinestring',
'multipolygon',
// "geometrycollection",
'json'
'json',
];
return result;
@ -1734,279 +1730,279 @@ class KnexClient extends SqlClient {
dtxp: '10',
dtxs: '',
aggrDataType: 'numeric',
cdf: '1'
cdf: '1',
},
{
type: 'tinyint',
dtxp: '1',
dtxs: '',
aggrDataType: 'numeric',
cdf: '1'
cdf: '1',
},
{
type: 'smallint',
dtxp: '5',
dtxs: '',
aggrDataType: 'numeric',
cdf: '1'
cdf: '1',
},
{
type: 'mediumint',
dtxp: '8',
dtxs: '',
aggrDataType: 'numeric',
cdf: '1'
cdf: '1',
},
{
type: 'bigint',
dtxp: '20',
dtxs: '',
aggrDataType: 'numeric',
cdf: '1'
cdf: '1',
},
{
type: 'bit',
dtxp: '',
dtxs: '',
aggrDataType: 'numeric',
cdf: '1'
cdf: '1',
},
{
type: 'boolean',
dtxp: '',
dtxs: '',
aggrDataType: 'boolean',
cdf: ''
cdf: '',
},
{
type: 'float',
dtxp: '10',
dtxs: '2',
aggrDataType: 'float',
cdf: ''
cdf: '',
},
{
type: 'decimal',
dtxp: '10',
dtxs: '2',
aggrDataType: 'float',
cdf: ''
cdf: '',
},
{
type: 'double',
dtxp: '10',
dtxs: '2',
aggrDataType: 'float',
cdf: ''
cdf: '',
},
{
type: 'serial',
dtxp: '',
dtxs: '',
aggrDataType: 'numeric',
cdf: ''
cdf: '',
},
{
type: 'date',
dtxp: '',
dtxs: '',
aggrDataType: 'datetime',
cdf: ''
cdf: '',
},
{
type: 'datetime',
dtxp: '',
dtxs: '',
aggrDataType: 'datetime',
cdf: ''
cdf: '',
},
{
type: 'timestamp',
dtxp: '',
dtxs: '',
aggrDataType: 'datetime',
cdf: ''
cdf: '',
},
{
type: 'time',
dtxp: '',
dtxs: '',
aggrDataType: 'time',
cdf: ''
cdf: '',
},
{
type: 'year',
dtxp: '',
dtxs: '',
aggrDataType: 'year',
cdf: ''
cdf: '',
},
{
type: 'char',
dtxp: '10',
dtxs: '',
aggrDataType: 'char',
cdf: ''
cdf: '',
},
{
type: 'varchar',
dtxp: '10',
dtxs: '',
aggrDataType: 'char',
cdf: ''
cdf: '',
},
{
type: 'nchar',
dtxp: '10',
dtxs: '',
aggrDataType: 'char',
cdf: ''
cdf: '',
},
{
type: 'text',
dtxp: '',
dtxs: '',
aggrDataType: 'text',
cdf: ''
cdf: '',
},
{
type: 'tinytext',
dtxp: '',
dtxs: '',
aggrDataType: 'text',
cdf: ''
cdf: '',
},
{
type: 'mediumtext',
dtxp: '',
dtxs: '',
aggrDataType: 'text',
cdf: ''
cdf: '',
},
{
type: 'longtext',
dtxp: '',
dtxs: '',
aggrDataType: 'text',
cdf: ''
cdf: '',
},
{
type: 'binary',
dtxp: '255',
dtxs: '',
aggrDataType: 'binary',
cdf: ''
cdf: '',
},
{
type: 'varbinary',
dtxp: '255',
dtxs: '',
aggrDataType: 'binary',
cdf: ''
cdf: '',
},
{
type: 'blob',
dtxp: '',
dtxs: '',
aggrDataType: 'blob',
cdf: ''
cdf: '',
},
{
type: 'tinyblob',
dtxp: '',
dtxs: '',
aggrDataType: 'blob',
cdf: ''
cdf: '',
},
{
type: 'mediumblob',
dtxp: '',
dtxs: '',
aggrDataType: 'blob',
cdf: ''
cdf: '',
},
{
type: 'longblob',
dtxp: '',
dtxs: '',
aggrDataType: 'blob',
cdf: ''
cdf: '',
},
{
type: 'enum',
dtxp: `'a','b'`,
dtxs: '',
aggrDataType: 'enum',
cdf: ''
cdf: '',
},
{
type: 'set',
dtxp: `'a','b'`,
dtxs: '',
aggrDataType: 'set',
cdf: ''
cdf: '',
},
{
type: 'geometry',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'point',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'linestring',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'polygon',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'multipoint',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'multilinestring',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'multipolygon',
dtxp: '',
dtxs: '',
aggrDataType: 'geometry',
cdf: ''
cdf: '',
},
{
type: 'json',
dtxp: '',
dtxs: '',
aggrDataType: 'json',
cdf: ''
}
cdf: '',
},
];
if (args && 'aggrDataType' in args) {
result.data.list = result.data.list.filter(
d => d.aggrDataType === args['aggrDataType']
(d) => d.aggrDataType === args['aggrDataType']
);
}
@ -2115,7 +2111,7 @@ class KnexClient extends SqlClient {
args.sqlClient = this.sqlClient;
/** ************** create table *************** */
await this.sqlClient.schema.createTable(args.table, function(table) {
await this.sqlClient.schema.createTable(args.table, function (table) {
const multiplePks = [];
const columns = JSON.parse(JSON.stringify(args.columns));
@ -2143,7 +2139,7 @@ class KnexClient extends SqlClient {
/** ************** create up & down statements *************** */
const upStatement = this.sqlClient.schema
.createTable(args.table, function(table) {
.createTable(args.table, function (table) {
const multiplePks = [];
const columns = JSON.parse(JSON.stringify(args.columns));
@ -2176,7 +2172,7 @@ class KnexClient extends SqlClient {
/** ************** return files *************** */
result.data.object = {
upStatement,
downStatement
downStatement,
};
} catch (e) {
log.ppe(e, _func);
@ -2218,7 +2214,7 @@ class KnexClient extends SqlClient {
/** ************** return files *************** */
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
@ -2416,13 +2412,13 @@ class KnexClient extends SqlClient {
/** ************** END : has PK changed *************** */
/** ************** update table *************** */
await this.sqlClient.schema.alterTable(args.table, function(table) {
await this.sqlClient.schema.alterTable(args.table, function (table) {
if (pksChanged) {
pkUpdate(table, args.columns, args.originalColumns);
} else {
for (let i = 0; i < args.columns.length; ++i) {
const column = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 8) {
@ -2460,13 +2456,13 @@ class KnexClient extends SqlClient {
} else {
/** ************** create up & down statements *************** */
const upStatement = this.sqlClient.schema
.alterTable(args.table, function(table) {
.alterTable(args.table, function (table) {
if (pksChanged) {
pkUpdate(table, args.columns, args.originalColumns);
} else {
for (let i = 0; i < args.columns.length; ++i) {
const column = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 8) {
// col remove
@ -2494,13 +2490,13 @@ class KnexClient extends SqlClient {
// log.debug(upStatement);
const downStatement = this.sqlClient.schema
.alterTable(args.table, function(table) {
.alterTable(args.table, function (table) {
if (pksChanged) {
pkUpdate(table, args.columns, args.originalColumns);
} else {
for (let i = 0; i < args.columns.length; ++i) {
const column = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 8) {
// col remove
@ -2526,7 +2522,7 @@ class KnexClient extends SqlClient {
result.data.object = {
upStatement,
downStatement
downStatement,
};
}
} catch (e) {
@ -2592,7 +2588,7 @@ class KnexClient extends SqlClient {
/** ************** create up & down statements *************** */
const upStatement = this.sqlClient.schema.dropTable(args.tn).toSQL();
const downStatement = this.sqlClient.schema
.createTable(args.tn, function(tn) {
.createTable(args.tn, function (tn) {
for (let i = 0; i < columns.length; ++i) {
columnCreate(args.sqlClient, tn, columns[i]);
}
@ -2607,7 +2603,7 @@ class KnexClient extends SqlClient {
/** ************** return files *************** */
result.data.object = {
upStatement,
downStatement
downStatement,
};
} catch (e) {
log.ppe(e, _func);
@ -2637,7 +2633,7 @@ class KnexClient extends SqlClient {
args.table = args.tn;
// s = await this.sqlClient.schema.index(Object.keys(args.columns));
await this.sqlClient.schema.table(args.table, function(table) {
await this.sqlClient.schema.table(args.table, function (table) {
if (args.non_unique) {
table.index(args.columns, indexName);
} else {
@ -2648,7 +2644,7 @@ class KnexClient extends SqlClient {
const upStatement =
this.querySeparator() +
this.sqlClient.schema
.table(args.table, function(table) {
.table(args.table, function (table) {
if (args.non_unique) {
table.index(args.columns, indexName);
} else {
@ -2662,7 +2658,7 @@ class KnexClient extends SqlClient {
const downStatement =
this.querySeparator() +
this.sqlClient.schema
.table(args.table, function(table) {
.table(args.table, function (table) {
if (args.non_unique) {
table.dropIndex(args.columns, indexName);
} else {
@ -2673,7 +2669,7 @@ class KnexClient extends SqlClient {
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
// result.data.object = {
@ -2708,7 +2704,7 @@ class KnexClient extends SqlClient {
args.table = args.tn;
// s = await this.sqlClient.schema.index(Object.keys(args.columns));
await this.sqlClient.schema.table(args.table, function(table) {
await this.sqlClient.schema.table(args.table, function (table) {
if (args.non_unique_original) {
table.dropIndex(args.columns, indexName);
} else {
@ -2719,7 +2715,7 @@ class KnexClient extends SqlClient {
const upStatement =
this.querySeparator() +
this.sqlClient.schema
.table(args.table, function(table) {
.table(args.table, function (table) {
if (args.non_unique_original) {
table.dropIndex(args.columns, indexName);
} else {
@ -2733,7 +2729,7 @@ class KnexClient extends SqlClient {
const downStatement =
this.querySeparator() +
this.sqlClient.schema
.table(args.table, function(table) {
.table(args.table, function (table) {
if (args.non_unique_original) {
table.index(args.columns, indexName);
} else {
@ -2744,7 +2740,7 @@ class KnexClient extends SqlClient {
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
@ -2773,7 +2769,7 @@ class KnexClient extends SqlClient {
try {
// s = await this.sqlClient.schema.index(Object.keys(args.columns));
await this.sqlClient.schema.table(args.childTable, function(table) {
await this.sqlClient.schema.table(args.childTable, function (table) {
table = table
.foreign(args.childColumn, foreignKeyName)
.references(args.parentColumn)
@ -2790,7 +2786,7 @@ class KnexClient extends SqlClient {
const upStatement =
this.querySeparator() +
(await this.sqlClient.schema
.table(args.childTable, function(table) {
.table(args.childTable, function (table) {
table = table
.foreign(args.childColumn, foreignKeyName)
.references(args.parentColumn)
@ -2810,7 +2806,7 @@ class KnexClient extends SqlClient {
const downStatement =
this.querySeparator() +
this.sqlClient.schema
.table(args.childTable, function(table) {
.table(args.childTable, function (table) {
table = table.dropForeign(args.childColumn, foreignKeyName);
})
.toQuery();
@ -2830,7 +2826,7 @@ class KnexClient extends SqlClient {
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
@ -2860,14 +2856,14 @@ class KnexClient extends SqlClient {
try {
// const self = this;
await this.sqlClient.schema.table(args.childTable, function(table) {
await this.sqlClient.schema.table(args.childTable, function (table) {
table.dropForeign(args.childColumn, foreignKeyName);
});
const upStatement =
this.querySeparator() +
this.sqlClient.schema
.table(args.childTable, function(table) {
.table(args.childTable, function (table) {
table.dropForeign(args.childColumn, foreignKeyName);
})
.toQuery();
@ -2875,7 +2871,7 @@ class KnexClient extends SqlClient {
const downStatement =
this.querySeparator() +
(await this.sqlClient.schema
.table(args.childTable, function(table) {
.table(args.childTable, function (table) {
table
.foreign(args.childColumn, foreignKeyName)
.references(args.parentColumn)
@ -2898,7 +2894,7 @@ class KnexClient extends SqlClient {
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
@ -3161,7 +3157,7 @@ class KnexClient extends SqlClient {
const fakerColumnPath = path.join(args.seedsFolder, `${args.tn}.json`);
await promisify(jsonfile.writeFile)(fakerColumnPath, args.fakerColumns, {
spaces: 2
spaces: 2,
});
this.emit(`Created : ${fakerColumnPath}`);
@ -3328,7 +3324,7 @@ class KnexClient extends SqlClient {
const seedSettings = path.join(args.seedsFolder, '__xseeds.json');
await promisify(jsonfile.writeFile)(seedSettings, args.settings, {
spaces: 2
spaces: 2,
});
this.emit(`Success : Seed settings updated`);
} catch (e) {
@ -3365,7 +3361,7 @@ class KnexClient extends SqlClient {
genQuery(query, args = [], shouldSanitize: any = 0) {
if (shouldSanitize) {
args = (args || []).map(s =>
args = (args || []).map((s) =>
typeof s === 'string' ? this.sanitize(s) : s
);
}

26
packages/nocodb/src/lib/db/sql-client/lib/data.helper.ts

@ -28,7 +28,7 @@ export const findObjectInArrayByKey = (key, value, objArray) => {
return null;
};
export const round = function(number, precision) {
export const round = function (number, precision) {
const factor = Math.pow(10, precision);
const tempNumber = number * factor;
const roundedTempNumber = Math.round(tempNumber);
@ -42,7 +42,7 @@ export const numberRound = (number, precision) => {
return roundedTempNumber / factor;
};
export const numberGetLength = number => {
export const numberGetLength = (number) => {
let n = number;
if (number < 0) {
@ -52,12 +52,12 @@ export const numberGetLength = number => {
return n.toString().length;
};
export const numberGetFixed = number => {
export const numberGetFixed = (number) => {
//console.log(number, typeof number);
return parseInt(number.toFixed());
};
export const getStepArraySimple = function(min, max, step) {
export const getStepArraySimple = function (min, max, step) {
const arr = [];
for (let i = min; i <= max; i = i + step) {
arr.push(i);
@ -111,7 +111,7 @@ export const getStepArray = (min, max, stddev) => {
return arr;
};
export const getMysqlSchemaQuery = function() {
export const getMysqlSchemaQuery = function () {
return (
'select ' +
'c.table_name as tn, c.column_name as cn, c.ordinal_position as cop,' +
@ -147,11 +147,11 @@ export const getMysqlSchemaQuery = function() {
);
};
export const getChartQuery = function() {
export const getChartQuery = function () {
return 'select ? as ??, count(*) as _count from ?? where ?? between ? and ? ';
};
export const getDataType = function(colType, typesArr) {
export const getDataType = function (colType, typesArr) {
// console.log(colType,typesArr);
for (let i = 0; i < typesArr.length; ++i) {
if (colType.indexOf(typesArr[i]) !== -1) {
@ -161,7 +161,7 @@ export const getDataType = function(colType, typesArr) {
return 0;
};
export const getColumnType = function(column) {
export const getColumnType = function (column) {
const strTypes = [
'varchar',
'text',
@ -186,7 +186,7 @@ export const getColumnType = function(column) {
'raw',
'long raw',
'bfile',
'nclob'
'nclob',
];
const intTypes = [
'bit',
@ -205,7 +205,7 @@ export const getColumnType = function(column) {
'smallserial',
'bool',
'boolean',
'number'
'number',
];
const floatTypes = [
'float',
@ -217,7 +217,7 @@ export const getColumnType = function(column) {
'real',
'money',
'smallmoney',
'dec'
'dec',
];
const dateTypes = [
'date',
@ -233,7 +233,7 @@ export const getColumnType = function(column) {
'smalldatetime',
'datetimeoffset',
'interval year',
'interval day'
'interval day',
];
// const rowIds = ['rowId', 'urowid'];
@ -252,7 +252,7 @@ export const getColumnType = function(column) {
}
};
export const getType = function(colType, typesArr) {
export const getType = function (colType, typesArr) {
// for (let i = 0; i < typesArr.length; ++i) {
// // if (typesArr[i].indexOf(colType) !== -1) {
// // return 1;

142
packages/nocodb/src/lib/db/sql-client/lib/mssql/MssqlClient.ts

@ -32,9 +32,10 @@ class MssqlClient extends KnexClient {
upStatement: [{ sql: query }],
downStatement: [
{
sql: this.querySeparator() + `CREATE SEQUENCE ${args.sequence_name}`
}
]
sql:
this.querySeparator() + `CREATE SEQUENCE ${args.sequence_name}`,
},
],
};
} catch (e) {
log.ppe(e, _func);
@ -69,11 +70,11 @@ class MssqlClient extends KnexClient {
args.databaseName = this.connectionConfig.connection.database;
const rows = await this.sqlClient.raw(`SELECT * FROM sys.SEQUENCES;`);
result.data.list = rows.map(seq => {
result.data.list = rows.map((seq) => {
return {
...seq,
sequence_name: seq.name,
original_sequence_name: seq.name
original_sequence_name: seq.name,
};
});
} catch (e) {
@ -113,8 +114,10 @@ class MssqlClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: query }],
downStatement: [
{ sql: this.querySeparator() + `DROP SEQUENCE ${args.sequence_name}` }
]
{
sql: this.querySeparator() + `DROP SEQUENCE ${args.sequence_name}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -157,7 +160,7 @@ class MssqlClient extends KnexClient {
await this.sqlClient.raw(upQuery);
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, func);
@ -230,7 +233,7 @@ class MssqlClient extends KnexClient {
'uniqueidentifier',
'varbinary',
'xml',
'varchar'
'varchar',
];
return result;
@ -301,7 +304,7 @@ class MssqlClient extends KnexClient {
EXEC('CREATE SCHEMA ??')`,
[
this.connectionConfig.searchPath[0],
this.connectionConfig.searchPath[0]
this.connectionConfig.searchPath[0],
]
);
}
@ -360,7 +363,7 @@ class MssqlClient extends KnexClient {
if (!exists) {
await this.sqlClient.schema.createTable(
this.getTnPath(args.tn),
function(table) {
function (table) {
table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
@ -864,7 +867,7 @@ class MssqlClient extends KnexClient {
CASCADE: 'CASCADE',
RESTRICT: 'RESTRICT',
SET_NULL: 'SET NULL',
SET_DEFAULT: 'SET DEFAULT'
SET_DEFAULT: 'SET DEFAULT',
};
for (const row of response) {
@ -929,7 +932,7 @@ class MssqlClient extends KnexClient {
CASCADE: 'CASCADE',
RESTRICT: 'RESTRICT',
SET_NULL: 'SET NULL',
SET_DEFAULT: 'SET DEFAULT'
SET_DEFAULT: 'SET DEFAULT',
};
for (const row of response) {
@ -1354,9 +1357,9 @@ class MssqlClient extends KnexClient {
upStatement: [{ sql: query }],
downStatement: [
{
sql: `${this.querySeparator()}${args.oldStatement}`
}
]
sql: `${this.querySeparator()}${args.oldStatement}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1378,7 +1381,7 @@ class MssqlClient extends KnexClient {
await this.sqlClient.raw(upQuery);
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -1403,12 +1406,12 @@ class MssqlClient extends KnexClient {
{
sql:
this.querySeparator() +
`DROP PROCEDURE IF EXISTS ${args.procedure_name}`
}
`DROP PROCEDURE IF EXISTS ${args.procedure_name}`,
},
],
downStatement: [
{ sql: this.querySeparator() + `${args.create_procedure}` }
]
{ sql: this.querySeparator() + `${args.create_procedure}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1436,15 +1439,15 @@ class MssqlClient extends KnexClient {
await this.sqlClient.raw(`${args.create_function}`);
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + `${args.create_function}` }
{ sql: this.querySeparator() + `${args.create_function}` },
],
downStatement: [
{
sql:
this.querySeparator() +
`DROP FUNCTION IF EXISTS ${args.function_name}`
}
]
`DROP FUNCTION IF EXISTS ${args.function_name}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1478,8 +1481,8 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`DROP FUNCTION IF EXISTS ${
args.function_name
};${this.querySeparator()}\n${args.create_function}`
}
};${this.querySeparator()}\n${args.create_function}`,
},
],
downStatement: [
{
@ -1487,9 +1490,9 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`DROP FUNCTION IF EXISTS ${
args.function_name
};${this.querySeparator()} ${args.oldCreateFunction}`
}
]
};${this.querySeparator()} ${args.oldCreateFunction}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1517,13 +1520,14 @@ class MssqlClient extends KnexClient {
await this.sqlClient.raw(`${args.create_procedure}`);
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + `${args.create_procedure}` }
{ sql: this.querySeparator() + `${args.create_procedure}` },
],
downStatement: [
{
sql: this.querySeparator() + `DROP PROCEDURE ${args.procedure_name}`
}
]
sql:
this.querySeparator() + `DROP PROCEDURE ${args.procedure_name}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1559,8 +1563,8 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`DROP PROCEDURE IF EXISTS ${
args.procedure_name
};${this.querySeparator()}\n${args.create_procedure}`
}
};${this.querySeparator()}\n${args.create_procedure}`,
},
],
downStatement: [
{
@ -1568,9 +1572,9 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`DROP PROCEDURE IF EXISTS ${
args.procedure_name
};${this.querySeparator()}${args.oldCreateProcedure}`
}
]
};${this.querySeparator()}${args.oldCreateProcedure}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1602,8 +1606,8 @@ class MssqlClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [
{ sql: this.querySeparator() + `DROP TRIGGER ${args.trigger_name}` }
]
{ sql: this.querySeparator() + `DROP TRIGGER ${args.trigger_name}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1643,8 +1647,8 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`ALTER TRIGGER ${args.trigger_name} ON ${this.getTnPath(
args.tn
)} \n${args.timing} ${args.event}\n AS\n${args.statement}`
}
)} \n${args.timing} ${args.event}\n AS\n${args.statement}`,
},
],
downStatement: [
{
@ -1652,9 +1656,9 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`ALTER TRIGGER ${args.trigger_name} ON ${this.getTnPath(
args.tn
)} \n${args.timing} ${args.event}\n AS\n${args.statement}`
}
]
)} \n${args.timing} ${args.event}\n AS\n${args.statement}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1683,8 +1687,8 @@ class MssqlClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [
{ sql: this.querySeparator() + `DROP VIEW ${args.view_name}` }
]
{ sql: this.querySeparator() + `DROP VIEW ${args.view_name}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1719,9 +1723,9 @@ class MssqlClient extends KnexClient {
this.querySeparator() +
`DROP VIEW ${args.view_name} ; ${this.querySeparator()}${
args.oldViewDefination
};`
}
]
};`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1754,9 +1758,9 @@ class MssqlClient extends KnexClient {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [
{
sql: this.querySeparator() + args.oldViewDefination
}
]
sql: this.querySeparator() + args.oldViewDefination,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1824,8 +1828,8 @@ class MssqlClient extends KnexClient {
upStatement: [{ sql: upQuery }, ...triggerStatements.upStatement],
downStatement: [
...triggerStatements.downStatement,
{ sql: downStatement }
]
{ sql: downStatement },
],
};
} catch (e) {
log.ppe(e, _func);
@ -1840,7 +1844,7 @@ class MssqlClient extends KnexClient {
let upQuery = '';
let downQuery = '';
const pk = args.columns.find(c => c.pk);
const pk = args.columns.find((c) => c.pk);
if (!pk) return result;
for (let i = 0; i < args.columns.length; i++) {
@ -1875,7 +1879,7 @@ class MssqlClient extends KnexClient {
let upQuery = '';
let downQuery = '';
const pk = args.columns.find(c => c.pk);
const pk = args.columns.find((c) => c.pk);
if (!pk) return result;
for (let i = 0; i < args.columns.length; i++) {
@ -1948,7 +1952,7 @@ class MssqlClient extends KnexClient {
for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 4) {
@ -2023,12 +2027,12 @@ class MssqlClient extends KnexClient {
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + upQuery },
...afterUpdate.upStatement
...afterUpdate.upStatement,
],
downStatement: [
...afterUpdate.downStatement,
{ sql: this.querySeparator() + downQuery }
]
{ sql: this.querySeparator() + downQuery },
],
};
} catch (e) {
log.ppe(e, _func);
@ -2061,7 +2065,7 @@ class MssqlClient extends KnexClient {
this.emit(`Success : ${upStatement}`);
let relationsList: any = await this.relationList({
tn: this.getTnPath(args.tn)
tn: this.getTnPath(args.tn),
});
relationsList = relationsList.data.list;
@ -2070,7 +2074,7 @@ class MssqlClient extends KnexClient {
downQuery +=
this.querySeparator() +
(await this.sqlClient.schema
.table(this.getTnPath(relation.tn), function(table) {
.table(this.getTnPath(relation.tn), function (table) {
table = table
.foreign(relation.cn, null)
.references(relation.rcn)
@ -2102,7 +2106,7 @@ class MssqlClient extends KnexClient {
tn: this.getTnPath(args.tn),
indexName: key_name,
non_unique,
columns: []
columns: [],
};
}
indexesMap[key_name].columns.push(cn);
@ -2114,7 +2118,7 @@ class MssqlClient extends KnexClient {
downQuery +=
this.querySeparator() +
this.sqlClient.schema
.table(tn, function(table) {
.table(tn, function (table) {
if (non_unique) {
table.index(columns, key_name);
} else {
@ -2130,7 +2134,7 @@ class MssqlClient extends KnexClient {
/** ************** return files *************** */
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -2155,7 +2159,7 @@ class MssqlClient extends KnexClient {
result = await this.columnList(args);
const upQuery = this.createTable(args.tn, {
tn: args.tn,
columns: result.data.list
columns: result.data.list,
});
result.data = upQuery;
} catch (e) {
@ -2508,7 +2512,7 @@ class MssqlClient extends KnexClient {
'tinyint',
'geometry',
'datetime',
'text'
'text',
].includes(n.dt)
)
query += n.dtxp && n.dtxp != -1 ? `(${n.dtxp})` : '';

2
packages/nocodb/src/lib/db/sql-client/lib/mssql/mssql.queries.ts

@ -35,5 +35,5 @@ export default {
xml: {},
'Spatial Geometry Types': {},
'Spatial Geography Types': {},
table: {}
table: {},
};

161
packages/nocodb/src/lib/db/sql-client/lib/mysql/MysqlClient.ts

@ -36,7 +36,7 @@ class MysqlClient extends KnexClient {
log.api(data);
evt.evt.emit('UI', {
status: 0,
data: `SQL : ${data}`
data: `SQL : ${data}`,
});
}
@ -44,7 +44,7 @@ class MysqlClient extends KnexClient {
log.warn(data);
evt.evt.emit('UI', {
status: 1,
data: `SQL : ${data}`
data: `SQL : ${data}`,
});
}
@ -52,7 +52,7 @@ class MysqlClient extends KnexClient {
log.error(data);
evt.evt.emit('UI', {
status: -1,
data: `SQL : ${data}`
data: `SQL : ${data}`,
});
}
@ -213,7 +213,7 @@ class MysqlClient extends KnexClient {
'multilinestring',
'multipolygon',
// "geometrycollection",
'json'
'json',
];
return result;
@ -313,7 +313,7 @@ class MysqlClient extends KnexClient {
const tempSqlClient = knex(connectionParamsWithoutDb);
const data = await tempSqlClient.raw(this.queries[func].default.sql, [
args.database
args.database,
]);
log.debug('Create database if not exists', data);
@ -360,7 +360,7 @@ class MysqlClient extends KnexClient {
const exists = await this.sqlClient.schema.hasTable(args.tn);
if (!exists) {
await this.sqlClient.schema.createTable(args.tn, function(table) {
await this.sqlClient.schema.createTable(args.tn, function (table) {
table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
@ -431,7 +431,7 @@ class MysqlClient extends KnexClient {
try {
const rows = await this.sqlClient.raw(this.queries[func].default.sql, [
`${args.databaseName}`
`${args.databaseName}`,
]);
result.data.value = rows.length > 0;
} catch (e) {
@ -505,7 +505,7 @@ class MysqlClient extends KnexClient {
if (response.length === 2) {
for (let i = 0; i < response[0].length; ++i) {
if (!keyInResponse) {
keyInResponse = Object.keys(response[0][i]).find(k =>
keyInResponse = Object.keys(response[0][i]).find((k) =>
/^Tables_in_/i.test(k)
);
}
@ -523,7 +523,7 @@ class MysqlClient extends KnexClient {
this.emitTele({
mysql: 1,
table_count: result.data.list.length,
api_count: result.data.list.length * 10
api_count: result.data.list.length * 10,
});
} catch (e) {
log.ppe(e, func);
@ -550,7 +550,7 @@ class MysqlClient extends KnexClient {
order by schema_name;`
);
if (response.length === 2) {
result.data.list = response[0].map(v =>
result.data.list = response[0].map((v) =>
lodash.mapKeys(v, (_, k) => k.toLowerCase())
);
} else {
@ -604,7 +604,7 @@ class MysqlClient extends KnexClient {
const response = await this.sqlClient.raw(
await this._getQuery({
func
func,
}),
[args.databaseName, args.tn, args.databaseName, args.tn]
);
@ -753,7 +753,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i];
index = lodash.mapKeys(index, function(_v, k) {
index = lodash.mapKeys(index, function (_v, k) {
return k.toLowerCase();
});
index.cn = index.column_name;
@ -800,7 +800,7 @@ class MysqlClient extends KnexClient {
try {
const response = await this.sqlClient.raw(
await this._getQuery({
func
func,
}),
[this.connectionConfig.connection.database, args.tn]
);
@ -810,7 +810,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i];
index = lodash.mapKeys(index, function(_v, k) {
index = lodash.mapKeys(index, function (_v, k) {
return k.toLowerCase();
});
indexes.push(index);
@ -868,7 +868,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let relation = response[0][i];
relation = lodash.mapKeys(relation, function(_v, k) {
relation = lodash.mapKeys(relation, function (_v, k) {
return k.toLowerCase();
});
relations.push(relation);
@ -923,7 +923,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let relation = response[0][i];
relation = lodash.mapKeys(relation, function(_v, k) {
relation = lodash.mapKeys(relation, function (_v, k) {
return k.toLowerCase();
});
relations.push(relation);
@ -934,7 +934,7 @@ class MysqlClient extends KnexClient {
this.emitTele({
mysql: 1,
relation_count: result.data.list.length,
api_count: result.data.list.length * 10
api_count: result.data.list.length * 10,
});
} else {
log.debug('Unknown response for databaseList:', response);
@ -985,7 +985,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let trigger = response[0][i];
trigger = lodash.mapKeys(trigger, function(_v, k) {
trigger = lodash.mapKeys(trigger, function (_v, k) {
return k.toLowerCase();
});
trigger.trigger_name = trigger.trigger;
@ -1040,7 +1040,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let fn = response[0][i];
fn = lodash.mapKeys(fn, function(_v, k) {
fn = lodash.mapKeys(fn, function (_v, k) {
return k.toLowerCase();
});
fn.function_name = fn.name;
@ -1099,7 +1099,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let procedure = response[0][i];
procedure = lodash.mapKeys(procedure, function(_v, k) {
procedure = lodash.mapKeys(procedure, function (_v, k) {
return k.toLowerCase();
});
procedure.procedure_name = procedure.name;
@ -1151,7 +1151,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
if (!keyInResponse) {
keyInResponse = Object.keys(response[0][i]).find(k =>
keyInResponse = Object.keys(response[0][i]).find((k) =>
/^Tables_in_/i.test(k)
);
}
@ -1205,7 +1205,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let _function = response[0][i];
_function = lodash.mapKeys(_function, function(_v, k) {
_function = lodash.mapKeys(_function, function (_v, k) {
return k.toLowerCase();
});
@ -1259,7 +1259,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let procedure = response[0][i];
procedure = lodash.mapKeys(procedure, function(_v, k) {
procedure = lodash.mapKeys(procedure, function (_v, k) {
return k.toLowerCase();
});
@ -1311,7 +1311,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let view = response[0][i];
view = lodash.mapKeys(view, function(_v, k) {
view = lodash.mapKeys(view, function (_v, k) {
return k.toLowerCase();
});
@ -1375,7 +1375,7 @@ class MysqlClient extends KnexClient {
log.api(`${func}:args:`, args);
// `create database ${args.database_name}`
const rows = await this.sqlClient.raw(this.queries[func].default.sql, [
args.database_name
args.database_name,
]);
return rows;
}
@ -1385,7 +1385,7 @@ class MysqlClient extends KnexClient {
log.api(`${func}:args:`, args);
// `drop database ${args.database_name}`
const rows = await this.sqlClient.raw(this.queries[func].default.sql, [
args.database_name
args.database_name,
]);
return rows;
}
@ -1413,8 +1413,8 @@ class MysqlClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: query }],
downStatement: [
{ sql: this.querySeparator() + `DROP TRIGGER ${args.trigger_name}` }
]
{ sql: this.querySeparator() + `DROP TRIGGER ${args.trigger_name}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1454,8 +1454,8 @@ class MysqlClient extends KnexClient {
args.trigger_name
}\` \n${args.timing} ${args.event}\nON ${args.tn} FOR EACH ROW\n${
args.statement
}`
}
}`,
},
],
downStatement: [
{
@ -1463,9 +1463,9 @@ class MysqlClient extends KnexClient {
args.trigger_name
}\` \n${args.timing} ${args.event}\nON ${args.tn} FOR EACH ROW\n${
args.oldStatement
}`
}
]
}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1493,9 +1493,9 @@ class MysqlClient extends KnexClient {
args.trigger_name
}\` \n${args.timing} ${args.event}\nON ${args.tn} FOR EACH ROW\n${
args.oldStatement
}`
}
]
}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1526,8 +1526,8 @@ class MysqlClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: query }],
downStatement: [
{ sql: this.querySeparator() + `DROP VIEW ${args.view_name}` }
]
{ sql: this.querySeparator() + `DROP VIEW ${args.view_name}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1562,9 +1562,9 @@ class MysqlClient extends KnexClient {
{
sql:
this.querySeparator() +
`CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`
}
]
`CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1599,9 +1599,9 @@ class MysqlClient extends KnexClient {
{
sql:
this.querySeparator() +
`CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`
}
]
`CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1627,11 +1627,13 @@ class MysqlClient extends KnexClient {
await this.sqlClient.raw(`${args.create_function}`);
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + `${args.create_function}` }
{ sql: this.querySeparator() + `${args.create_function}` },
],
downStatement: [
{ sql: this.querySeparator() + `DROP FUNCTION ${args.function_name}` }
]
{
sql: this.querySeparator() + `DROP FUNCTION ${args.function_name}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1664,8 +1666,8 @@ class MysqlClient extends KnexClient {
this.querySeparator() +
`DROP FUNCTION IF EXISTS ${
args.function_name
};${this.querySeparator()}\n${args.create_function}`
}
};${this.querySeparator()}\n${args.create_function}`,
},
],
downStatement: [
{
@ -1673,9 +1675,9 @@ class MysqlClient extends KnexClient {
this.querySeparator() +
`DROP FUNCTION IF EXISTS ${
args.function_name
};${this.querySeparator()}${args.oldCreateFunction}`
}
]
};${this.querySeparator()}${args.oldCreateFunction}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1704,12 +1706,12 @@ class MysqlClient extends KnexClient {
{
sql:
this.querySeparator() +
`DROP FUNCTION IF EXISTS ${args.function_name}`
}
`DROP FUNCTION IF EXISTS ${args.function_name}`,
},
],
downStatement: [
{ sql: this.querySeparator() + `${args.create_function}` }
]
{ sql: this.querySeparator() + `${args.create_function}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1735,13 +1737,14 @@ class MysqlClient extends KnexClient {
await this.sqlClient.raw(`${args.create_procedure}`);
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + `${args.create_procedure}` }
{ sql: this.querySeparator() + `${args.create_procedure}` },
],
downStatement: [
{
sql: this.querySeparator() + `DROP PROCEDURE ${args.procedure_name}`
}
]
sql:
this.querySeparator() + `DROP PROCEDURE ${args.procedure_name}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1776,8 +1779,8 @@ class MysqlClient extends KnexClient {
this.querySeparator() +
`DROP PROCEDURE IF EXISTS ${
args.procedure_name
}; ${this.querySeparator()} \n${args.create_procedure}`
}
}; ${this.querySeparator()} \n${args.create_procedure}`,
},
],
downStatement: [
{
@ -1785,9 +1788,9 @@ class MysqlClient extends KnexClient {
this.querySeparator() +
`DROP PROCEDURE IF EXISTS ${
args.procedure_name
}; ${this.querySeparator()} ${args.oldCreateProcedure}`
}
]
}; ${this.querySeparator()} ${args.oldCreateProcedure}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -1818,12 +1821,12 @@ class MysqlClient extends KnexClient {
{
sql:
this.querySeparator() +
`DROP PROCEDURE IF EXISTS ${args.procedure_name}`
}
`DROP PROCEDURE IF EXISTS ${args.procedure_name}`,
},
],
downStatement: [
{ sql: this.querySeparator() + `${args.create_procedure}` }
]
{ sql: this.querySeparator() + `${args.create_procedure}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1865,7 +1868,7 @@ class MysqlClient extends KnexClient {
}
mapFieldWithSuggestedFakerFn(cols) {
const newCols = cols.map(col => {
const newCols = cols.map((col) => {
let suggestion = null;
let l_score = Infinity;
const nativeType = findDataType.mapDataType(col.dt);
@ -1923,8 +1926,8 @@ class MysqlClient extends KnexClient {
rows: { value: 8, description: 'Maximum number of rows' },
foreign_key_rows: {
value: 2,
description: '1:n - Total number foreign key per relation'
}
description: '1:n - Total number foreign key per relation',
},
},
{ spaces: 2 }
);
@ -1965,7 +1968,7 @@ class MysqlClient extends KnexClient {
await this.fakerColumnsCreate({
seedsFolder: args.seedsFolder,
tn: table.tn,
fakerColumns: columns
fakerColumns: columns,
});
}
@ -2030,7 +2033,7 @@ class MysqlClient extends KnexClient {
/**************** return files *************** */
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downStatement }]
downStatement: [{ sql: downStatement }],
};
} catch (e) {
log.ppe(e, _func);
@ -2083,7 +2086,7 @@ class MysqlClient extends KnexClient {
for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 4) {
@ -2134,7 +2137,7 @@ class MysqlClient extends KnexClient {
if (upQuery) {
upQuery = this.genQuery(`ALTER TABLE ?? ${this.sanitize(upQuery)};`, [
args.tn
args.tn,
]);
downQuery = this.genQuery(
`ALTER TABLE ?? ${this.sanitize(downQuery)};`,
@ -2148,7 +2151,7 @@ class MysqlClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: this.querySeparator() + upQuery }],
downStatement: [{ sql: this.querySeparator() + downQuery }]
downStatement: [{ sql: this.querySeparator() + downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -2194,7 +2197,7 @@ class MysqlClient extends KnexClient {
/** ************** return files *************** */
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -2437,7 +2440,7 @@ class MysqlClient extends KnexClient {
query += this.alterTablePK(args.columns, [], query, true);
query = this.genQuery(`CREATE TABLE ?? (${this.sanitize(query)});`, [
args.tn
args.tn,
]);
return query;

2
packages/nocodb/src/lib/db/sql-client/lib/mysql/TidbClient.ts

@ -33,7 +33,7 @@ class Tidb extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i];
index = _.mapKeys(index, function(_v, k) {
index = _.mapKeys(index, function (_v, k) {
return k.toLowerCase();
});
indexes.push(index);

2
packages/nocodb/src/lib/db/sql-client/lib/mysql/VitessClient.ts

@ -220,7 +220,7 @@ class Vitess extends MysqlClient {
for (let i = 0; i < response[0].length; ++i) {
let index = response[0][i];
index = _.mapKeys(index, function(_v, k) {
index = _.mapKeys(index, function (_v, k) {
return k.toLowerCase();
});
indexes.push(index);

282
packages/nocodb/src/lib/db/sql-client/lib/mysql/fakerFunctionList.ts

@ -3,241 +3,241 @@ export default [
name: 'zipCode',
group: 'address',
value: 'address.zipCode',
type: 'string'
type: 'string',
},
{
name: 'city',
group: 'address',
value: 'address.city',
type: 'string'
type: 'string',
},
{
name: 'cityPrefix',
group: 'address',
value: 'address.cityPrefix',
type: 'string'
type: 'string',
},
{
name: 'citySuffix',
group: 'address',
value: 'address.citySuffix',
type: 'string'
type: 'string',
},
{
name: 'streetName',
group: 'address',
value: 'address.streetName',
type: 'string'
type: 'string',
},
{
name: 'streetAddress',
group: 'address',
value: 'address.streetAddress',
type: 'string'
type: 'string',
},
{
name: 'streetSuffix',
group: 'address',
value: 'address.streetSuffix',
type: 'string'
type: 'string',
},
{
name: 'streetPrefix',
group: 'address',
value: 'address.streetPrefix',
type: 'string'
type: 'string',
},
{
name: 'secondaryAddress',
group: 'address',
value: 'address.secondaryAddress',
type: 'string'
type: 'string',
},
{
name: 'county',
group: 'address',
value: 'address.county',
type: 'string'
type: 'string',
},
{
name: 'country',
group: 'address',
value: 'address.country',
type: 'string'
type: 'string',
},
{
name: 'countryCode',
group: 'address',
value: 'address.countryCode',
type: 'string'
type: 'string',
},
{
name: 'state',
group: 'address',
value: 'address.state',
type: 'string'
type: 'string',
},
{
name: 'stateAbbr',
group: 'address',
value: 'address.stateAbbr',
type: 'string'
type: 'string',
},
{
name: 'latitude',
group: 'address',
value: 'address.latitude',
type: 'number'
type: 'number',
},
{
name: 'longitude',
group: 'address',
value: 'address.longitude',
type: 'number'
type: 'number',
},
{
name: 'color',
group: 'commerce',
value: 'commerce.color',
type: 'string'
type: 'string',
},
{
name: 'department',
group: 'commerce',
value: 'commerce.department',
type: 'string'
type: 'string',
},
{
name: 'productName',
group: 'commerce',
value: 'commerce.productName',
type: 'string'
type: 'string',
},
{
name: 'price',
group: 'commerce',
value: 'commerce.price',
type: 'number'
type: 'number',
},
{
name: 'productAdjective',
group: 'commerce',
value: 'commerce.productAdjective',
type: 'string'
type: 'string',
},
{
name: 'productMaterial',
group: 'commerce',
value: 'commerce.productMaterial',
type: 'string'
type: 'string',
},
{
name: 'product',
group: 'commerce',
value: 'commerce.product',
type: 'string'
type: 'string',
},
{
name: 'suffixes',
group: 'company',
value: 'company.suffixes',
type: 'string'
type: 'string',
},
{
name: 'companyName',
group: 'company',
value: 'company.companyName',
type: 'string'
type: 'string',
},
{
name: 'companySuffix',
group: 'company',
value: 'company.companySuffix',
type: 'string'
type: 'string',
},
{
name: 'catchPhrase',
group: 'company',
value: 'company.catchPhrase',
type: 'string'
type: 'string',
},
{
name: 'bs',
group: 'company',
value: 'company.bs',
type: 'string'
type: 'string',
},
{
name: 'catchPhraseAdjective',
group: 'company',
value: 'company.catchPhraseAdjective',
type: 'string'
type: 'string',
},
{
name: 'catchPhraseDescriptor',
group: 'company',
value: 'company.catchPhraseDescriptor',
type: 'string'
type: 'string',
},
{
name: 'catchPhraseNoun',
group: 'company',
value: 'company.catchPhraseNoun',
type: 'string'
type: 'string',
},
{
name: 'bsAdjective',
group: 'company',
value: 'company.bsAdjective',
type: 'string'
type: 'string',
},
{
name: 'bsBuzz',
group: 'company',
value: 'company.bsBuzz',
type: 'string'
type: 'string',
},
{
name: 'bsNoun',
group: 'company',
value: 'company.bsNoun',
type: 'string'
type: 'string',
},
{
name: 'column',
group: 'database',
value: 'database.column',
type: 'string'
type: 'string',
},
{
name: 'type',
group: 'database',
value: 'database.type',
type: 'string'
type: 'string',
},
{
name: 'collation',
group: 'database',
value: 'database.collation',
type: 'string'
type: 'string',
},
{
name: 'engine',
group: 'database',
value: 'database.engine',
type: 'string'
type: 'string',
},
{
name: 'past',
group: 'date',
value: 'date.past',
type: 'date'
type: 'date',
},
{
name: 'future',
group: 'date',
value: 'date.future',
type: 'date'
type: 'date',
},
// {
// name: 'between',
@ -249,133 +249,133 @@ export default [
name: 'recent',
group: 'date',
value: 'date.recent',
type: 'date'
type: 'date',
},
{
name: 'soon',
group: 'date',
value: 'date.soon',
type: 'date'
type: 'date',
},
{
name: 'month',
group: 'date',
value: 'date.month',
type: 'string'
type: 'string',
},
{
name: 'weekday',
group: 'date',
value: 'date.weekday',
type: 'string'
type: 'string',
},
{
name: 'account',
group: 'finance',
value: 'finance.account',
type: 'string'
type: 'string',
},
{
name: 'accountName',
group: 'finance',
value: 'finance.accountName',
type: 'string'
type: 'string',
},
{
name: 'mask',
group: 'finance',
value: 'finance.mask',
type: 'string'
type: 'string',
},
{
name: 'amount',
group: 'finance',
value: 'finance.amount',
type: 'number'
type: 'number',
},
{
name: 'transactionType',
group: 'finance',
value: 'finance.transactionType',
type: 'string'
type: 'string',
},
{
name: 'currencyCode',
group: 'finance',
value: 'finance.currencyCode',
type: 'string'
type: 'string',
},
{
name: 'currencyName',
group: 'finance',
value: 'finance.currencyName',
type: 'string'
type: 'string',
},
{
name: 'currencySymbol',
group: 'finance',
value: 'finance.currencySymbol',
type: 'string'
type: 'string',
},
{
name: 'bitcoinAddress',
group: 'finance',
value: 'finance.bitcoinAddress',
type: 'string'
type: 'string',
},
{
name: 'ethereumAddress',
group: 'finance',
value: 'finance.ethereumAddress',
type: 'string'
type: 'string',
},
{
name: 'iban',
group: 'finance',
value: 'finance.iban',
type: 'string'
type: 'string',
},
{
name: 'bic',
group: 'finance',
value: 'finance.bic',
type: 'string'
type: 'string',
},
{
name: 'abbreviation',
group: 'hacker',
value: 'hacker.abbreviation',
type: 'string'
type: 'string',
},
{
name: 'adjective',
group: 'hacker',
value: 'hacker.adjective',
type: 'string'
type: 'string',
},
{
name: 'noun',
group: 'hacker',
value: 'hacker.noun',
type: 'string'
type: 'string',
},
{
name: 'verb',
group: 'hacker',
value: 'hacker.verb',
type: 'string'
type: 'string',
},
{
name: 'ingverb',
group: 'hacker',
value: 'hacker.ingverb',
type: 'string'
type: 'string',
},
{
name: 'phrase',
group: 'hacker',
value: 'hacker.phrase',
type: 'string'
type: 'string',
},
// {
// name: 'randomize',
@ -417,361 +417,361 @@ export default [
name: 'createCard',
group: 'helpers',
value: 'helpers.createCard',
type: 'string'
type: 'string',
},
{
name: 'contextualCard',
group: 'helpers',
value: 'helpers.contextualCard',
type: 'string'
type: 'string',
},
{
name: 'userCard',
group: 'helpers',
value: 'helpers.userCard',
type: 'string'
type: 'string',
},
{
name: 'createTransaction',
group: 'helpers',
value: 'helpers.createTransaction',
type: 'string'
type: 'string',
},
{
name: 'image',
group: 'image',
value: 'image.image',
type: 'string'
type: 'string',
},
{
name: 'avatar',
group: 'image',
value: 'image.avatar',
type: 'string'
type: 'string',
},
{
name: 'imageUrl',
group: 'image',
value: 'image.imageUrl',
type: 'string'
type: 'string',
},
{
name: 'abstract',
group: 'image',
value: 'image.abstract',
type: 'string'
type: 'string',
},
{
name: 'animals',
group: 'image',
value: 'image.animals',
type: 'string'
type: 'string',
},
{
name: 'business',
group: 'image',
value: 'image.business',
type: 'string'
type: 'string',
},
{
name: 'cats',
group: 'image',
value: 'image.cats',
type: 'string'
type: 'string',
},
{
name: 'city',
group: 'image',
value: 'image.city',
type: 'string'
type: 'string',
},
{
name: 'food',
group: 'image',
value: 'image.food',
type: 'string'
type: 'string',
},
{
name: 'nightlife',
group: 'image',
value: 'image.nightlife',
type: 'string'
type: 'string',
},
{
name: 'fashion',
group: 'image',
value: 'image.fashion',
type: 'string'
type: 'string',
},
{
name: 'people',
group: 'image',
value: 'image.people',
type: 'string'
type: 'string',
},
{
name: 'nature',
group: 'image',
value: 'image.nature',
type: 'string'
type: 'string',
},
{
name: 'sports',
group: 'image',
value: 'image.sports',
type: 'string'
type: 'string',
},
{
name: 'technics',
group: 'image',
value: 'image.technics',
type: 'string'
type: 'string',
},
{
name: 'transport',
group: 'image',
value: 'image.transport',
type: 'string'
type: 'string',
},
{
name: 'dataUri',
group: 'image',
value: 'image.dataUri',
type: 'string'
type: 'string',
},
{
name: 'avatar',
group: 'internet',
value: 'internet.avatar',
type: 'string'
type: 'string',
},
{
name: 'email',
group: 'internet',
value: 'internet.email',
type: 'string'
type: 'string',
},
{
name: 'exampleEmail',
group: 'internet',
value: 'internet.exampleEmail',
type: 'string'
type: 'string',
},
{
name: 'userName',
group: 'internet',
value: 'internet.userName',
type: 'string'
type: 'string',
},
{
name: 'protocol',
group: 'internet',
value: 'internet.protocol',
type: 'string'
type: 'string',
},
{
name: 'url',
group: 'internet',
value: 'internet.url',
type: 'string'
type: 'string',
},
{
name: 'domainName',
group: 'internet',
value: 'internet.domainName',
type: 'string'
type: 'string',
},
{
name: 'domainSuffix',
group: 'internet',
value: 'internet.domainSuffix',
type: 'string'
type: 'string',
},
{
name: 'domainWord',
group: 'internet',
value: 'internet.domainWord',
type: 'string'
type: 'string',
},
{
name: 'ip',
group: 'internet',
value: 'internet.ip',
type: 'string'
type: 'string',
},
{
name: 'ipv6',
group: 'internet',
value: 'internet.ipv6',
type: 'string'
type: 'string',
},
{
name: 'userAgent',
group: 'internet',
value: 'internet.userAgent',
type: 'string'
type: 'string',
},
{
name: 'color',
group: 'internet',
value: 'internet.color',
type: 'string'
type: 'string',
},
{
name: 'mac',
group: 'internet',
value: 'internet.mac',
type: 'string'
type: 'string',
},
{
name: 'password',
group: 'internet',
value: 'internet.password',
type: 'string'
type: 'string',
},
{
name: 'word',
group: 'lorem',
value: 'lorem.word',
type: 'string'
type: 'string',
},
{
name: 'words',
group: 'lorem',
value: 'lorem.words',
type: 'string'
type: 'string',
},
{
name: 'sentence',
group: 'lorem',
value: 'lorem.sentence',
type: 'string'
type: 'string',
},
{
name: 'slug',
group: 'lorem',
value: 'lorem.slug',
type: 'string'
type: 'string',
},
{
name: 'sentences',
group: 'lorem',
value: 'lorem.sentences',
type: 'string'
type: 'string',
},
{
name: 'paragraph',
group: 'lorem',
value: 'lorem.paragraph',
type: 'string'
type: 'string',
},
{
name: 'paragraphs',
group: 'lorem',
value: 'lorem.paragraphs',
type: 'string'
type: 'string',
},
{
name: 'text',
group: 'lorem',
value: 'lorem.text',
type: 'string'
type: 'string',
},
{
name: 'lines',
group: 'lorem',
value: 'lorem.lines',
type: 'string'
type: 'string',
},
{
name: 'firstName',
group: 'name',
value: 'name.firstName',
type: 'string'
type: 'string',
},
{
name: 'lastName',
group: 'name',
value: 'name.lastName',
type: 'string'
type: 'string',
},
{
name: 'findName',
group: 'name',
value: 'name.findName',
type: 'string'
type: 'string',
},
{
name: 'jobTitle',
group: 'name',
value: 'name.jobTitle',
type: 'string'
type: 'string',
},
{
name: 'prefix',
group: 'name',
value: 'name.prefix',
type: 'string'
type: 'string',
},
{
name: 'suffix',
group: 'name',
value: 'name.suffix',
type: 'string'
type: 'string',
},
{
name: 'title',
group: 'name',
value: 'name.title',
type: 'string'
type: 'string',
},
{
name: 'jobDescriptor',
group: 'name',
value: 'name.jobDescriptor',
type: 'string'
type: 'string',
},
{
name: 'jobArea',
group: 'name',
value: 'name.jobArea',
type: 'string'
type: 'string',
},
{
name: 'jobType',
group: 'name',
value: 'name.jobType',
type: 'string'
type: 'string',
},
{
name: 'phoneNumber',
group: 'phone',
value: 'phone.phoneNumber',
type: 'string'
type: 'string',
},
{
name: 'phoneNumberFormat',
group: 'phone',
value: 'phone.phoneNumberFormat',
type: 'string'
type: 'string',
},
{
name: 'phoneFormats',
group: 'phone',
value: 'phone.phoneFormats',
type: 'string'
type: 'string',
},
{
name: 'number',
group: 'random',
value: 'random.number',
type: 'number'
type: 'number',
},
{
name: 'float',
group: 'random',
value: 'random.float',
type: 'number'
type: 'number',
},
// Todo : use it for collection or enum
// {
@ -790,109 +790,109 @@ export default [
name: 'uuid',
group: 'random',
value: 'random.uuid',
type: 'string'
type: 'string',
},
{
name: 'boolean',
group: 'random',
value: 'random.boolean',
type: 'boolean'
type: 'boolean',
},
{
name: 'word',
group: 'random',
value: 'random.word',
type: 'string'
type: 'string',
},
{
name: 'words',
group: 'random',
value: 'random.words',
type: 'string'
type: 'string',
},
{
name: 'image',
group: 'random',
value: 'random.image',
type: 'string'
type: 'string',
},
{
name: 'locale',
group: 'random',
value: 'random.locale',
type: 'string'
type: 'string',
},
{
name: 'alphaNumeric',
group: 'random',
value: 'random.alphaNumeric',
type: 'string'
type: 'string',
},
{
name: 'hexaDecimal',
group: 'random',
value: 'random.hexaDecimal',
type: 'string'
type: 'string',
},
{
name: 'fileName',
group: 'system',
value: 'system.fileName',
type: 'string'
type: 'string',
},
{
name: 'commonFileName',
group: 'system',
value: 'system.commonFileName',
type: 'string'
type: 'string',
},
{
name: 'mimeType',
group: 'system',
value: 'system.mimeType',
type: 'string'
type: 'string',
},
{
name: 'commonFileType',
group: 'system',
value: 'system.commonFileType',
type: 'string'
type: 'string',
},
{
name: 'commonFileExt',
group: 'system',
value: 'system.commonFileExt',
type: 'string'
type: 'string',
},
{
name: 'fileType',
group: 'system',
value: 'system.fileType',
type: 'string'
type: 'string',
},
{
name: 'fileExt',
group: 'system',
value: 'system.fileExt',
type: 'string'
type: 'string',
},
{
name: 'directoryPath',
group: 'system',
value: 'system.directoryPath',
type: 'string'
type: 'string',
},
{
name: 'filePath',
group: 'system',
value: 'system.filePath',
type: 'string'
type: 'string',
},
{
name: 'semver',
group: 'system',
value: 'system.semver',
type: 'string'
}
type: 'string',
},
];
// export default functionList;

2
packages/nocodb/src/lib/db/sql-client/lib/mysql/findDataTypeMapping.ts

@ -1,4 +1,4 @@
export const mapDataType = function(type) {
export const mapDataType = function (type) {
switch (type) {
case 'int':
case 'tinyint':

110
packages/nocodb/src/lib/db/sql-client/lib/mysql/mysql.queries.ts

@ -51,11 +51,11 @@ export default {
columnList: {
'55': {
sql: columnListOld,
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn']
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn'],
},
'56': {
sql: columnListOld,
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn']
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn'],
},
default: {
sql: `SELECT
@ -108,8 +108,8 @@ export default {
ORDER BY
c.table_name,
c.ordinal_position`,
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn']
}
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn'],
},
},
constraintList: {
default: {
@ -125,84 +125,84 @@ USING(constraint_name,table_schema,table_name)
WHERE
t.table_schema=?
AND t.table_name=?;`,
paramsHints: ['database', 'tn']
}
paramsHints: ['database', 'tn'],
},
},
createDatabaseIfNotExists: {
default: {
sql: `create database if not exists ??`,
paramsHints: ['database']
}
paramsHints: ['database'],
},
},
createTableIfNotExists: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
dropDatabase: {
default: {
sql: `drop database ??`,
paramsHints: ['database']
}
paramsHints: ['database'],
},
},
databaseList: {
default: {
sql: `SHOW databases`,
paramsHints: []
}
paramsHints: [],
},
},
hasDatabase: {
default: {
sql: `SHOW DATABASES LIKE ?`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
indexList: {
default: {
sql: `show index from ??`,
paramsHints: ['tn']
}
paramsHints: ['tn'],
},
},
functionList: {
default: {
sql: `show function status where db=?`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
functionRead: {
default: {
sql: `SHOW CREATE FUNCTION ??`,
paramsHints: ['function_name']
}
paramsHints: ['function_name'],
},
},
functionDelete: {
default: {
sql: `DROP FUNCTION IF EXISTS ??`,
paramsHints: ['function_name']
}
paramsHints: ['function_name'],
},
},
procedureList: {
default: {
sql: `show procedure status where db=?`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
procedureRead: {
default: {
sql: `show create procedure ??`,
paramsHints: ['procedure_name']
}
paramsHints: ['procedure_name'],
},
},
procedureDelete: {
default: {
sql: `DROP PROCEDURE IF EXISTS ??`,
paramsHints: ['procedure_name']
}
paramsHints: ['procedure_name'],
},
},
relationList: {
@ -235,8 +235,8 @@ AND t.table_name=?;`,
kcu.table_schema = ?
AND kcu.referenced_column_name IS NOT NULL
AND kcu.table_name=?`,
paramsHints: ['database', 'tn']
}
paramsHints: ['database', 'tn'],
},
},
relationListAll: {
@ -295,70 +295,70 @@ AND t.table_name=?;`,
AND kcu.REFERENCED_COLUMN_NAME IS NOT NULL
GROUP BY cstn , tn , rcn , cn , puc , rtn ,cn, mo , ur , dr , ts`,
paramsHints: ['database']
}
paramsHints: ['database'],
},
},
schemaCreate: {
default: {
sql: `create database ??`,
paramsHints: ['database_name']
}
paramsHints: ['database_name'],
},
},
schemaDelete: {
default: {
sql: `drop database ??`,
paramsHints: ['database_name']
}
paramsHints: ['database_name'],
},
},
triggerList: {
default: {
sql: `SHOW TRIGGERS like ?`,
paramsHints: ['tn']
}
paramsHints: ['tn'],
},
},
tableList: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
testConnection: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
triggerRead: {
default: {
sql: `SHOW FULL TABLES IN ?? WHERE TABLE_TYPE LIKE 'VIEW';`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
triggerDelete: {
default: {
sql: `DROP TRIGGER ??`,
paramsHints: ['trigger_name']
}
paramsHints: ['trigger_name'],
},
},
version: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
viewRead: {
default: {
sql: `select * FROM INFORMATION_SCHEMA.VIEWS WHERE
TABLE_SCHEMA = ? AND TABLE_NAME = ?`,
paramsHints: ['databaseName', 'view_name']
}
paramsHints: ['databaseName', 'view_name'],
},
},
//
viewList: {
default: {
sql: `SHOW FULL TABLES WHERE TABLE_TYPE LIKE 'VIEW'`,
paramsHints: []
}
}
paramsHints: [],
},
},
};

25
packages/nocodb/src/lib/db/sql-client/lib/oracle/OracleClient.ts

@ -85,7 +85,7 @@ class OracleClient extends KnexClient {
'varchar',
'varchar2',
'varray',
'varying array'
'varying array',
];
return result;
@ -213,7 +213,8 @@ class OracleClient extends KnexClient {
await this.sqlClient.destroy();
log.debug('dropping database:', this.connectionConfig.connection.user);
// await tempSqlClient.raw(`ALTER SYSTEM enable restricted session`);
const sessions = await tempSqlClient.raw(`select SID,SERIAL# from v$session where username = '${this.connectionConfig.connection.user}'
const sessions =
await tempSqlClient.raw(`select SID,SERIAL# from v$session where username = '${this.connectionConfig.connection.user}'
`);
log.debug(
`Active Sessions for ${this.connectionConfig.connection.user}: `,
@ -255,7 +256,7 @@ class OracleClient extends KnexClient {
const exists = await this.hasTable({ tn: args.tn });
if (!exists.data.value) {
await this.sqlClient.schema.createTable(args.tn, function(table) {
await this.sqlClient.schema.createTable(args.tn, function (table) {
// table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
@ -1386,7 +1387,7 @@ class OracleClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: query,
downStatement: `DROP TRIGGER ${args.trigger_name}`
downStatement: `DROP TRIGGER ${args.trigger_name}`,
};
} catch (e) {
log.ppe(e, func);
@ -1419,7 +1420,7 @@ class OracleClient extends KnexClient {
result.data.object = {
upStatement: `DROP TRIGGER ${args.trigger_name};\nCREATE TRIGGER \`${args.trigger_name}\` \n${args.timing} ${args.event}\nON ${args.tn} FOR EACH ROW\n${args.statement}`,
downStatement: `CREATE TRIGGER \`${args.trigger_name}\` \n${args.timing} ${args.event}\nON ${args.tn} FOR EACH ROW\n${args.oldStatement}`
downStatement: `CREATE TRIGGER \`${args.trigger_name}\` \n${args.timing} ${args.event}\nON ${args.tn} FOR EACH ROW\n${args.oldStatement}`,
};
} catch (e) {
log.ppe(e, func);
@ -1447,7 +1448,7 @@ class OracleClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: query,
downStatement: `DROP VIEW ${args.view_name}`
downStatement: `DROP VIEW ${args.view_name}`,
};
} catch (e) {
log.ppe(e, func);
@ -1476,7 +1477,7 @@ class OracleClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: query,
downStatement: `CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`
downStatement: `CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`,
};
} catch (e) {
log.ppe(e, func);
@ -1507,7 +1508,7 @@ class OracleClient extends KnexClient {
result.data.object = {
upStatement: query,
downStatement: `CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`
downStatement: `CREATE VIEW ${args.view_name} AS \n${args.oldViewDefination}`,
};
} catch (e) {
log.ppe(e, func);
@ -1569,7 +1570,7 @@ class OracleClient extends KnexClient {
/**************** return files *************** */
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement
downStatement,
};
} catch (e) {
log.ppe(e, _func);
@ -1622,7 +1623,7 @@ class OracleClient extends KnexClient {
for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 4) {
@ -1684,7 +1685,7 @@ class OracleClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -1720,7 +1721,7 @@ class OracleClient extends KnexClient {
/** ************** return files *************** */
result.data.object = {
upStatement,
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, _func);

2
packages/nocodb/src/lib/db/sql-client/lib/oracle/oracle.queries.ts

@ -19,7 +19,7 @@ const oracleQueries = {
'long varraw': {},
char: {},
charz: {},
rowiddescriptor: {}
rowiddescriptor: {},
};
export default oracleQueries;

139
packages/nocodb/src/lib/db/sql-client/lib/pg/PgClient.ts

@ -59,11 +59,11 @@ class PGClient extends KnexClient {
await this.sqlClient.raw(`create user ? with encrypted password ?`, [
args.user,
args.password
args.password,
]);
await this.sqlClient.raw(`grant all privileges on database ?? to ?`, [
args.schema,
args.user
args.user,
]);
log.debug('Create database if not exists', data);
@ -101,9 +101,11 @@ class PGClient extends KnexClient {
upStatement: [{ sql: query }],
downStatement: [
{
sql: `${this.querySeparator()}CREATE SEQUENCE ${args.sequence_name}`
}
]
sql: `${this.querySeparator()}CREATE SEQUENCE ${
args.sequence_name
}`,
},
],
};
} catch (e) {
log.ppe(e, _func);
@ -139,10 +141,10 @@ class PGClient extends KnexClient {
const { rows } = await this.raw(`select *
from INFORMATION_SCHEMA.sequences;`);
result.data.list = rows.map(seq => {
result.data.list = rows.map((seq) => {
return {
...seq,
original_sequence_name: seq.sequence_name
original_sequence_name: seq.sequence_name,
};
});
} catch (e) {
@ -176,8 +178,10 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: query }],
downStatement: [
{ sql: this.querySeparator() + `DROP SEQUENCE ${args.sequence_name}` }
]
{
sql: this.querySeparator() + `DROP SEQUENCE ${args.sequence_name}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -213,7 +217,7 @@ class PGClient extends KnexClient {
await this.sqlClient.raw(upQuery);
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, func);
@ -380,7 +384,7 @@ class PGClient extends KnexClient {
'unknown',
'void',
'xid',
'xml'
'xml',
];
return result;
@ -474,7 +478,7 @@ class PGClient extends KnexClient {
(this.connectionConfig.searchPath &&
this.connectionConfig.searchPath[0]) ||
'public',
this.connectionConfig.connection.user
this.connectionConfig.connection.user,
]
);
// }
@ -541,19 +545,20 @@ class PGClient extends KnexClient {
);
if (exists.rows.length === 0) {
const data = await this.sqlClient.schema.createTable(args.tn, function(
table
) {
table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
table.string('description').nullable();
table.integer('batch').nullable();
table.string('checksum').nullable();
table.integer('status').nullable();
table.dateTime('created');
table.timestamps();
});
const data = await this.sqlClient.schema.createTable(
args.tn,
function (table) {
table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
table.string('description').nullable();
table.integer('batch').nullable();
table.string('checksum').nullable();
table.integer('status').nullable();
table.dateTime('created');
table.timestamps();
}
);
log.debug('Table created:', `${args.tn}`, data);
} else {
log.debug(`${args.tn} tables exists`);
@ -596,9 +601,7 @@ class PGClient extends KnexClient {
log.api(`${_func}:args:`, args);
try {
const {
rows
} = await this.sqlClient.raw(
const { rows } = await this.sqlClient.raw(
`SELECT table_schema,table_name as tn, table_catalog FROM information_schema.tables where table_schema=? and table_name = '${args.tn}' and table_catalog = '${this.connectionConfig.connection.database}'`,
[this.schema]
);
@ -1077,7 +1080,7 @@ class PGClient extends KnexClient {
c: 'CASCADE',
r: 'RESTRICT',
n: 'SET NULL',
d: 'SET DEFAULT'
d: 'SET DEFAULT',
};
for (const row of rows) {
@ -1148,7 +1151,7 @@ class PGClient extends KnexClient {
c: 'CASCADE',
r: 'RESTRICT',
n: 'SET NULL',
d: 'SET DEFAULT'
d: 'SET DEFAULT',
};
for (const row of rows) {
@ -1191,9 +1194,7 @@ class PGClient extends KnexClient {
try {
args.databaseName = this.connectionConfig.connection.database;
const {
rows
} = await this.sqlClient.raw(
const { rows } = await this.sqlClient.raw(
`select * from information_schema.triggers where trigger_schema=? and event_object_table='${args.tn}'`,
[this.schema]
);
@ -1252,7 +1253,7 @@ class PGClient extends KnexClient {
if (!('prokind' in rows[i]) || rows[i].prokind !== 'p')
functionRows.push({
create_function: rows[i].prosrc,
function_name: rows[i].proname
function_name: rows[i].proname,
});
}
@ -1307,7 +1308,7 @@ class PGClient extends KnexClient {
if ('prokind' in rows[i] && rows[i].prokind === 'p')
procedureRows.push({
create_procedure: rows[i].prosrc,
procedure_name: rows[i].proname
procedure_name: rows[i].proname,
});
}
@ -1553,7 +1554,7 @@ class PGClient extends KnexClient {
try {
const upQuery = this.genQuery(`DROP TRIGGER IF EXISTS ?? ON ??`, [
args.trigger_name,
args.tn
args.tn,
]);
await this.sqlClient.raw(upQuery);
result.data.object = {
@ -1565,9 +1566,9 @@ class PGClient extends KnexClient {
this.genQuery(
`CREATE TRIGGER ?? \n${args.timing} ${args.event}\nON ?? FOR EACH ROW\n${args.statement}`,
[args.trigger_name, args.tn]
)
}
]
),
},
],
};
} catch (e) {
log.ppe(e, _func);
@ -1599,7 +1600,7 @@ class PGClient extends KnexClient {
await this.sqlClient.raw(upQuery);
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -1679,7 +1680,7 @@ class PGClient extends KnexClient {
await this.sqlClient.raw(upQuery);
const functionCreated = await this.functionRead({
function_name: args.function_name
function_name: args.function_name,
});
const downQuery =
@ -1688,7 +1689,7 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, func);
@ -1722,7 +1723,7 @@ class PGClient extends KnexClient {
await this.sqlClient.raw(upQuery);
const functionCreated = await this.functionRead({
function_name: args.function_name
function_name: args.function_name,
});
downQuery =
@ -1731,7 +1732,7 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, func);
@ -1767,7 +1768,7 @@ class PGClient extends KnexClient {
`DROP PROCEDURE IF EXISTS ${args.procedure_name}`;
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: downQuery }]
downStatement: [{ sql: downQuery }],
};
} catch (e) {
log.ppe(e, func);
@ -1804,7 +1805,7 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: ';' }]
downStatement: [{ sql: ';' }],
};
} catch (e) {
log.ppe(e, func);
@ -1836,8 +1837,8 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [
{ sql: this.querySeparator() + `DROP TRIGGER ${args.trigger_name}` }
]
{ sql: this.querySeparator() + `DROP TRIGGER ${args.trigger_name}` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1880,7 +1881,7 @@ class PGClient extends KnexClient {
} ${args.event}\nON "${args.tn}" FOR EACH ROW\n${args.statement}`,
downStatement:
this.querySeparator() +
`CREATE TRIGGER ${args.trigger_name} \n${args.timing} ${args.event}\nON "${args.tn}" FOR EACH ROW\n${args.oldStatement}`
`CREATE TRIGGER ${args.trigger_name} \n${args.timing} ${args.event}\nON "${args.tn}" FOR EACH ROW\n${args.oldStatement}`,
};
} catch (e) {
log.ppe(e, func);
@ -1909,8 +1910,8 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [
{ sql: this.querySeparator() + `DROP VIEW "${args.view_name}"` }
]
{ sql: this.querySeparator() + `DROP VIEW "${args.view_name}"` },
],
};
} catch (e) {
log.ppe(e, func);
@ -1941,7 +1942,7 @@ class PGClient extends KnexClient {
upStatement: this.querySeparator() + query,
downStatement:
this.querySeparator() +
`CREATE VIEW "${args.view_name}" AS \n${args.oldViewDefination}`
`CREATE VIEW "${args.view_name}" AS \n${args.oldViewDefination}`,
};
} catch (e) {
log.ppe(e, func);
@ -1976,9 +1977,9 @@ class PGClient extends KnexClient {
{
sql:
this.querySeparator() +
`CREATE VIEW "${args.view_name}" AS \n${args.oldViewDefination}`
}
]
`CREATE VIEW "${args.view_name}" AS \n${args.oldViewDefination}`,
},
],
};
} catch (e) {
log.ppe(e, func);
@ -2046,8 +2047,8 @@ class PGClient extends KnexClient {
upStatement: [{ sql: upQuery }, ...triggerStatements.upStatement],
downStatement: [
...triggerStatements.downStatement,
{ sql: downStatement }
]
{ sql: downStatement },
],
};
} catch (e) {
log.ppe(e, _func);
@ -2095,7 +2096,7 @@ class PGClient extends KnexClient {
this.querySeparator() +
this.genQuery(`DROP TRIGGER IF EXISTS ?? ON ??;`, [
triggerName,
args.tn
args.tn,
]) +
this.querySeparator() +
this.genQuery(`DROP FUNCTION IF EXISTS ??()`, [triggerFnName]);
@ -2146,7 +2147,7 @@ class PGClient extends KnexClient {
this.querySeparator() +
this.genQuery(`DROP TRIGGER IF EXISTS ?? ON ??;`, [
triggerName,
args.tn
args.tn,
]) +
this.querySeparator() +
this.genQuery(`DROP FUNCTION IF EXISTS ??()`, [triggerFnName]);
@ -2202,7 +2203,7 @@ class PGClient extends KnexClient {
for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 4) {
@ -2281,12 +2282,12 @@ class PGClient extends KnexClient {
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + upQuery },
...afterUpdate.upStatement
...afterUpdate.upStatement,
],
downStatement: [
...afterUpdate.downStatement,
{ sql: this.querySeparator() + downQuery }
]
{ sql: this.querySeparator() + downQuery },
],
};
} catch (e) {
log.ppe(e, _func);
@ -2339,7 +2340,7 @@ class PGClient extends KnexClient {
downQuery +=
this.querySeparator() +
(await this.sqlClient.schema
.table(relation.tn, function(table) {
.table(relation.tn, function (table) {
table = table
.foreign(relation.cn, null)
.references(relation.rcn)
@ -2369,7 +2370,7 @@ class PGClient extends KnexClient {
tn: args.tn,
indexName: key_name,
non_unique,
columns: []
columns: [],
};
}
indexesMap[key_name].columns.push(cn);
@ -2381,7 +2382,7 @@ class PGClient extends KnexClient {
downQuery +=
this.querySeparator() +
this.sqlClient.schema
.table(tn, function(table) {
.table(tn, function (table) {
if (non_unique) {
table.index(columns, indexName);
} else {
@ -2399,7 +2400,7 @@ class PGClient extends KnexClient {
/** ************** return files *************** */
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement: [{ sql: this.querySeparator() + downQuery }]
downStatement: [{ sql: this.querySeparator() + downQuery }],
};
} catch (e) {
log.ppe(e, _func);
@ -2424,7 +2425,7 @@ class PGClient extends KnexClient {
result = await this.columnList(args);
const upQuery = this.createTable(args.tn, {
tn: args.tn,
columns: result.data.list
columns: result.data.list,
});
result.data = upQuery;
} catch (e) {
@ -2618,7 +2619,7 @@ class PGClient extends KnexClient {
query += numOfPksInOriginal.length
? this.genQuery(`alter TABLE ?? drop constraint IF EXISTS ??;`, [
t,
`${t}_pkey`
`${t}_pkey`,
])
: '';
if (numOfPksInNew.length) {

102
packages/nocodb/src/lib/db/sql-client/lib/pg/pg.queries.ts

@ -51,8 +51,8 @@ const pgQueries = {
ORDER BY
c.table_name,
c.ordinal_position`,
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn']
}
paramsHints: ['databaseName', 'tn', 'databaseName', 'tn'],
},
},
constraintList: {
default: {
@ -68,84 +68,84 @@ USING(constraint_name,table_schema,table_name)
WHERE
t.table_schema=?
AND t.table_name=?;`,
paramsHints: ['database', 'tn']
}
paramsHints: ['database', 'tn'],
},
},
createDatabaseIfNotExists: {
default: {
sql: `create database if not exists ??`,
paramsHints: ['database']
}
paramsHints: ['database'],
},
},
createTableIfNotExists: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
dropDatabase: {
default: {
sql: `drop database ??`,
paramsHints: ['database']
}
paramsHints: ['database'],
},
},
databaseList: {
default: {
sql: `SHOW databases`,
paramsHints: []
}
paramsHints: [],
},
},
hasDatabase: {
default: {
sql: `SHOW DATABASES LIKE ??`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
indexList: {
default: {
sql: `show index from ??`,
paramsHints: ['tn']
}
paramsHints: ['tn'],
},
},
functionList: {
default: {
sql: `show function status where db=?`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
functionRead: {
default: {
sql: `SHOW CREATE FUNCTION ??`,
paramsHints: ['function_name']
}
paramsHints: ['function_name'],
},
},
functionDelete: {
default: {
sql: `DROP FUNCTION IF EXISTS ??`,
paramsHints: ['function_name']
}
paramsHints: ['function_name'],
},
},
procedureList: {
default: {
sql: `show procedure status where db=?`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
procedureRead: {
default: {
sql: `show create procedure ??`,
paramsHints: ['procedure_name']
}
paramsHints: ['procedure_name'],
},
},
procedureDelete: {
default: {
sql: `DROP PROCEDURE IF EXISTS ??`,
paramsHints: ['procedure_name']
}
paramsHints: ['procedure_name'],
},
},
relationList: {
@ -168,72 +168,72 @@ AND t.table_name=?;`,
kcu.table_schema = ?
AND kcu.referenced_column_name IS NOT NULL
AND kcu.table_name=?`,
paramsHints: ['database', 'tn']
}
paramsHints: ['database', 'tn'],
},
},
schemaCreate: {
default: {
sql: `create database ??`,
paramsHints: ['database_name']
}
paramsHints: ['database_name'],
},
},
schemaDelete: {
default: {
sql: `drop database ??`,
paramsHints: ['database_name']
}
paramsHints: ['database_name'],
},
},
triggerList: {
default: {
sql: `SHOW TRIGGERS like ?`,
paramsHints: ['tn']
}
paramsHints: ['tn'],
},
},
tableList: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
testConnection: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
triggerRead: {
default: {
sql: `SHOW FULL TABLES IN ?? WHERE TABLE_TYPE LIKE 'VIEW';`,
paramsHints: ['databaseName']
}
paramsHints: ['databaseName'],
},
},
triggerDelete: {
default: {
sql: `DROP TRIGGER ??`,
paramsHints: ['trigger_name']
}
paramsHints: ['trigger_name'],
},
},
version: {
default: {
sql: ``,
paramsHints: []
}
paramsHints: [],
},
},
viewRead: {
default: {
sql: `select * FROM INFORMATION_SCHEMA.VIEWS WHERE
TABLE_SCHEMA = ? AND TABLE_NAME = ?`,
paramsHints: ['databaseName', 'view_name']
}
paramsHints: ['databaseName', 'view_name'],
},
},
//
viewList: {
default: {
sql: `SHOW FULL TABLES IN ?? WHERE TABLE_TYPE LIKE 'VIEW'`,
paramsHints: ['databaseName']
}
}
paramsHints: ['databaseName'],
},
},
};
export default pgQueries;

71
packages/nocodb/src/lib/db/sql-client/lib/sqlite/SqliteClient.ts

@ -45,7 +45,7 @@ class SqliteClient extends KnexClient {
'datetime',
'text',
'varchar',
'timestamp'
'timestamp',
];
return result;
@ -176,19 +176,20 @@ class SqliteClient extends KnexClient {
const exists = await this.hasTable({ tn: args.tn });
if (!exists.data.value) {
const data = await this.sqlClient.schema.createTable(args.tn, function(
table
) {
table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
table.string('description').nullable();
table.integer('batch').nullable();
table.string('checksum').nullable();
table.integer('status').nullable();
table.dateTime('created');
table.timestamps();
});
const data = await this.sqlClient.schema.createTable(
args.tn,
function (table) {
table.increments();
table.string('title').notNullable();
table.string('titleDown').nullable();
table.string('description').nullable();
table.integer('batch').nullable();
table.string('checksum').nullable();
table.integer('status').nullable();
table.dateTime('created');
table.timestamps();
}
);
log.debug('Table created:', `${args.tn}`, data);
} else {
log.debug(`${args.tn} tables exists`);
@ -671,7 +672,7 @@ class SqliteClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let fn = response[0][i];
fn = _.mapKeys(fn, function(_v, k) {
fn = _.mapKeys(fn, function (_v, k) {
return k.toLowerCase();
});
fn.function_name = fn.name;
@ -725,7 +726,7 @@ class SqliteClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let procedure = response[0][i];
procedure = _.mapKeys(procedure, function(_v, k) {
procedure = _.mapKeys(procedure, function (_v, k) {
return k.toLowerCase();
});
procedure.procedure_name = procedure.name;
@ -809,7 +810,7 @@ class SqliteClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let _function = response[0][i];
_function = _.mapKeys(_function, function(_v, k) {
_function = _.mapKeys(_function, function (_v, k) {
return k.toLowerCase();
});
@ -861,7 +862,7 @@ class SqliteClient extends KnexClient {
for (let i = 0; i < response[0].length; ++i) {
let procedure = response[0][i];
procedure = _.mapKeys(procedure, function(_v, k) {
procedure = _.mapKeys(procedure, function (_v, k) {
return k.toLowerCase();
});
@ -983,7 +984,7 @@ class SqliteClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: [{ sql: query }],
downStatement: [{ sql: `;` }]
downStatement: [{ sql: `;` }],
};
} catch (e) {
log.ppe(e, _func);
@ -1175,7 +1176,7 @@ class SqliteClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: [{ sql: query }],
downStatement: [{ sql: ';' }]
downStatement: [{ sql: ';' }],
};
} catch (e) {
log.ppe(e, func);
@ -1210,7 +1211,7 @@ class SqliteClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: upQuery }],
downStatement: [{ sql: ';' }]
downStatement: [{ sql: ';' }],
};
} catch (e) {
log.ppe(e, func);
@ -1238,7 +1239,7 @@ class SqliteClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [{ sql: `;` }]
downStatement: [{ sql: `;` }],
//downStatement: [{sql:`DROP VIEW ${args.view_name}`}]
};
} catch (e) {
@ -1268,7 +1269,7 @@ class SqliteClient extends KnexClient {
await this.sqlClient.raw(query);
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [{ sql: ';' }]
downStatement: [{ sql: ';' }],
// downStatement: [{`CREATE VIEW ${args.view_name} AS \n${
// args.oldViewDefination
// }`}]
@ -1302,7 +1303,7 @@ class SqliteClient extends KnexClient {
result.data.object = {
upStatement: [{ sql: this.querySeparator() + query }],
downStatement: [{ sql: ';' }]
downStatement: [{ sql: ';' }],
// downStatement: `CREATE VIEW ${args.view_name} AS \n${
// args.oldViewDefination
// }`
@ -1370,7 +1371,7 @@ class SqliteClient extends KnexClient {
/**************** return files *************** */
result.data.object = {
upStatement: [{ sql: upQuery }, ...triggerStatements.upStatement],
downStatement: downStatement
downStatement: downStatement,
};
} catch (e) {
log.ppe(e, _func);
@ -1385,7 +1386,7 @@ class SqliteClient extends KnexClient {
let upQuery = '';
const downQuery = '';
const pk = args.columns.find(c => c.pk);
const pk = args.columns.find((c) => c.pk);
if (!pk) return result;
for (let i = 0; i < args.columns.length; i++) {
@ -1416,7 +1417,7 @@ class SqliteClient extends KnexClient {
let upQuery = '';
const downQuery = '';
const pk = args.columns.find(c => c.pk);
const pk = args.columns.find((c) => c.pk);
if (!pk) return result;
for (let i = 0; i < args.columns.length; i++) {
@ -1485,7 +1486,7 @@ class SqliteClient extends KnexClient {
for (let i = 0; i < args.columns.length; ++i) {
const oldColumn = lodash.find(originalColumns, {
cn: args.columns[i].cno
cn: args.columns[i].cno,
});
if (args.columns[i].altered & 4) {
@ -1551,7 +1552,7 @@ class SqliteClient extends KnexClient {
}
await Promise.all(
upQuery.split(';').map(async query => {
upQuery.split(';').map(async (query) => {
if (query.trim().length) await this.sqlClient.raw(query);
})
);
@ -1565,9 +1566,9 @@ class SqliteClient extends KnexClient {
result.data.object = {
upStatement: [
{ sql: this.querySeparator() + upQuery },
...afterUpdate.upStatement
...afterUpdate.upStatement,
],
downStatement: [{ sql: ';' }]
downStatement: [{ sql: ';' }],
};
} catch (e) {
log.ppe(e, _func);
@ -1604,7 +1605,7 @@ class SqliteClient extends KnexClient {
/** ************** return files *************** */
result.data.object = {
upStatement: [{ sql: upStatement }],
downStatement
downStatement,
};
} catch (e) {
log.ppe(e, _func);
@ -1629,7 +1630,7 @@ class SqliteClient extends KnexClient {
result = await this.columnList(args);
const upQuery = this.createTable(args.tn, {
tn: args.tn,
columns: result.data.list
columns: result.data.list,
});
result.data = upQuery;
} catch (e) {
@ -1819,7 +1820,7 @@ class SqliteClient extends KnexClient {
/* Filter relations for current table */
if (args.tn) {
relations = relations.filter(
r => r.tn === args.tn || r.rtn === args.tn
(r) => r.tn === args.tn || r.rtn === args.tn
);
}
@ -1916,7 +1917,7 @@ class SqliteClient extends KnexClient {
// query += ` DROP COLUMN ${n.cn}`;
// query = existingQuery ? query : `ALTER TABLE "${t}" ${query};`;
// return query;
await this.sqlClient.schema.alterTable(t, tb => {
await this.sqlClient.schema.alterTable(t, (tb) => {
tb.dropColumn(n.cn);
});

2
packages/nocodb/src/lib/db/sql-client/lib/sqlite/sqlite.queries.ts

@ -28,7 +28,7 @@ const sqliteQueries = {
decimal: {},
boolean: {},
date: {},
datetime: {}
datetime: {},
};
export default sqliteQueries;

129
packages/nocodb/src/lib/db/sql-data-mapper/lib/BaseModel.ts

@ -85,13 +85,13 @@ abstract class BaseModel {
columns,
hasMany = [],
belongsTo = [],
type = 'table'
type = 'table',
}) {
this.dbDriver = dbDriver;
this.tn = tn;
this.columns = columns;
this.pks = columns.filter(c => c.pk === true);
this.pks = columns.filter((c) => c.pk === true);
this.hasManyRelations = hasMany;
this.belongsToRelations = belongsTo;
this.type = type;
@ -107,7 +107,7 @@ abstract class BaseModel {
stepMin: 1,
stepsMax: 100,
record: true,
timeout: 25000
timeout: 25000,
};
this.clientType = this.dbDriver.clientType();
@ -128,7 +128,7 @@ abstract class BaseModel {
for (let i = 0; i < this.columns.length; ++i) {
const {
validate: { func, msg },
cn
cn,
} = this.columns[i];
for (let j = 0; j < func.length; ++j) {
const fn = typeof func[j] === 'string' ? Validator[func[j]] : func[j];
@ -192,7 +192,7 @@ abstract class BaseModel {
_extractPks(obj) {
const objCopy = JSON.parse(JSON.stringify(obj));
for (const key in obj) {
if (this.pks.filter(pk => pk.cn === key).length === 0) {
if (this.pks.filter((pk) => pk.cn === key).length === 0) {
delete objCopy[key];
}
}
@ -227,7 +227,7 @@ abstract class BaseModel {
} else {
response = data;
const res = await this._run(query);
const ai = this.columns.find(c => c.ai);
const ai = this.columns.find((c) => c.ai);
if (ai) {
response[ai.cn] = res[0];
}
@ -272,7 +272,7 @@ abstract class BaseModel {
} else {
response = data;
const res = await this._run(query);
const ai = this.columns.find(c => c.ai);
const ai = this.columns.find((c) => c.ai);
if (ai) {
response[ai.cn] = res[0];
}
@ -325,10 +325,7 @@ abstract class BaseModel {
async readByPk(id, { conditionGraph }) {
try {
return await this._run(
this.$db
.select()
.where(this._wherePk(id))
.first()
this.$db.select().where(this._wherePk(id)).first()
);
} catch (e) {
console.log(e);
@ -354,7 +351,7 @@ abstract class BaseModel {
.andWhere(
this._whereFk({
tnp,
parentId
parentId,
})
)
.limit(1)
@ -380,14 +377,8 @@ abstract class BaseModel {
*/
async list(args) {
try {
const {
fields,
where,
limit,
offset,
sort,
condition
} = this._getListArgs(args);
const { fields, where, limit, offset, sort, condition } =
this._getListArgs(args);
const query = this.$db
.select(...fields.split(','))
@ -506,7 +497,7 @@ abstract class BaseModel {
.where(
this._whereFk({
parentId,
tnp
tnp,
})
)
.count(`${(this.pks?.[0] || this.columns[0]).cn} as count`)
@ -568,15 +559,12 @@ abstract class BaseModel {
// this.validate(data);
response = await this._run(
this.$db
.update(data)
.where(this._wherePk(id))
.andWhere(
this._whereFk({
tnp,
parentId
})
)
this.$db.update(data).where(this._wherePk(id)).andWhere(
this._whereFk({
tnp,
parentId,
})
)
);
await this.afterUpdate(response, trx, cookie);
return response;
@ -627,15 +615,12 @@ abstract class BaseModel {
let response;
response = await this._run(
this.$db
.del()
.where(this._wherePk(id))
.andWhere(
this._whereFk({
tnp,
parentId
})
)
this.$db.del().where(this._wherePk(id)).andWhere(
this._whereFk({
tnp,
parentId,
})
)
);
await this.afterDelete(response, trx, cookie);
return response;
@ -663,9 +648,7 @@ abstract class BaseModel {
for (const d of data) {
// this.validate(d);
const response = await this._run(
trx(this.tn)
.update(d)
.where(this._extractPks(d))
trx(this.tn).update(d).where(this._extractPks(d))
);
res.push(response);
}
@ -697,9 +680,7 @@ abstract class BaseModel {
const res = [];
for (const d of ids) {
const response = await this._run(
trx(this.tn)
.del()
.where(this._extractPks(d))
trx(this.tn).del().where(this._extractPks(d))
);
res.push(response);
}
@ -767,7 +748,7 @@ abstract class BaseModel {
try {
const columns = [
...(column_name ? [column_name] : []),
...fields.split(',').filter(Boolean)
...fields.split(',').filter(Boolean),
];
const query = this.$db
.groupBy(columns)
@ -806,7 +787,7 @@ abstract class BaseModel {
column_name,
limit,
offset,
sort
sort,
}) {
try {
const query = this.$db.select(...fields.split(',')).xhaving(having);
@ -815,7 +796,7 @@ abstract class BaseModel {
query.groupBy(...fields.split(','));
}
if (func && column_name) {
func.split(',').forEach(fn => query[fn](`${column_name} as ${fn}`));
func.split(',').forEach((fn) => query[fn](`${column_name} as ${fn}`));
}
this._paginateAndSort(query, { limit, offset, sort });
@ -894,7 +875,7 @@ abstract class BaseModel {
if (func) {
func
.split(',')
.forEach(fn => query[fn](`${column_name} as ${fn}`));
.forEach((fn) => query[fn](`${column_name} as ${fn}`));
}
return this.isSqlite() ? this.dbDriver.select().from(query) : query;
}),
@ -931,7 +912,7 @@ abstract class BaseModel {
limit,
offset,
sort,
condition
condition,
}) {
try {
const query = this.$db;
@ -973,14 +954,8 @@ abstract class BaseModel {
* @private
*/
async _getChildListInParent({ parent, child }, rest = {}, index) {
let {
fields,
where,
limit,
offset,
sort,
condition
} = this._getChildListArgs(rest, index);
let { fields, where, limit, offset, sort, condition } =
this._getChildListArgs(rest, index);
const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
if (fields !== '*' && fields.split(',').indexOf(cn) === -1) {
@ -989,7 +964,7 @@ abstract class BaseModel {
const childs = await this._run(
this.dbDriver.union(
parent.map(p => {
parent.map((p) => {
const query = this.dbDriver(child)
.where({ [cn]: p[this.pks?.[0]?.cn] })
.xwhere(where)
@ -1004,7 +979,7 @@ abstract class BaseModel {
);
const gs = _.groupBy(childs, cn);
parent.forEach(row => {
parent.forEach((row) => {
row[child] = gs[row[this.pks?.[0]?.cn]] || [];
});
}
@ -1024,14 +999,8 @@ abstract class BaseModel {
*/
async hasManyChildren({ child, parentId, ...args }) {
try {
const {
fields,
where,
limit,
offset,
sort,
condition
} = this._getListArgs(args);
const { fields, where, limit, offset, sort, condition } =
this._getListArgs(args);
const { rcn } =
this.hasManyRelations.find(({ tn }) => tn === child) || {};
@ -1083,7 +1052,7 @@ abstract class BaseModel {
this._getChildListInParent(
{
parent,
child
child,
},
rest,
index
@ -1127,7 +1096,7 @@ abstract class BaseModel {
parents.split('~').map((parent, index) => {
const { cn, rcn } =
this.belongsToRelations.find(({ rtn }) => rtn === parent) || {};
const parentIds = [...new Set(childs.map(c => c[cn]))];
const parentIds = [...new Set(childs.map((c) => c[cn]))];
return this._belongsTo(
{ parent, rcn, parentIds, childs, cn, ...rest },
index
@ -1167,7 +1136,7 @@ abstract class BaseModel {
const gs = _.groupBy(parents, rcn);
childs.forEach(row => {
childs.forEach((row) => {
row[parent] = gs[row[cn]] && gs[row[cn]][0];
});
}
@ -1186,14 +1155,8 @@ abstract class BaseModel {
*/
async hasManyListGQL({ child, ids, ...rest }) {
try {
let {
fields,
where,
limit,
offset,
sort,
condition
} = this._getChildListArgs(rest);
let { fields, where, limit, offset, sort, condition } =
this._getChildListArgs(rest);
const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
@ -1203,7 +1166,7 @@ abstract class BaseModel {
const childs = await this._run(
this.dbDriver.union(
ids.map(p => {
ids.map((p) => {
const query = this.dbDriver(child)
.where({ [cn]: p })
.xwhere(where)
@ -1248,7 +1211,7 @@ abstract class BaseModel {
const childs = await this._run(
this.dbDriver.unionAll(
ids.map(p => {
ids.map((p) => {
const query = this.dbDriver(child)
.where({ [cn]: p })
.xwhere(where)
@ -1285,13 +1248,13 @@ abstract class BaseModel {
{
limit = 20,
offset = 0,
sort = ''
sort = '',
}: { limit?: number | string; offset?: number | string; sort?: string }
) {
query.offset(offset).limit(limit);
if (sort) {
sort.split(',').forEach(o => {
sort.split(',').forEach((o) => {
if (o[0] === '-') {
query.orderBy(o.slice(1), 'desc');
} else {

220
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/BaseModelSql.ts

@ -49,7 +49,7 @@ class BaseModelSql extends BaseModel {
manyToMany = [],
v,
type,
dbModels
dbModels,
}: {
[key: string]: any;
dbModels?: {
@ -62,14 +62,14 @@ class BaseModelSql extends BaseModel {
columns,
hasMany,
belongsTo,
type
type,
});
this.dbDriver = dbDriver;
this.columns = columns;
this.pks = columns.filter(c => c.pk === true);
this._primaryColRef = columns.find(c => c.pv);
this.pks = columns.filter((c) => c.pk === true);
this._primaryColRef = columns.find((c) => c.pv);
this.hasManyRelations = hasMany;
this.belongsToRelations = belongsTo;
this.manyToManyRelations = manyToMany;
@ -86,7 +86,7 @@ class BaseModelSql extends BaseModel {
stepMin: 1,
stepsMax: 100,
record: true,
timeout: 25000
timeout: 25000,
};
this.clientType = this.dbDriver.clientType();
@ -108,7 +108,7 @@ class BaseModelSql extends BaseModel {
for (let i = 0; i < this.columns.length; ++i) {
const {
validate: { func, msg },
cn
cn,
} = this.columns[i];
for (let j = 0; j < func.length; ++j) {
const fn = typeof func[j] === 'string' ? Validator[func[j]] : func[j];
@ -184,14 +184,12 @@ class BaseModelSql extends BaseModel {
* @returns {Object} Copy of the object excluding primary keys
* @private
*/
_extractPks(
obj
): {
_extractPks(obj): {
[key: string]: any;
} {
const objCopy = this.mapAliasToColumn(obj);
for (const key in objCopy) {
if (this.pks.filter(pk => pk._cn === key).length === 0) {
if (this.pks.filter((pk) => pk._cn === key).length === 0) {
delete objCopy[key];
}
}
@ -207,7 +205,9 @@ class BaseModelSql extends BaseModel {
_extractPksValues(obj): string {
const objCopy = this.mapAliasToColumn(obj);
for (const key in objCopy) {
if (this.pks.filter(pk => pk._cn === key || pk.cn === key).length === 0) {
if (
this.pks.filter((pk) => pk._cn === key || pk.cn === key).length === 0
) {
delete objCopy[key];
}
}
@ -290,7 +290,7 @@ class BaseModelSql extends BaseModel {
response = await this._run(query);
}
const ai = this.columns.find(c => c.ai);
const ai = this.columns.find((c) => c.ai);
if (
!response ||
(typeof response?.[0] !== 'object' && response?.[0] !== null)
@ -355,9 +355,7 @@ class BaseModelSql extends BaseModel {
// this.validate(data);
await this._run(
driver(this.tnPath)
.update(mappedData)
.where(this._wherePk(id))
driver(this.tnPath).update(mappedData).where(this._wherePk(id))
);
let response = await this.nestedRead(id, this.defaultNestedQueryParams);
@ -384,9 +382,7 @@ class BaseModelSql extends BaseModel {
const dbDriver = trx ? trx : this.dbDriver;
const response = await this._run(
dbDriver(this.tnPath)
.del()
.where(this._wherePk(id))
dbDriver(this.tnPath).del().where(this._wherePk(id))
);
await this.afterDelete({ id }, trx, cookie);
return response;
@ -447,7 +443,7 @@ class BaseModelSql extends BaseModel {
id = (await this._run(query))[0];
}
const ai = this.columns.find(c => c.ai);
const ai = this.columns.find((c) => c.ai);
if (ai) {
response = await this.readByPk(id);
} else {
@ -485,15 +481,12 @@ class BaseModelSql extends BaseModel {
const dbDriver = trx ? trx : this.dbDriver;
// this.validate(data);
const response = await this._run(
dbDriver(this.tnPath)
.update(data)
.where(this._wherePk(id))
.andWhere(
this._whereFk({
tnp,
parentId
})
)
dbDriver(this.tnPath).update(data).where(this._wherePk(id)).andWhere(
this._whereFk({
tnp,
parentId,
})
)
);
await this.afterUpdate(response, trx, cookie);
return response;
@ -553,15 +546,12 @@ class BaseModelSql extends BaseModel {
const dbDriver = trx ? trx : this.dbDriver;
const response = await this._run(
dbDriver(this.tnPath)
.del()
.where(this._wherePk(id))
.andWhere(
this._whereFk({
tnp,
parentId
})
)
dbDriver(this.tnPath).del().where(this._wherePk(id)).andWhere(
this._whereFk({
tnp,
parentId,
})
)
);
await this.afterDelete({ id, parentId, tnp }, trx, cookie);
return response;
@ -610,7 +600,7 @@ class BaseModelSql extends BaseModel {
*/
async insertb(data) {
try {
const insertDatas = data.map(d => this.mapAliasToColumn(d));
const insertDatas = data.map((d) => this.mapAliasToColumn(d));
await this.beforeInsertb(insertDatas, null);
@ -640,7 +630,7 @@ class BaseModelSql extends BaseModel {
async updateb(data) {
let transaction;
try {
const insertDatas = data.map(d => this.mapAliasToColumn(d));
const insertDatas = data.map((d) => this.mapAliasToColumn(d));
transaction = await this.dbDriver.transaction();
@ -650,9 +640,7 @@ class BaseModelSql extends BaseModel {
await this.validate(d);
// this.validate(d);
const response = await this._run(
transaction(this.tn)
.update(d)
.where(this._extractPks(d))
transaction(this.tn).update(d).where(this._extractPks(d))
);
res.push(response);
}
@ -684,11 +672,7 @@ class BaseModelSql extends BaseModel {
const res = [];
for (const d of ids) {
if (Object.keys(d).length) {
const response = await this._run(
transaction(this.tn)
.del()
.where(d)
);
const response = await this._run(transaction(this.tn).del().where(d));
res.push(response);
}
}
@ -750,7 +734,7 @@ class BaseModelSql extends BaseModel {
.andWhere(
this._whereFk({
tnp,
parentId
parentId,
})
)
.limit(1)
@ -784,7 +768,7 @@ class BaseModelSql extends BaseModel {
sort,
condition,
conditionGraph = null,
having
having,
} = this._getListArgs(args);
const query = this.$db
@ -831,9 +815,8 @@ class BaseModelSql extends BaseModel {
const { hm: childs = '', bt: parents = '', mm: many = '' } = args;
const { where, condition, conditionGraph, ...rest } = this._getListArgs(
args
);
const { where, condition, conditionGraph, ...rest } =
this._getListArgs(args);
let { fields } = rest;
if (fields === '*') {
fields = `${this.tn}.*`;
@ -884,12 +867,8 @@ class BaseModelSql extends BaseModel {
*/
async findOneByFk({ parentId, tnp, ...args }) {
try {
const {
where,
condition,
conditionGraph,
...restArgs
} = this._getListArgs(args);
const { where, condition, conditionGraph, ...restArgs } =
this._getListArgs(args);
let { fields } = restArgs;
if (fields === '*') {
fields = `${this.tn}.*`;
@ -923,7 +902,7 @@ class BaseModelSql extends BaseModel {
where = '',
conditionGraph = null,
having = '',
condition
condition,
}) {
try {
if (this.isPg() && !conditionGraph && !where && !having) {
@ -975,7 +954,7 @@ class BaseModelSql extends BaseModel {
.where(
this._whereFk({
parentId,
tnp
tnp,
})
)
.count(`${this.tn}.${(this.pks[0] || this.columns[0]).cn} as count`)
@ -1040,7 +1019,7 @@ class BaseModelSql extends BaseModel {
try {
const columns = [
...(column_name ? [column_name] : []),
...fields.split(',').filter(Boolean)
...fields.split(',').filter(Boolean),
];
const query = this.$db
.groupBy(columns)
@ -1080,7 +1059,7 @@ class BaseModelSql extends BaseModel {
column_name,
limit,
offset,
sort
sort,
}) {
try {
const query = this.$db
@ -1095,7 +1074,7 @@ class BaseModelSql extends BaseModel {
query.groupBy(column_name);
}
if (func && column_name) {
func.split(',').forEach(fn => query[fn](`${column_name} as ${fn}`));
func.split(',').forEach((fn) => query[fn](`${column_name} as ${fn}`));
}
this._paginateAndSort(query, { limit, offset, sort });
@ -1175,7 +1154,7 @@ class BaseModelSql extends BaseModel {
if (func) {
func
.split(',')
.forEach(fn => query[fn](`${column_name} as ${fn}`));
.forEach((fn) => query[fn](`${column_name} as ${fn}`));
}
return this.isSqlite() ? this.dbDriver.select().from(query) : query;
}),
@ -1211,7 +1190,7 @@ class BaseModelSql extends BaseModel {
limit,
offset,
sort,
conditionGraph = null
conditionGraph = null,
}) {
try {
const query = this._buildDistinctQuery(
@ -1277,9 +1256,9 @@ class BaseModelSql extends BaseModel {
* @returns {Array<string>} - an array of the formula columns.
*/
private filterFormulaColumns(columns: string[]) {
return columns.filter(column => {
return columns.filter((column) => {
return this.virtualColumns.find(
col => col._cn === column && col?.formula
(col) => col._cn === column && col?.formula
);
});
}
@ -1334,7 +1313,7 @@ class BaseModelSql extends BaseModel {
const childs = await this._run(
driver.union(
parent.map(p => {
parent.map((p) => {
const id =
p[_cn] ||
p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn] ||
@ -1352,7 +1331,7 @@ class BaseModelSql extends BaseModel {
);
const gs = _.groupBy(childs, _cn);
parent.forEach(row => {
parent.forEach((row) => {
row[`${this.dbModels?.[child]?._tn || child}List`] =
gs[row[_cn] || row[this.pks[0]._cn]] || [];
});
@ -1375,8 +1354,8 @@ class BaseModelSql extends BaseModel {
index,
child,
parentIds: parent.map(
p => p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn]
)
(p) => p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn]
),
},
trx
);
@ -1412,14 +1391,14 @@ class BaseModelSql extends BaseModel {
const childs = await this._run(
driver.union(
parentIds.map(id => {
parentIds.map((id) => {
const query = driver(this.dbModels[child].tnPath)
.join(vtn, `${vtn}.${vrcn}`, `${rtn}.${rcn}`)
.where(`${vtn}.${vcn}`, id) // p[this.columnToAlias?.[this.pks[0].cn] || this.pks[0].cn])
.xwhere(where, this.dbModels[child].selectQuery(''))
.select({
[`${tn}_${vcn}`]: `${vtn}.${vcn}`,
...this.dbModels[child].selectQuery(fields)
...this.dbModels[child].selectQuery(fields),
}); // ...fields.split(','));
this._paginateAndSort(query, { sort, limit, offset }, null, true);
@ -1430,7 +1409,7 @@ class BaseModelSql extends BaseModel {
);
const gs = _.groupBy(childs, `${tn}_${vcn}`);
return parentIds.map(id => gs[id] || []);
return parentIds.map((id) => gs[id] || []);
}
/**
@ -1453,9 +1432,8 @@ class BaseModelSql extends BaseModel {
...args
}: XcFilterWithAlias & { child: string; parentId: any }) {
try {
const { where, limit, offset, sort, ...restArgs } = this._getListArgs(
args
);
const { where, limit, offset, sort, ...restArgs } =
this._getListArgs(args);
let { fields } = restArgs;
const { cn } = this.hasManyRelations.find(({ tn }) => tn === child) || {};
@ -1513,7 +1491,7 @@ class BaseModelSql extends BaseModel {
this._getChildListInParent(
{
parent,
child
child,
},
rest,
index
@ -1585,7 +1563,7 @@ class BaseModelSql extends BaseModel {
this._getChildListInParent(
{
parent: items,
child
child,
},
rest,
index
@ -1603,7 +1581,7 @@ class BaseModelSql extends BaseModel {
const { cn, rcn } =
this.belongsToRelations.find(({ rtn }) => rtn === parent) || {};
const parentIds = [
...new Set(items.map(c => c[cn] || c[this.columnToAlias[cn]]))
...new Set(items.map((c) => c[cn] || c[this.columnToAlias[cn]])),
];
return this._belongsTo(
{ parent, rcn, parentIds, childs: items, cn, ...rest },
@ -1620,7 +1598,7 @@ class BaseModelSql extends BaseModel {
this._getManyToManyList(
{
parent: items,
child
child,
},
rest,
index
@ -1701,19 +1679,19 @@ class BaseModelSql extends BaseModel {
const childModel = this.dbModels[meta.hm.tn];
await driver(meta.hm.tn)
.update({
[meta.hm.cn]: rowId
[meta.hm.cn]: rowId,
})
.whereIn(
childModel.pks[0].cn,
nestedData?.map(r => childModel._extractPksValues(r))
nestedData?.map((r) => childModel._extractPksValues(r))
);
});
} else if (meta.mm) {
postInsertOps.push(async () => {
const childModel = this.dbModels[meta.mm.rtn];
const rows = nestedData.map(r => ({
const rows = nestedData.map((r) => ({
[meta.mm.vcn]: rowId,
[meta.mm.vrcn]: childModel._extractPksValues(r)
[meta.mm.vrcn]: childModel._extractPksValues(r),
}));
await driver(meta.mm.vtn).insert(rows);
});
@ -1739,7 +1717,7 @@ class BaseModelSql extends BaseModel {
response = await this._run(query);
}
const ai = this.columns.find(c => c.ai);
const ai = this.columns.find((c) => c.ai);
if (
!response ||
(typeof response?.[0] !== 'object' && response?.[0] !== null)
@ -1779,7 +1757,7 @@ class BaseModelSql extends BaseModel {
if (response) rowId = this._extractPksValues(response);
await Promise.all(postInsertOps.map(f => f()));
await Promise.all(postInsertOps.map((f) => f()));
if (rowId) {
response = await this.nestedRead(
@ -1822,7 +1800,7 @@ class BaseModelSql extends BaseModel {
this._getChildListInParent(
{
parent: items,
child
child,
},
rest,
index,
@ -1840,7 +1818,7 @@ class BaseModelSql extends BaseModel {
const { cn, rcn } =
this.belongsToRelations.find(({ rtn }) => rtn === parent) || {};
const parentIds = [
...new Set(items.map(c => c[cn] || c[this.columnToAlias[cn]]))
...new Set(items.map((c) => c[cn] || c[this.columnToAlias[cn]])),
];
return this._belongsTo(
{ parent, rcn, parentIds, childs: items, cn, ...rest },
@ -1858,7 +1836,7 @@ class BaseModelSql extends BaseModel {
this._getManyToManyList(
{
parent: items,
child
child,
},
rest,
index,
@ -1886,7 +1864,7 @@ class BaseModelSql extends BaseModel {
offset,
sort,
condition,
conditionGraph = null
conditionGraph = null,
} = childModel._getListArgs(args);
const query = childModel.$db
@ -1921,9 +1899,11 @@ class BaseModelSql extends BaseModel {
this.manyToManyRelations.find(({ vtn }) => assoc === vtn) || {};
const childModel = this.dbModels[rtn];
const { where, condition, conditionGraph = null } = childModel._getListArgs(
args
);
const {
where,
condition,
conditionGraph = null,
} = childModel._getListArgs(args);
const query = childModel.$db
.count(`${rcn} as count`)
@ -1977,7 +1957,7 @@ class BaseModelSql extends BaseModel {
this.belongsToRelations.find(({ rtn }) => rtn === parent) || {};
this.belongsToRelations.find(({ rtn }) => rtn === parent) || {};
const parentIds = [
...new Set(childs.map(c => c[cn] || c[this.columnToAlias[cn]]))
...new Set(childs.map((c) => c[cn] || c[this.columnToAlias[cn]])),
];
return this._belongsTo(
{ parent, rcn, parentIds, childs, cn, ...rest },
@ -2029,7 +2009,7 @@ class BaseModelSql extends BaseModel {
this.dbModels[parent]?.columnToAlias?.[rcn] || rcn
);
childs.forEach(row => {
childs.forEach((row) => {
row[`${this.dbModels?.[parent]?._tn || parent}Read`] =
gs[row[this?.columnToAlias?.[cn] || cn]]?.[0];
});
@ -2054,7 +2034,7 @@ class BaseModelSql extends BaseModel {
limit,
offset,
conditionGraph,
sort
sort,
// ...restArgs
} = this.dbModels[child]._getListArgs(rest);
// let { fields } = restArgs;
@ -2069,7 +2049,7 @@ class BaseModelSql extends BaseModel {
fields = fields
.split(',')
.map(c => `${child}.${c}`)
.map((c) => `${child}.${c}`)
.join(',');
const childs = await this._run(
@ -2077,7 +2057,7 @@ class BaseModelSql extends BaseModel {
this.dbDriver.queryBuilder().from(
this.dbDriver
.union(
ids.map(p => {
ids.map((p) => {
const query = this.dbDriver(this.dbModels[child].tnPath)
.where({ [cn]: p })
.conditionGraph(conditionGraph)
@ -2139,7 +2119,7 @@ class BaseModelSql extends BaseModel {
const childs = await this._run(
this.dbDriver.unionAll(
ids.map(p => {
ids.map((p) => {
const query = this.dbDriver(this.dbModels[child].tnPath)
.count(`${cn} as count`)
.where({ [cn]: p })
@ -2177,7 +2157,7 @@ class BaseModelSql extends BaseModel {
limit = 20,
offset = 0,
sort = '',
ignoreLimit = false
ignoreLimit = false,
}: XcFilter & { ignoreLimit?: boolean },
table?: string,
isUnion?: boolean
@ -2188,13 +2168,13 @@ class BaseModelSql extends BaseModel {
if (!table && !sort && this.clientType === 'mssql' && !isUnion) {
sort =
this.columns
.filter(c => c.pk)
.map(c => `${c.cn}`)
.filter((c) => c.pk)
.map((c) => `${c.cn}`)
.join(',') || `${this.columns[0].cn}`;
}
if (sort) {
sort.split(',').forEach(o => {
sort.split(',').forEach((o) => {
if (o[0] === '-') {
query.orderBy(this.columnToAlias[o.slice(1)] || o.slice(1), 'desc');
} else {
@ -2291,8 +2271,8 @@ class BaseModelSql extends BaseModel {
public getTablePKandPVFields(table?: string): string {
return (
this.dbModels[table || this.tn]?.columns
?.filter(col => col.pk || col.pv)
.map(col => col.cn) || ['*']
?.filter((col) => col.pk || col.pv)
.map((col) => col.cn) || ['*']
).join(',');
}
@ -2419,7 +2399,7 @@ class BaseModelSql extends BaseModel {
(ro, [k, a]) => ({ ...ro, [k]: a.join(',') }),
{}
),
...fieldsObj
...fieldsObj,
};
} catch (e) {
return {};
@ -2499,7 +2479,7 @@ class BaseModelSql extends BaseModel {
knex: this.dbDriver,
rollup: v.rl,
hasMany: this.hasManyRelations,
manyToMany: this.manyToManyRelations
manyToMany: this.manyToManyRelations,
}).as(v._cn)
);
}
@ -2537,7 +2517,7 @@ class BaseModelSql extends BaseModel {
...defaultNestedQueryParams,
...args,
offset,
limit
limit,
});
if (!rows?.length) {
@ -2552,7 +2532,7 @@ class BaseModelSql extends BaseModel {
if (column._cn in row) {
csvRow[column._cn] = this.serializeCellValue({
value: row[column._cn],
column
column,
});
}
}
@ -2571,16 +2551,16 @@ class BaseModelSql extends BaseModel {
const mapPropFn = (alias, colAlias) => {
if (Array.isArray(row[prop])) {
csvRow[alias] = row[prop].map(r =>
csvRow[alias] = row[prop].map((r) =>
refModel.serializeCellValue({
value: r[colAlias],
columnName: colAlias
columnName: colAlias,
})
);
} else if (row[prop]) {
csvRow[alias] = refModel.serializeCellValue({
value: row?.[prop]?.[colAlias],
columnName: colAlias
columnName: colAlias,
});
}
};
@ -2623,14 +2603,14 @@ class BaseModelSql extends BaseModel {
fields:
fields &&
fields.filter(
f =>
this.columns.some(c => c._cn === f) ||
this.virtualColumns.some(c => c._cn === f)
(f) =>
this.columns.some((c) => c._cn === f) ||
this.virtualColumns.some((c) => c._cn === f)
),
data: csvRows
data: csvRows,
},
{
escapeFormulae: true
escapeFormulae: true,
}
);
return { data, offset, elapsed };
@ -2648,7 +2628,7 @@ class BaseModelSql extends BaseModel {
return value;
}
const column =
args.column || this.columns.find(c => c._cn === args.columnName);
args.column || this.columns.find((c) => c._cn === args.columnName);
switch (column?.uidt) {
case 'Attachment': {
@ -2660,7 +2640,7 @@ class BaseModelSql extends BaseModel {
} catch {}
return (data || []).map(
attachment =>
(attachment) =>
`${encodeURI(attachment.title)}(${encodeURI(attachment.url)})`
);
}

225
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/CustomKnex.ts

@ -2,7 +2,7 @@ import Knex, { QueryBuilder } from 'knex';
const types = require('pg').types;
// override parsing date column to Date()
types.setTypeParser(1082, val => val);
types.setTypeParser(1082, (val) => val);
import { BaseModelSql } from './BaseModelSql';
import Filter from '../../../../models/Filter';
@ -14,7 +14,7 @@ const opMappingGen = {
le: '<=',
ge: '>=',
not: '!=',
like: 'like'
like: 'like',
};
/**
@ -77,7 +77,7 @@ function toArrayOfConditions(str) {
operator,
conditions: toArrayOfConditions(
str.substring(openIndex + 1, closingIndex + 1)
)
),
},
// RHS of nested query(recursion)
...toArrayOfConditions(str.substring(closingIndex + 2))
@ -85,7 +85,7 @@ function toArrayOfConditions(str) {
return nestedArrayConditions;
}
const appendWhereCondition = function(
const appendWhereCondition = function (
conditions,
columnAliases: {
[columnAlias: string]: string;
@ -96,45 +96,45 @@ const appendWhereCondition = function(
const clientType = knexRef?.client?.config?.client;
const opMapping = {
...opMappingGen,
...(clientType === 'pg' ? { like: 'ilike' } : {})
...(clientType === 'pg' ? { like: 'ilike' } : {}),
};
const camKey = isHaving ? 'Having' : 'Where';
const key = isHaving ? 'having' : 'where';
conditions.forEach(condition => {
conditions.forEach((condition) => {
if (Array.isArray(condition)) {
knexRef[key](function() {
knexRef[key](function () {
appendWhereCondition(condition, columnAliases, this);
});
} else if (typeof condition === 'object') {
switch (condition.operator) {
case 'or':
knexRef[`or${camKey}`](function() {
knexRef[`or${camKey}`](function () {
appendWhereCondition(condition.conditions, columnAliases, this);
});
break;
case 'and':
knexRef[`and${camKey}`](function() {
knexRef[`and${camKey}`](function () {
appendWhereCondition(condition.conditions, columnAliases, this);
});
break;
case 'andnot':
knexRef[`and${camKey}Not`](function() {
knexRef[`and${camKey}Not`](function () {
appendWhereCondition(condition.conditions, columnAliases, this);
});
break;
case 'ornot':
knexRef[`or${camKey}Not`](function() {
knexRef[`or${camKey}Not`](function () {
appendWhereCondition(condition.conditions, columnAliases, this);
});
break;
case 'not':
knexRef[`${key}Not`](function() {
knexRef[`${key}Not`](function () {
appendWhereCondition(condition.conditions, columnAliases, this);
});
break;
default:
knexRef[`${key}`](function() {
knexRef[`${key}`](function () {
appendWhereCondition(condition.conditions, columnAliases, this);
});
break;
@ -149,7 +149,7 @@ const appendWhereCondition = function(
case 'in':
switch (matches[1] || '') {
case 'or':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}In`](
columnAliases[matches[2]] || matches[2],
matches[4].split(',')
@ -169,7 +169,7 @@ const appendWhereCondition = function(
);
break;
case 'ornot':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}NotIn`](
columnAliases[matches[2]] || matches[2],
matches[4].split(',')
@ -200,7 +200,7 @@ const appendWhereCondition = function(
);
switch (matches[1] || '') {
case 'or':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}Null`](columnAliases[matches[2]] || matches[2])
);
break;
@ -211,7 +211,7 @@ const appendWhereCondition = function(
knexRef[`${key}NotNull`](columnAliases[matches[2]] || matches[2]);
break;
case 'ornot':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}NotNull`](
columnAliases[matches[2]] || matches[2]
)
@ -235,7 +235,7 @@ const appendWhereCondition = function(
);
switch (matches[1] || '') {
case 'or':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}NotNull`](
columnAliases[matches[2]] || matches[2]
)
@ -248,7 +248,7 @@ const appendWhereCondition = function(
knexRef[`${key}NotNull`](columnAliases[matches[2]] || matches[2]);
break;
case 'ornot':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}NotNull`](
columnAliases[matches[2]] || matches[2]
)
@ -278,7 +278,7 @@ const appendWhereCondition = function(
);
switch (matches[1] || '') {
case 'or':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}Between`](
columnAliases[matches[2]] || matches[2],
range
@ -298,7 +298,7 @@ const appendWhereCondition = function(
);
break;
case 'ornot':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}NotBetween`](
columnAliases[matches[2]] || matches[2],
range
@ -336,7 +336,7 @@ const appendWhereCondition = function(
);
switch (matches[1] || '') {
case 'or':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}NotBetween`](
columnAliases[matches[2]] || matches[2],
range
@ -356,7 +356,7 @@ const appendWhereCondition = function(
);
break;
case 'ornot':
knexRef[`or${camKey}`](builder =>
knexRef[`or${camKey}`]((builder) =>
builder[`${key}Between`](
columnAliases[matches[2]] || matches[2],
range
@ -377,8 +377,9 @@ const appendWhereCondition = function(
break;
default:
throw new Error(
`${columnAliases[matches[2]] ||
matches[2]} : Invalid operation.`
`${
columnAliases[matches[2]] || matches[2]
} : Invalid operation.`
);
break;
}
@ -440,7 +441,7 @@ const appendWhereCondition = function(
// handle uuid case
knexRef[`${key}`](
knexRef?.client.raw(`??::TEXT ${operator} '${target}'`, [
column
column,
])
);
} else {
@ -526,19 +527,22 @@ declare module 'knex' {
/**
* Append xwhere to knex query builder
*/
Knex.QueryBuilder.extend('xwhere', function(
conditionString,
columnAliases?: {
[columnAlias: string]: string | any;
Knex.QueryBuilder.extend(
'xwhere',
function (
conditionString,
columnAliases?: {
[columnAlias: string]: string | any;
}
) {
const conditions = toArrayOfConditions(conditionString);
return appendWhereCondition(conditions, columnAliases || {}, this);
}
) {
const conditions = toArrayOfConditions(conditionString);
return appendWhereCondition(conditions, columnAliases || {}, this);
});
);
/**
* Append concat to knex query builder
*/
Knex.QueryBuilder.extend('concat', function(cn: any) {
Knex.QueryBuilder.extend('concat', function (cn: any) {
switch (this?.client?.config?.client) {
case 'pg':
this.select(this.client.raw(`STRING_AGG(?? , ',')`, [cn]));
@ -560,20 +564,23 @@ Knex.QueryBuilder.extend('concat', function(cn: any) {
/**
* Append xhaving to knex query builder
*/
Knex.QueryBuilder.extend('xhaving', function(
conditionString,
columnAliases?: {
[columnAlias: string]: string;
Knex.QueryBuilder.extend(
'xhaving',
function (
conditionString,
columnAliases?: {
[columnAlias: string]: string;
}
) {
const conditions = toArrayOfConditions(conditionString);
return appendWhereCondition(conditions, columnAliases || {}, this, true);
}
) {
const conditions = toArrayOfConditions(conditionString);
return appendWhereCondition(conditions, columnAliases || {}, this, true);
});
);
/**
* Append custom where condition(nested object) to knex query builder
*/
Knex.QueryBuilder.extend('condition', function(conditionObj, columnAliases) {
Knex.QueryBuilder.extend('condition', function (conditionObj, columnAliases) {
if (!conditionObj || typeof conditionObj !== 'object') {
return this;
}
@ -586,25 +593,25 @@ const parseCondition = (obj, columnAliases, qb, pKey?) => {
for (const [key, val] of conditions) {
switch (key) {
case '_or':
qb = qb.where(function() {
qb = qb.where(function () {
for (const condition of val as any[]) {
this.orWhere(function() {
this.orWhere(function () {
return parseCondition(condition, columnAliases, this);
});
}
});
break;
case '_and':
qb = qb.where(function() {
qb = qb.where(function () {
for (const condition of val as any[]) {
this.andWhere(function() {
this.andWhere(function () {
return parseCondition(condition, columnAliases, this);
});
}
});
break;
case '_not':
qb = qb.whereNot(function() {
qb = qb.whereNot(function () {
return parseCondition(val, columnAliases, this);
});
break;
@ -654,25 +661,29 @@ const parseCondition = (obj, columnAliases, qb, pKey?) => {
};
// todo: optimize
Knex.QueryBuilder.extend('conditionGraph', function(args: {
condition;
models;
}) {
if (!args) {
return this;
}
const { condition, models } = args;
if (!condition || typeof condition !== 'object') {
return this;
}
Knex.QueryBuilder.extend(
'conditionGraph',
function (args: { condition; models }) {
if (!args) {
return this;
}
const { condition, models } = args;
if (!condition || typeof condition !== 'object') {
return this;
}
const conditionCopy = JSON.parse(JSON.stringify(condition));
const conditionCopy = JSON.parse(JSON.stringify(condition));
// parse and do all the joins
const qb = parseNestedConditionAndJoin.call({ models }, conditionCopy, this);
// parse and define all where conditions
return parseNestedCondition.call({ models }, conditionCopy, qb);
});
// parse and do all the joins
const qb = parseNestedConditionAndJoin.call(
{ models },
conditionCopy,
this
);
// parse and define all where conditions
return parseNestedCondition.call({ models }, conditionCopy, qb);
}
);
// @ts-ignore
function parseNestedConditionAndJoin(obj, qb, pKey?, table?, tableAlias?) {
@ -709,7 +720,7 @@ function parseNestedConditionAndJoin(obj, qb, pKey?, table?, tableAlias?) {
alias: `${
this._tn[relation.tn] ? this._tn[relation.tn] + '___' : ''
}${relation.tn}`,
type: obj.relationType
type: obj.relationType,
};
qb = qb.join(
@ -721,7 +732,7 @@ function parseNestedConditionAndJoin(obj, qb, pKey?, table?, tableAlias?) {
// delete obj.relationType;
// return parseNestedConditionAndJoin.call(this, Object.entries(obj).find(([k]) => k !== 'relationType')?.[1], qb, Object.keys(obj).find(k => k !== 'relationType'), relation.tn)
tn = relation.tn;
conditions = conditions.filter(c => c[0] !== 'relationType');
conditions = conditions.filter((c) => c[0] !== 'relationType');
tableAlias = obj.relationType._tn;
}
@ -743,7 +754,7 @@ function parseNestedConditionAndJoin(obj, qb, pKey?, table?, tableAlias?) {
this._tn[relation.rtn] = (this._tn[relation.rtn] || 0) + 1;
obj.relationType = {
alias: `${this._tn[relation.rtn]}___${relation.rtn}`,
type: obj.relationType
type: obj.relationType,
};
qb = qb.join(
`${relation.rtn} as ${obj.relationType._tn}`,
@ -754,7 +765,7 @@ function parseNestedConditionAndJoin(obj, qb, pKey?, table?, tableAlias?) {
// delete obj.relationType;
// return parseNestedConditionAndJoin.call(self, Object.entries(obj).find(([k]) => k !== 'relationType')?.[1], qb, Object.keys(obj).find(k => k !== 'relationType'), relation.rtn)
tn = relation.rtn;
conditions = conditions.filter(c => c[0] !== 'relationType');
conditions = conditions.filter((c) => c[0] !== 'relationType');
tableAlias = obj.relationType._tn;
}
}
@ -875,7 +886,7 @@ function parseNestedCondition(obj, qb, pKey?, table?, tableAlias?) {
// alias = self.alias;
}
const conditions = Object.entries(obj).filter(c => c[0] !== 'relationType');
const conditions = Object.entries(obj).filter((c) => c[0] !== 'relationType');
// const colPrefix = `${alias[tn] ? alias[tn] + '___' : ''}${tn}.`;
const colPrefix = `${tableAlias}.`;
@ -883,9 +894,9 @@ function parseNestedCondition(obj, qb, pKey?, table?, tableAlias?) {
// handle logical operators recursively
switch (key) {
case '_or':
qb = qb.where(function() {
qb = qb.where(function () {
for (const condition of val as any[]) {
this.orWhere(function() {
this.orWhere(function () {
return parseNestedCondition.call(
self,
condition,
@ -899,9 +910,9 @@ function parseNestedCondition(obj, qb, pKey?, table?, tableAlias?) {
});
break;
case '_and':
qb = qb.where(function() {
qb = qb.where(function () {
for (const condition of val as any[]) {
this.andWhere(function() {
this.andWhere(function () {
parseNestedCondition.call(
self,
condition,
@ -915,7 +926,7 @@ function parseNestedCondition(obj, qb, pKey?, table?, tableAlias?) {
});
break;
case '_not':
qb = qb.whereNot(function() {
qb = qb.whereNot(function () {
return parseNestedCondition.call(
self,
val,
@ -994,7 +1005,7 @@ function CustomKnex(arg: string | Knex.Config<any> | any): CustomKnex {
enumerable: true,
value: (...args) => {
return knexRaw.apply(knex, args);
}
},
},
clientType: {
enumerable: true,
@ -1002,14 +1013,14 @@ function CustomKnex(arg: string | Knex.Config<any> | any): CustomKnex {
return typeof arg === 'string'
? arg.match(/^(\w+):/) ?? [1]
: arg.client;
}
},
},
searchPath: {
enumerable: true,
value: () => {
return arg?.searchPath?.[0];
}
}
},
},
});
/**
@ -1025,25 +1036,25 @@ function CustomKnex(arg: string | Knex.Config<any> | any): CustomKnex {
}
// todo: optimize
Knex.QueryBuilder.extend('conditionGraphv2', function(args: {
condition;
models;
}) {
if (!args) {
return this;
}
const { condition, models } = args;
if (!condition || typeof condition !== 'object') {
return this;
}
Knex.QueryBuilder.extend(
'conditionGraphv2',
function (args: { condition; models }) {
if (!args) {
return this;
}
const { condition, models } = args;
if (!condition || typeof condition !== 'object') {
return this;
}
const conditionCopy = JSON.parse(JSON.stringify(condition));
const conditionCopy = JSON.parse(JSON.stringify(condition));
// parse and do all the joins
// const qb = parseNestedConditionAndJoin.call({ models }, conditionCopy, this);
// parse and define all where conditions
return parseNestedConditionv2.call({ models }, conditionCopy);
});
// parse and do all the joins
// const qb = parseNestedConditionAndJoin.call({ models }, conditionCopy, this);
// parse and define all where conditions
return parseNestedConditionv2.call({ models }, conditionCopy);
}
);
function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
// this.alias = {...(this.alias || {})};
@ -1114,7 +1125,7 @@ function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
// alias = self.alias;
}
const conditions = Object.entries(obj).filter(c => c[0] !== 'relationType');
const conditions = Object.entries(obj).filter((c) => c[0] !== 'relationType');
// const colPrefix = `${alias[tn] ? alias[tn] + '___' : ''}${tn}.`;
const colPrefix = `${tableAlias}.`;
@ -1122,9 +1133,9 @@ function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
// handle logical operators recursively
switch (key) {
case '_or':
qb = qb.where(function() {
qb = qb.where(function () {
for (const condition of val as any[]) {
this.orWhere(function() {
this.orWhere(function () {
return parseNestedCondition.call(
self,
condition,
@ -1138,9 +1149,9 @@ function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
});
break;
case '_and':
qb = qb.where(function() {
qb = qb.where(function () {
for (const condition of val as any[]) {
this.andWhere(function() {
this.andWhere(function () {
parseNestedCondition.call(
self,
condition,
@ -1154,7 +1165,7 @@ function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
});
break;
case '_not':
qb = qb.whereNot(function() {
qb = qb.whereNot(function () {
return parseNestedCondition.call(
self,
val,
@ -1216,7 +1227,7 @@ function parseNestedConditionv2(obj, qb, pKey?, table?, tableAlias?) {
/**
* Append custom where condition(nested object) to knex query builder
*/
Knex.QueryBuilder.extend('conditionv2', function(conditionObj: Filter) {
Knex.QueryBuilder.extend('conditionv2', function (conditionObj: Filter) {
if (!conditionObj || typeof conditionObj !== 'object') {
return this;
}
@ -1225,17 +1236,17 @@ Knex.QueryBuilder.extend('conditionv2', function(conditionObj: Filter) {
const parseConditionv2 = (obj: Filter, qb: QueryBuilder) => {
if (obj.is_group) {
qb = qb.where(function() {
qb = qb.where(function () {
const children = obj.children;
if (obj.logical_op?.toLowerCase() === 'or') {
for (const filter of children || []) {
this.orWhere(function() {
this.orWhere(function () {
return parseConditionv2(filter, this);
});
}
} else {
for (const filter of children || []) {
this.andWhere(function() {
this.andWhere(function () {
return parseConditionv2(filter, this);
});
}

6
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts

@ -289,11 +289,7 @@ const parseConditionV2 = async (
if (qb?.client?.config?.client === 'pg') {
qb = qb.whereRaw('??::text ilike ?', [field, val]);
} else {
qb = qb.where(
field,
'like',
val
);
qb = qb.where(field, 'like', val);
}
break;
case 'nlike':

4
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/customValidators.ts

@ -1,5 +1,5 @@
import Validator from 'validator';
export const customValidators = {
isCurrency: Validator['isFloat']
}
isCurrency: Validator['isFloat'],
};

20
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulaQueryBuilderFromString.ts

@ -25,7 +25,7 @@ export default function formulaQueryBuilder(
type: 'BinaryExpression',
operator: '+',
left: pt.arguments[0],
right: { ...pt, arguments: pt.arguments.slice(1) }
right: { ...pt, arguments: pt.arguments.slice(1) },
},
alias,
prevBinaryOp
@ -54,7 +54,7 @@ export default function formulaQueryBuilder(
type: 'BinaryExpression',
operator: '||',
left: pt.arguments[0],
right: { ...pt, arguments: pt.arguments.slice(1) }
right: { ...pt, arguments: pt.arguments.slice(1) },
},
alias,
prevBinaryOp
@ -81,19 +81,19 @@ export default function formulaQueryBuilder(
{
type: 'Literal',
value: 'URI::(',
raw: '"URI::("'
raw: '"URI::("',
},
pt.arguments[0],
{
type: 'Literal',
value: ')',
raw: '")"'
}
raw: '")"',
},
],
callee: {
type: 'Identifier',
name: 'CONCAT'
}
name: 'CONCAT',
},
},
alias,
prevBinaryOp
@ -109,7 +109,7 @@ export default function formulaQueryBuilder(
aliasToCol: aliasToColumn,
fn,
colAlias,
prevBinaryOp
prevBinaryOp,
});
if (res) return res;
}
@ -118,7 +118,7 @@ export default function formulaQueryBuilder(
return knex.raw(
`${pt.callee.name}(${pt.arguments
.map(arg => fn(arg).toQuery())
.map((arg) => fn(arg).toQuery())
.join()})${colAlias}`
);
} else if (pt.type === 'Literal') {
@ -134,7 +134,7 @@ export default function formulaQueryBuilder(
pt.left = {
callee: { name: 'FLOAT' },
type: 'CallExpression',
arguments: [pt.left]
arguments: [pt.left],
};
}

109
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/formulav2/formulaQueryBuilderv2.ts

@ -12,9 +12,9 @@ import { jsepCurlyHook, UITypes } from 'nocodb-sdk';
// todo: switch function based on database
// @ts-ignore
const getAggregateFn: (
fnName: string
) => (args: { qb; knex?; cn }) => any = parentFn => {
const getAggregateFn: (fnName: string) => (args: { qb; knex?; cn }) => any = (
parentFn
) => {
switch (parentFn?.toUpperCase()) {
case 'MIN':
return ({ qb, cn }) => qb.clear('select').min(cn);
@ -82,9 +82,8 @@ export default async function formulaQueryBuilderv2(
const lookup = await col.getColOptions<LookupColumn>();
{
const relationCol = await lookup.getRelationColumn();
const relation = await relationCol.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await relationCol.getColOptions<LinkToAnotherRecordColumn>();
// if (relation.type !== 'bt') continue;
const childColumn = await relation.getChildColumn();
@ -98,7 +97,7 @@ export default async function formulaQueryBuilderv2(
selectQb = knex(`${parentModel.table_name} as ${alias}`).where(
`${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${childModel.table_name}.${childColumn.column_name}`
`${childModel.table_name}.${childColumn.column_name}`,
])
);
break;
@ -107,7 +106,7 @@ export default async function formulaQueryBuilderv2(
selectQb = knex(`${childModel.table_name} as ${alias}`).where(
`${alias}.${childColumn.column_name}`,
knex.raw(`??`, [
`${parentModel.table_name}.${parentColumn.column_name}`
`${parentModel.table_name}.${parentColumn.column_name}`,
])
);
break;
@ -128,7 +127,7 @@ export default async function formulaQueryBuilderv2(
.where(
`${assocAlias}.${mmChildColumn.column_name}`,
knex.raw(`??`, [
`${childModel.table_name}.${childColumn.column_name}`
`${childModel.table_name}.${childColumn.column_name}`,
])
);
}
@ -139,13 +138,11 @@ export default async function formulaQueryBuilderv2(
let prevAlias = alias;
while (lookupColumn.uidt === UITypes.Lookup) {
const nestedAlias = `__nc_formula${aliasCount++}`;
const nestedLookup = await lookupColumn.getColOptions<
LookupColumn
>();
const nestedLookup =
await lookupColumn.getColOptions<LookupColumn>();
const relationCol = await nestedLookup.getRelationColumn();
const relation = await relationCol.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await relationCol.getColOptions<LinkToAnotherRecordColumn>();
// if any of the relation in nested lookup is
// not belongs to then ignore the sort option
// if (relation.type !== 'bt') continue;
@ -216,20 +213,21 @@ export default async function formulaQueryBuilderv2(
await genRollupSelectv2({
knex,
alias: prevAlias,
columnOptions: (await lookupColumn.getColOptions()) as RollupColumn
columnOptions:
(await lookupColumn.getColOptions()) as RollupColumn,
})
).builder;
// selectQb.select(builder);
if (isMany) {
const qb = selectQb;
selectQb = fn =>
selectQb = (fn) =>
knex
.raw(
getAggregateFn(fn)({
qb,
knex,
cn: knex.raw(builder).wrap('(', ')')
cn: knex.raw(builder).wrap('(', ')'),
})
)
.wrap('(', ')');
@ -241,12 +239,12 @@ export default async function formulaQueryBuilderv2(
case UITypes.LinkToAnotherRecord:
{
const nestedAlias = `__nc_formula${aliasCount++}`;
const relation = await lookupColumn.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await lookupColumn.getColOptions<LinkToAnotherRecordColumn>();
// if (relation.type !== 'bt') continue;
const colOptions = (await lookupColumn.getColOptions()) as LinkToAnotherRecordColumn;
const colOptions =
(await lookupColumn.getColOptions()) as LinkToAnotherRecordColumn;
const childColumn = await colOptions.getChildColumn();
const parentColumn = await colOptions.getParentColumn();
const childModel = await childColumn.getModel();
@ -264,7 +262,7 @@ export default async function formulaQueryBuilderv2(
);
cn = knex.raw('??.??', [
nestedAlias,
parentModel?.primaryValue?.column_name
parentModel?.primaryValue?.column_name,
]);
}
break;
@ -278,7 +276,7 @@ export default async function formulaQueryBuilderv2(
);
cn = knex.raw('??.??', [
nestedAlias,
childModel?.primaryValue?.column_name
childModel?.primaryValue?.column_name,
]);
}
break;
@ -286,7 +284,8 @@ export default async function formulaQueryBuilderv2(
{
isMany = true;
const mmModel = await relation.getMMModel();
const mmParentColumn = await relation.getMMParentColumn();
const mmParentColumn =
await relation.getMMParentColumn();
const mmChildColumn = await relation.getMMChildColumn();
const assocAlias = `__nc${aliasCount++}`;
@ -305,7 +304,7 @@ export default async function formulaQueryBuilderv2(
}
cn = knex.raw('??.??', [
nestedAlias,
parentModel?.primaryValue?.column_name
parentModel?.primaryValue?.column_name,
]);
}
@ -317,13 +316,13 @@ export default async function formulaQueryBuilderv2(
if (isMany) {
const qb = selectQb;
selectQb = fn =>
selectQb = (fn) =>
knex
.raw(
getAggregateFn(fn)({
qb,
knex,
cn: lookupColumn.column_name
cn: lookupColumn.column_name,
})
)
.wrap('(', ')');
@ -334,9 +333,8 @@ export default async function formulaQueryBuilderv2(
break;
case UITypes.Formula:
{
const formulaOption = await lookupColumn.getColOptions<
FormulaColumn
>();
const formulaOption =
await lookupColumn.getColOptions<FormulaColumn>();
const lookupModel = await lookupColumn.getModel();
const { builder } = await formulaQueryBuilderv2(
formulaOption.formula,
@ -347,13 +345,13 @@ export default async function formulaQueryBuilderv2(
);
if (isMany) {
const qb = selectQb;
selectQb = fn =>
selectQb = (fn) =>
knex
.raw(
getAggregateFn(fn)({
qb,
knex,
cn: knex.raw(builder).wrap('(', ')')
cn: knex.raw(builder).wrap('(', ')'),
})
)
.wrap('(', ')');
@ -366,13 +364,13 @@ export default async function formulaQueryBuilderv2(
{
if (isMany) {
const qb = selectQb;
selectQb = fn =>
selectQb = (fn) =>
knex
.raw(
getAggregateFn(fn)({
qb,
knex,
cn: `${prevAlias}.${lookupColumn.column_name}`
cn: `${prevAlias}.${lookupColumn.column_name}`,
})
)
.wrap('(', ')');
@ -396,7 +394,7 @@ export default async function formulaQueryBuilderv2(
{
const qb = await genRollupSelectv2({
knex,
columnOptions: (await col.getColOptions()) as RollupColumn
columnOptions: (await col.getColOptions()) as RollupColumn,
});
aliasToColumn[col.id] = knex.raw(qb.builder).wrap('(', ')');
}
@ -407,7 +405,8 @@ export default async function formulaQueryBuilderv2(
const relation = await col.getColOptions<LinkToAnotherRecordColumn>();
// if (relation.type !== 'bt') continue;
const colOptions = (await col.getColOptions()) as LinkToAnotherRecordColumn;
const colOptions =
(await col.getColOptions()) as LinkToAnotherRecordColumn;
const childColumn = await colOptions.getChildColumn();
const parentColumn = await colOptions.getParentColumn();
const childModel = await childColumn.getModel();
@ -422,7 +421,7 @@ export default async function formulaQueryBuilderv2(
.where(
`${parentModel.table_name}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${childModel.table_name}.${childColumn.column_name}`
`${childModel.table_name}.${childColumn.column_name}`,
])
);
} else if (relation.type == 'hm') {
@ -431,17 +430,17 @@ export default async function formulaQueryBuilderv2(
.where(
`${childModel.table_name}.${childColumn.column_name}`,
knex.raw(`??`, [
`${parentModel.table_name}.${parentColumn.column_name}`
`${parentModel.table_name}.${parentColumn.column_name}`,
])
);
selectQb = fn =>
selectQb = (fn) =>
knex
.raw(
getAggregateFn(fn)({
qb,
knex,
cn: childModel?.primaryValue?.column_name
cn: childModel?.primaryValue?.column_name,
})
)
.wrap('(', ')');
@ -484,16 +483,16 @@ export default async function formulaQueryBuilderv2(
.where(
`${mmModel.table_name}.${mmChildColumn.column_name}`,
knex.raw(`??`, [
`${childModel.table_name}.${childColumn.column_name}`
`${childModel.table_name}.${childColumn.column_name}`,
])
);
selectQb = fn =>
selectQb = (fn) =>
knex
.raw(
getAggregateFn(fn)({
qb,
knex,
cn: parentModel?.primaryValue?.column_name
cn: parentModel?.primaryValue?.column_name,
})
)
.wrap('(', ')');
@ -513,7 +512,7 @@ export default async function formulaQueryBuilderv2(
const fn = (pt, a?, prevBinaryOp?) => {
const colAlias = a ? ` as ${a}` : '';
pt.arguments?.forEach?.(arg => {
pt.arguments?.forEach?.((arg) => {
if (arg.fnName) return;
arg.fnName = pt.callee.name;
arg.argsCount = pt.arguments?.length;
@ -528,7 +527,7 @@ export default async function formulaQueryBuilderv2(
type: 'BinaryExpression',
operator: '+',
left: pt.arguments[0],
right: { ...pt, arguments: pt.arguments.slice(1) }
right: { ...pt, arguments: pt.arguments.slice(1) },
},
a,
prevBinaryOp
@ -557,7 +556,7 @@ export default async function formulaQueryBuilderv2(
type: 'BinaryExpression',
operator: '||',
left: pt.arguments[0],
right: { ...pt, arguments: pt.arguments.slice(1) }
right: { ...pt, arguments: pt.arguments.slice(1) },
},
a,
prevBinaryOp
@ -575,19 +574,19 @@ export default async function formulaQueryBuilderv2(
{
type: 'Literal',
value: 'URI::(',
raw: '"URI::("'
raw: '"URI::("',
},
pt.arguments[0],
{
type: 'Literal',
value: ')',
raw: '")"'
}
raw: '")"',
},
],
callee: {
type: 'Identifier',
name: 'CONCAT'
}
name: 'CONCAT',
},
},
alias,
prevBinaryOp
@ -603,7 +602,7 @@ export default async function formulaQueryBuilderv2(
aliasToCol: aliasToColumn,
fn,
colAlias,
prevBinaryOp
prevBinaryOp,
});
if (res) return res;
}
@ -612,7 +611,7 @@ export default async function formulaQueryBuilderv2(
return knex.raw(
`${pt.callee.name}(${pt.arguments
.map(arg => {
.map((arg) => {
const query = fn(arg).toQuery();
if (pt.callee.name === 'CONCAT') {
if (knex.clientType() === 'mysql2') {
@ -645,7 +644,7 @@ export default async function formulaQueryBuilderv2(
pt.left = {
callee: { name: 'FLOAT' },
type: 'CallExpression',
arguments: [pt.left]
arguments: [pt.left],
};
}
pt.left.fnName = pt.left.fnName || 'ARITH';

14
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/commonFns.ts

@ -43,13 +43,15 @@ export default {
}
return args.knex.raw(`CASE ${query}\n END${args.colAlias}`);
},
TRUE: _args => 1,
FALSE: _args => 0,
TRUE: (_args) => 1,
FALSE: (_args) => 0,
AND: (args: MapFnArgs) => {
return args.knex.raw(
`${args.knex
.raw(
`${args.pt.arguments.map(ar => args.fn(ar).toQuery()).join(' AND ')}`
`${args.pt.arguments
.map((ar) => args.fn(ar).toQuery())
.join(' AND ')}`
)
.wrap('(', ')')
.toQuery()}${args.colAlias}`
@ -59,7 +61,7 @@ export default {
return args.knex.raw(
`${args.knex
.raw(
`${args.pt.arguments.map(ar => args.fn(ar).toQuery()).join(' OR ')}`
`${args.pt.arguments.map((ar) => args.fn(ar).toQuery()).join(' OR ')}`
)
.wrap('(', ')')
.toQuery()}${args.colAlias}`
@ -72,7 +74,7 @@ export default {
type: 'BinaryExpression',
operator: '/',
left: { ...args.pt, callee: { name: 'SUM' } },
right: { type: 'Literal', value: args.pt.arguments.length }
right: { type: 'Literal', value: args.pt.arguments.length },
},
args.a,
args.prevBinaryOp
@ -83,5 +85,5 @@ export default {
},
FLOAT: (args: MapFnArgs) => {
return args.fn(args.pt?.arguments?.[0]).wrap('(', ')');
}
},
};

22
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts

@ -17,7 +17,8 @@ const mssql = {
`\n\tWhen ${args.pt.arguments
.filter((_, j) => +i !== j)
.map(
arg1 => `${args.fn(arg).toQuery()} < ${args.fn(arg1).toQuery()}`
(arg1) =>
`${args.fn(arg).toQuery()} < ${args.fn(arg1).toQuery()}`
)
.join(' And ')} Then ${args.fn(arg).toQuery()}`
)
@ -40,7 +41,8 @@ const mssql = {
`\nWhen ${args.pt.arguments
.filter((_, j) => +i !== j)
.map(
arg1 => `${args.fn(arg).toQuery()} > ${args.fn(arg1).toQuery()}`
(arg1) =>
`${args.fn(arg).toQuery()} > ${args.fn(arg1).toQuery()}`
)
.join(' And ')} Then ${args.fn(arg).toQuery()}`
)
@ -54,16 +56,16 @@ const mssql = {
return args.knex.raw(
`LOG(${args.pt.arguments
.reverse()
.map(ar => args.fn(ar).toQuery())
.map((ar) => args.fn(ar).toQuery())
.join(',')})${args.colAlias}`
);
},
MOD: pt => {
MOD: (pt) => {
Object.assign(pt, {
type: 'BinaryExpression',
operator: '%',
left: pt.arguments[0],
right: pt.arguments[1]
right: pt.arguments[1],
});
},
REPEAT: 'REPLICATE',
@ -95,13 +97,17 @@ const mssql = {
`CASE
WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN
FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')},
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn(pt.arguments[0])}), 'yyyy-MM-dd HH:mm')
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn(
pt.arguments[0]
)}), 'yyyy-MM-dd HH:mm')
ELSE
FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')},
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn(pt.arguments[0])}), 'yyyy-MM-dd')
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn(
pt.arguments[0]
)}), 'yyyy-MM-dd')
END${colAlias}`
);
}
},
};
export default mssql;

2
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mysql.ts

@ -54,7 +54,7 @@ const mysql2 = {
)}))
END${colAlias}`
);
}
},
};
export default mysql2;

7
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts

@ -36,9 +36,12 @@ const pg = {
DATEADD: ({ fn, knex, pt, colAlias }: MapFnArgs) => {
return knex.raw(
`${fn(pt.arguments[0])} + (${fn(pt.arguments[1])} ||
'${String(fn(pt.arguments[2])).replace(/["']/g, '')}')::interval${colAlias}`
'${String(fn(pt.arguments[2])).replace(
/["']/g,
''
)}')::interval${colAlias}`
);
}
},
};
export default pg;

18
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts

@ -19,7 +19,7 @@ const sqlite3 = {
type: 'BinaryExpression',
operator: '%',
left: args.pt.arguments[0],
right: args.pt.arguments[1]
right: args.pt.arguments[1],
});
},
REPEAT(args: MapFnArgs) {
@ -64,19 +64,17 @@ const sqlite3 = {
STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${fn(
pt.arguments[0]
)}, 'localtime'),
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])} || ' ${String(fn(pt.arguments[2])).replace(
/["']/g,
''
)}'))
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])} || ' ${String(
fn(pt.arguments[2])
).replace(/["']/g, '')}'))
ELSE
DATE(DATETIME(${fn(pt.arguments[0])}, 'localtime'),
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])} || ' ${String(fn(pt.arguments[2])).replace(
/["']/g,
''
)}')
${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])} || ' ${String(
fn(pt.arguments[2])
).replace(/["']/g, '')}')
END${colAlias}`
);
}
},
};
export default sqlite3;

8
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelect.ts

@ -1,11 +1,11 @@
import Knex from 'knex';
import { RelationTypes } from 'nocodb-sdk';
export default function({
export default function ({
knex,
rollup: _rollup,
hasMany,
manyToMany
manyToMany,
}: {
tn: string;
knex: Knex;
@ -18,7 +18,7 @@ export default function({
switch (rollup.type) {
case RelationTypes.HAS_MANY:
if (!rollup.tn || !rollup.rtn) {
rollup = { ...rollup, ...hasMany.find(hm => hm.tn === rollup.rltn) };
rollup = { ...rollup, ...hasMany.find((hm) => hm.tn === rollup.rltn) };
}
return knex(rollup.rltn)
[rollup.fn]?.(knex.ref(`${rollup.rltn}.${rollup.rlcn}`))
@ -32,7 +32,7 @@ export default function({
if (!rollup.tn || !rollup.rtn || !rollup.vtn) {
rollup = {
...rollup,
...manyToMany.find(mm => mm.rtn === rollup.rltn)
...manyToMany.find((mm) => mm.rtn === rollup.rltn),
};
}
return knex(rollup.rltn)

11
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/genRollupSelectv2.ts

@ -4,19 +4,20 @@ import LinkToAnotherRecordColumn from '../../../../models/LinkToAnotherRecordCol
import { QueryBuilder } from 'knex';
import { RelationTypes } from 'nocodb-sdk';
export default async function({
export default async function ({
knex,
// tn,
// column,
alias,
columnOptions
columnOptions,
}: {
knex: XKnex;
alias?: string;
columnOptions: RollupColumn;
}): Promise<{ builder: QueryBuilder | any }> {
const relationColumn = await columnOptions.getRelationColumn();
const relationColumnOption: LinkToAnotherRecordColumn = (await relationColumn.getColOptions()) as LinkToAnotherRecordColumn;
const relationColumnOption: LinkToAnotherRecordColumn =
(await relationColumn.getColOptions()) as LinkToAnotherRecordColumn;
const rollupColumn = await columnOptions.getRollupColumn();
const childCol = await relationColumnOption.getChildColumn();
const childModel = await childCol?.getModel();
@ -39,7 +40,7 @@ export default async function({
),
'=',
knex.ref(`${childModel.table_name}.${childCol.column_name}`)
)
),
};
case RelationTypes.MANY_TO_MANY: {
const mmModel = await relationColumnOption.getMMModel();
@ -63,7 +64,7 @@ export default async function({
knex.ref(
`${alias || childModel.table_name}.${childCol.column_name}`
)
)
),
};
}

16
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/helpers/getAst.ts

@ -8,7 +8,7 @@ const getAst = async ({
extractOnlyPrimaries = false,
includePkByDefault = true,
model,
view
view,
}: {
query?: RequestQuery;
extractOnlyPrimaries?: boolean;
@ -24,7 +24,7 @@ const getAst = async ({
...(model.primaryKeys
? model.primaryKeys.reduce((o, pk) => ({ ...o, [pk.title]: 1 }), {})
: {}),
...(model.primaryValue ? { [model.primaryValue.title]: 1 } : {})
...(model.primaryValue ? { [model.primaryValue.title]: 1 } : {}),
};
}
@ -40,7 +40,7 @@ const getAst = async ({
allowedCols = (await View.getColumns(view.id)).reduce(
(o, c) => ({
...o,
[c.fk_column_id]: c.show
[c.fk_column_id]: c.show,
}),
{}
);
@ -53,11 +53,11 @@ const getAst = async ({
if (col.uidt === UITypes.LinkToAnotherRecord) {
const model = await col
.getColOptions<LinkToAnotherRecordColumn>()
.then(colOpt => colOpt.getRelatedTable());
.then((colOpt) => colOpt.getRelatedTable());
value = await getAst({
model,
query: query?.nested?.[col.title]
query: query?.nested?.[col.title],
});
} else {
value = (Array.isArray(fields) ? fields : fields.split(',')).reduce(
@ -68,12 +68,12 @@ const getAst = async ({
} else if (col.uidt === UITypes.LinkToAnotherRecord) {
const model = await col
.getColOptions<LinkToAnotherRecordColumn>()
.then(colOpt => colOpt.getRelatedTable());
.then((colOpt) => colOpt.getRelatedTable());
value = await getAst({
model,
query: query?.nested?.[col.title],
extractOnlyPrimaries: nestedFields !== '*'
extractOnlyPrimaries: nestedFields !== '*',
});
}
@ -87,7 +87,7 @@ const getAst = async ({
value
: fields?.length
? fields.includes(col.title) && value
: value
: value,
};
}, Promise.resolve({}));
};

48
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/sortV2.ts

@ -35,7 +35,7 @@ export default async function sortV2(
const builder = (
await genRollupSelectv2({
knex,
columnOptions: (await column.getColOptions()) as RollupColumn
columnOptions: (await column.getColOptions()) as RollupColumn,
})
).builder;
@ -46,7 +46,9 @@ export default async function sortV2(
{
const builder = (
await formulaQueryBuilderv2(
(await column.getColOptions<FormulaColumn>()).formula,
(
await column.getColOptions<FormulaColumn>()
).formula,
null,
knex,
model
@ -64,9 +66,8 @@ export default async function sortV2(
const lookup = await column.getColOptions<LookupColumn>();
{
const relationCol = await lookup.getRelationColumn();
const relation = await relationCol.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await relationCol.getColOptions<LinkToAnotherRecordColumn>();
if (relation.type !== RelationTypes.BELONGS_TO) return;
const childColumn = await relation.getChildColumn();
@ -79,7 +80,7 @@ export default async function sortV2(
selectQb = knex(`${parentModel.table_name} as ${alias}`).where(
`${alias}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${childModel.table_name}.${childColumn.column_name}`
`${childModel.table_name}.${childColumn.column_name}`,
])
);
}
@ -87,13 +88,11 @@ export default async function sortV2(
let prevAlias = alias;
while (lookupColumn.uidt === UITypes.Lookup) {
const nestedAlias = `__nc_sort${aliasCount++}`;
const nestedLookup = await lookupColumn.getColOptions<
LookupColumn
>();
const nestedLookup =
await lookupColumn.getColOptions<LookupColumn>();
const relationCol = await nestedLookup.getRelationColumn();
const relation = await relationCol.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await relationCol.getColOptions<LinkToAnotherRecordColumn>();
// if any of the relation in nested lookup is
// not belongs to then ignore the sort option
if (relation.type !== 'bt') return;
@ -121,7 +120,8 @@ export default async function sortV2(
const builder = (
await genRollupSelectv2({
knex,
columnOptions: (await lookupColumn.getColOptions()) as RollupColumn
columnOptions:
(await lookupColumn.getColOptions()) as RollupColumn,
})
).builder;
selectQb.select(builder);
@ -130,12 +130,12 @@ export default async function sortV2(
case UITypes.LinkToAnotherRecord:
{
const nestedAlias = `__nc_sort${aliasCount++}`;
const relation = await lookupColumn.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await lookupColumn.getColOptions<LinkToAnotherRecordColumn>();
if (relation.type !== 'bt') return;
const colOptions = (await column.getColOptions()) as LinkToAnotherRecordColumn;
const colOptions =
(await column.getColOptions()) as LinkToAnotherRecordColumn;
const childColumn = await colOptions.getChildColumn();
const parentColumn = await colOptions.getParentColumn();
const childModel = await childColumn.getModel();
@ -156,7 +156,9 @@ export default async function sortV2(
{
const builder = (
await formulaQueryBuilderv2(
(await column.getColOptions<FormulaColumn>()).formula,
(
await column.getColOptions<FormulaColumn>()
).formula,
null,
knex,
model
@ -180,12 +182,12 @@ export default async function sortV2(
break;
case UITypes.LinkToAnotherRecord:
{
const relation = await column.getColOptions<
LinkToAnotherRecordColumn
>();
const relation =
await column.getColOptions<LinkToAnotherRecordColumn>();
if (relation.type !== 'bt') return;
const colOptions = (await column.getColOptions()) as LinkToAnotherRecordColumn;
const colOptions =
(await column.getColOptions()) as LinkToAnotherRecordColumn;
const childColumn = await colOptions.getChildColumn();
const parentColumn = await colOptions.getParentColumn();
const childModel = await childColumn.getModel();
@ -198,7 +200,7 @@ export default async function sortV2(
.where(
`${parentModel.table_name}.${parentColumn.column_name}`,
knex.raw(`??`, [
`${childModel.table_name}.${childColumn.column_name}`
`${childModel.table_name}.${childColumn.column_name}`,
])
);

108
packages/nocodb/src/lib/db/sql-mgr/SqlMgr.ts

@ -90,7 +90,7 @@ const ToolOps = {
PROJECT_CREATE_BY_WEB: 'projectCreateByWeb',
PROJECT_CHANGE_ENV: 'projectChangeEnv',
PROJECT_UPDATE_BY_WEB: 'projectUpdateByWeb'
PROJECT_UPDATE_BY_WEB: 'projectUpdateByWeb',
};
export default class SqlMgr {
@ -173,21 +173,21 @@ export default class SqlMgr {
args.folder = slash(this.currentProjectFolder);
const projectJson = {
...this.currentProjectJson,
envs: { ...this.currentProjectJson.envs }
envs: { ...this.currentProjectJson.envs },
};
// delete db credentials
for (const env of Object.keys(projectJson.envs)) {
projectJson.envs[env] = {
...projectJson.envs[env],
db: [...projectJson.envs[env].db]
db: [...projectJson.envs[env].db],
};
for (let i = 0; i < projectJson.envs[env].db.length; i++) {
projectJson.envs[env].db[i] = {
...projectJson.envs[env].db[i],
connection: {
database: projectJson.envs[env].db[i].connection.database
}
database: projectJson.envs[env].db[i].connection.database,
},
};
}
}
@ -219,8 +219,8 @@ export default class SqlMgr {
// }
result.data.list = [
{
folder: args.folder
}
folder: args.folder,
},
];
log.api(`${_func}: result`, result);
return result;
@ -255,7 +255,7 @@ export default class SqlMgr {
i
.toString(26)
.split('')
.map(v => l[parseInt(v, 26)])
.map((v) => l[parseInt(v, 26)])
.join('') + '1'
);
}
@ -296,22 +296,21 @@ export default class SqlMgr {
const connectionKey = `${env}_${this.currentProjectJson.envs[env].db[i].meta.dbAlias}`;
this.currentProjectConnections[
connectionKey
] = SqlClientFactory.create({
...connectionConfig,
knex: NcConnectionMgr.get({
dbAlias: this.currentProjectJson.envs[env].db[i].meta.dbAlias,
env: env,
config: args,
projectId: args.id
})
});
this.currentProjectConnections[connectionKey] =
SqlClientFactory.create({
...connectionConfig,
knex: NcConnectionMgr.get({
dbAlias: this.currentProjectJson.envs[env].db[i].meta.dbAlias,
env: env,
config: args,
projectId: args.id,
}),
});
this.currentProjectServers[connectionKey] = {
xserver: null,
input: {},
output: {}
output: {},
};
}
}
@ -524,8 +523,8 @@ export default class SqlMgr {
client: 'sqlite3',
connection: {
// filename: "./db/sakila-sqlite"
filename: sqlConfig.database
}
filename: sqlConfig.database,
},
};
} else if (sqlConfig.typeOfDatabase === 'oracledb') {
return {
@ -536,26 +535,26 @@ export default class SqlMgr {
password: sqlConfig.password,
database: sqlConfig.database,
port: sqlConfig.port,
connectString: `localhost:${ORACLE_PORT}/xe`
connectString: `localhost:${ORACLE_PORT}/xe`,
// connectString: `${sqlConfig.host}:${sqlConfig.port}/${sqlConfig.database}`,
}
},
};
} else if (sqlConfig.typeOfDatabase === 'mariadb') {
sqlConfig.typeOfDatabase = 'mysql2';
return {
client: sqlConfig.typeOfDatabase,
connection: sqlConfig
connection: sqlConfig,
};
} else if (sqlConfig.typeOfDatabase === 'cockroachdb') {
sqlConfig.typeOfDatabase = 'pg';
return {
client: sqlConfig.typeOfDatabase,
connection: sqlConfig
connection: sqlConfig,
};
} else {
return {
client: sqlConfig.typeOfDatabase,
connection: { ...sqlConfig }
connection: { ...sqlConfig },
};
}
}
@ -590,7 +589,7 @@ export default class SqlMgr {
config.connection = {};
config.meta = {
tn: 'nc_evolutions',
dbAlias: 'db'
dbAlias: 'db',
};
const urlParts = url.parse(dbUrl, true);
@ -630,9 +629,9 @@ export default class SqlMgr {
_noco: {
db: [],
apiClient: {
data: []
}
}
data: [],
},
},
},
workingEnv: '_noco',
meta: {
@ -642,7 +641,7 @@ export default class SqlMgr {
apisFolder: 'apis',
projectType: args.projectType || 'rest',
type: args.type || 'mvc',
language: args.language || 'ts'
language: args.language || 'ts',
},
version: '0.5',
seedsFolder: 'seeds',
@ -652,8 +651,8 @@ export default class SqlMgr {
type: args.type || 'mvc',
language: args.language || 'ts',
apiClient: {
data: []
}
data: [],
},
};
for (let i = 0; i < args.url.length; ++i) {
@ -690,7 +689,7 @@ export default class SqlMgr {
args.project = {
title: path.basename(path.dirname(args.folder)),
folder: args.folder,
type: 'mysql'
type: 'mysql',
};
args.projectJson = this._createProjectJsonFromDbUrls(args);
@ -805,7 +804,7 @@ export default class SqlMgr {
...sqlMigrationStatements.data.object,
folder: this.currentProjectFolder,
up: sqlMigrationFiles.up,
down: sqlMigrationFiles.down
down: sqlMigrationFiles.down,
});
// mark as migration done in nc_evolutions table
@ -818,7 +817,7 @@ export default class SqlMgr {
sqlContentMigrate: 0,
migrationSteps: 9999,
folder: this.currentProjectFolder,
sqlClient
sqlClient,
};
// console.log(`Migration up args for '${op}'`, migrationArgs);
await this.migrator().migrationsUp(migrationArgs);
@ -840,7 +839,7 @@ export default class SqlMgr {
url: `/api/v1/${tables[i].tn}`,
routeFunction: 'list',
tn: tables[i].tn,
enabled: true
enabled: true,
});
routes.push({
@ -848,7 +847,7 @@ export default class SqlMgr {
url: `/api/v1/${tables[i].tn}`,
routeFunction: 'create',
tn: tables[i].tn,
enabled: true
enabled: true,
});
routes.push({
@ -856,7 +855,7 @@ export default class SqlMgr {
url: `/api/v1/${tables[i].tn}/${id}`,
routeFunction: 'read',
tn: tables[i].tn,
enabled: true
enabled: true,
});
routes.push({
@ -864,7 +863,7 @@ export default class SqlMgr {
url: `/api/v1/${tables[i].tn}/${id}`,
routeFunction: 'update',
tn: tables[i].tn,
enabled: true
enabled: true,
});
routes.push({
@ -872,10 +871,10 @@ export default class SqlMgr {
url: `/api/v1/${tables[i].tn}/${id}`,
routeFunction: 'delete',
tn: tables[i].tn,
enabled: true
enabled: true,
});
const hasManyRelations = relations.filter(r => r.tn === tables[i].tn);
const hasManyRelations = relations.filter((r) => r.tn === tables[i].tn);
for (let j = 0; j < hasManyRelations.length; ++j) {
routes.push({
@ -884,7 +883,7 @@ export default class SqlMgr {
routeFunction: `${hasManyRelations[j].rtn}_has_many_${tables[i].tn}`,
tn: tables[i].tn,
relation: hasManyRelations[j].rtn,
enabled: true
enabled: true,
});
}
@ -896,7 +895,7 @@ export default class SqlMgr {
public getDbType({ env, dbAlias }) {
const db = this.currentProjectJson.envs[env].db.find(
db => db.meta.dbAlias === dbAlias
(db) => db.meta.dbAlias === dbAlias
);
return db.client;
}
@ -910,7 +909,7 @@ export default class SqlMgr {
const sqlClient = await this.projectGetSqlClient({
env: '_noco',
dbAlias: 'db'
dbAlias: 'db',
});
const usersTableExists = await sqlClient.hasTable({ tn: 'xc_users' });
@ -1019,8 +1018,8 @@ export default class SqlMgr {
response: {
...apiMeta.response,
// timeTaken: t2,
createdAt: Date.now()
}
createdAt: Date.now(),
},
};
}
@ -1070,7 +1069,7 @@ export default class SqlMgr {
return headersObj;
}, {})
: {},
withCredentials: true
withCredentials: true,
};
return req;
}
@ -1135,11 +1134,12 @@ export default class SqlMgr {
let result;
try {
const op = (args.sqlOpPlus &&
!process.env.NC_TRY &&
!('NC_MIGRATIONS_DISABLED' in process.env)
? this.sqlOpPlus
: this.sqlOp
const op = (
args.sqlOpPlus &&
!process.env.NC_TRY &&
!('NC_MIGRATIONS_DISABLED' in process.env)
? this.sqlOpPlus
: this.sqlOp
).bind(this);
switch (operation) {

6
packages/nocodb/src/lib/db/sql-mgr/code/BaseRender.ts

@ -41,7 +41,7 @@ class BaseRender {
this.log.api(data);
this.evt.evt.emit('UI', {
status: 0,
data: `File : ${data}`
data: `File : ${data}`,
});
}
@ -49,7 +49,7 @@ class BaseRender {
this.log.warn(data);
this.evt.evt.emit('UI', {
status: 1,
data: `File : ${data}`
data: `File : ${data}`,
});
}
@ -57,7 +57,7 @@ class BaseRender {
this.log.error(data);
this.evt.evt.emit('UI', {
status: -1,
data: `File : ${data}`
data: `File : ${data}`,
});
}

60
packages/nocodb/src/lib/db/sql-mgr/code/gql-policies/xc-ts/ExpressXcTsPolicyGql.ts

@ -33,68 +33,68 @@ class ExpressXcPolicyGql extends BaseRender {
[`${this.ctx.tn_camelize}Create`]: {
admin: true,
user: true,
guest: false
guest: false,
},
[`${this.ctx.tn_camelize}Update`]: {
admin: true,
user: true,
guest: false
guest: false,
},
[`${this.ctx.tn_camelize}Delete`]: {
admin: true,
user: true,
guest: false
guest: false,
},
[`${this.ctx.tn_camelize}Exists`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}FindOne`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}Count`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}Distinct`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}GroupBy`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}Aggregate`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}Distribution`]: {
admin: true,
user: true,
guest: true
guest: true,
},
[`${this.ctx.tn_camelize}CreateBulk`]: {
admin: true,
user: true,
guest: false
guest: false,
},
[`${this.ctx.tn_camelize}UpdateBulk`]: {
admin: true,
user: true,
guest: false
guest: false,
},
[`${this.ctx.tn_camelize}DeleteBulk`]: {
admin: true,
user: true,
guest: false
}
guest: false,
},
};
}
@ -107,7 +107,7 @@ async function(args, {req,res,next}){
return new req.gqlType(o);
});
}
`
`,
],
[`${this.ctx.tn_camelize}Read`]: [
`
@ -115,7 +115,7 @@ async function(args, {req,res,next}){
const data = await req.model.readByPk(args.id);
return new req.gqlType(data);
}
`
`,
],
[`${this.ctx.tn_camelize}Create`]: [
`
@ -123,7 +123,7 @@ async function(args, {req,res,next}){
const data = await req.model.insert(args.data);
return new req.gqlType(data);
}
`
`,
],
[`${this.ctx.tn_camelize}Update`]: [
`
@ -131,7 +131,7 @@ async function(args, {req,res,next}){
const data = await req.model.updateByPk(args.id, args.data);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}Delete`]: [
`
@ -139,7 +139,7 @@ async function(args, {req,res,next}){
const data = await req.model.delByPk(args.id);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}Exists`]: [
`
@ -147,7 +147,7 @@ async function(args, {req,res,next}){
const data = await req.model.exists(args.id);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}FindOne`]: [
`
@ -155,7 +155,7 @@ async function(args, {req,res,next}){
const data = await req.model.findOne(args);
return new req.gqlType(data);
}
`
`,
],
[`${this.ctx.tn_camelize}Count`]: [
`
@ -163,7 +163,7 @@ async function(args, {req,res,next}){
const data = await req.model.countByPk(args);
return data.count;
}
`
`,
],
[`${this.ctx.tn_camelize}Distinct`]: [
`
@ -171,7 +171,7 @@ async function(args, {req,res,next}){
const data = (await req.model.distinct(args)).map(d => new req.gqlType(d));
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}GroupBy`]: [
`
@ -179,7 +179,7 @@ async function(args, {req,res,next}){
const data = await req.model.groupBy(args);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}Aggregate`]: [
`
@ -187,7 +187,7 @@ async function(args, {req,res,next}){
const data = await req.model.aggregate(args);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}Distribution`]: [
`
@ -195,7 +195,7 @@ async function(args, {req,res,next}){
const data = await req.model.distribution(args);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}CreateBulk`]: [
`
@ -203,7 +203,7 @@ async function(args, {req,res,next}){
const data = await req.model.insertb(args.data);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}UpdateBulk`]: [
`
@ -211,7 +211,7 @@ async function(args, {req,res,next}){
const data = await req.model.updateb(args.data);
return data;
}
`
`,
],
[`${this.ctx.tn_camelize}DeleteBulk`]: [
`
@ -219,8 +219,8 @@ async function(args, {req,res,next}){
const data = await req.model.delb(args.data);
return data;
}
`
]
`,
],
};
}
}

6
packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/BaseGqlXcTsSchema.ts

@ -26,7 +26,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
data.columns = {
func: this._renderColumns.bind(this),
args: this.ctx
args: this.ctx,
};
return data;
@ -142,7 +142,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
let hasManyRelations = args.hasMany;
if (hasManyRelations.length > 1) {
hasManyRelations = lodash.uniqBy(hasManyRelations, e => {
hasManyRelations = lodash.uniqBy(hasManyRelations, (e) => {
return [e.tn, e.rtn].join();
});
}
@ -161,7 +161,7 @@ abstract class BaseGqlXcTsSchema extends BaseRender {
let belongsToRelations = args.belongsTo;
if (belongsToRelations.length > 1) {
belongsToRelations = lodash.uniqBy(belongsToRelations, e => {
belongsToRelations = lodash.uniqBy(belongsToRelations, (e) => {
return [e.tn, e.rtn].join();
});
}

4
packages/nocodb/src/lib/db/sql-mgr/code/gql-schema/xc-ts/schemaHelp.ts

@ -3,11 +3,11 @@ const AGG_DEFAULT_COLS = {
avg: `\t\tavg: Float,\r\n`,
min: `\t\tmin: Float,\r\n`,
max: `\t\tmax: Int,\r\n`,
sum: `\t\tsum: Float\r\n`
sum: `\t\tsum: Float\r\n`,
};
const GROUPBY_DEFAULT_COLS = {
count: `\t\tcount: Int,\r\n`
count: `\t\tcount: Int,\r\n`,
};
export { AGG_DEFAULT_COLS, GROUPBY_DEFAULT_COLS };

20
packages/nocodb/src/lib/db/sql-mgr/code/models/xc/BaseModelXcMeta.ts

@ -11,14 +11,14 @@ abstract class BaseModelXcMeta extends BaseRender {
const columnsArr = [];
for (const column of args.columns) {
if (this.ctx?.belongsTo?.find(c => c.cn === column.cn))
if (this.ctx?.belongsTo?.find((c) => c.cn === column.cn))
column.uidt = UITypes.ForeignKey;
const columnObj = {
validate: {
func: [],
args: [],
msg: []
msg: [],
},
column_name: column.cn || column.column_name,
title: column._cn || column.cn || column.column_name || column.title,
@ -28,7 +28,7 @@ abstract class BaseModelXcMeta extends BaseRender {
uidt: column.uidt || this.getUIDataType(column),
uip: column.uip,
uicn: column.uicn,
...column
...column,
};
if (column.rqd) {
@ -60,7 +60,7 @@ abstract class BaseModelXcMeta extends BaseRender {
columnObj.dtxs = column.dtxs;
}
const oldColMeta = this.ctx?.oldMeta?.columns?.find(c => {
const oldColMeta = this.ctx?.oldMeta?.columns?.find((c) => {
return columnObj.cn == c.cn && columnObj.type == c.type;
});
@ -94,27 +94,27 @@ abstract class BaseModelXcMeta extends BaseRender {
db_type: this.ctx.db_type,
type: this.ctx.type,
v: this.getVitualColumns()
v: this.getVitualColumns(),
};
}
public getVitualColumns(): any[] {
// todo: handle duplicate relation
const virtualColumns = [
...(this.ctx.hasMany || []).map(hm => {
...(this.ctx.hasMany || []).map((hm) => {
return {
uidt: UITypes.LinkToAnotherRecord,
type: 'hm',
hm,
_cn: `${hm._tn}List`
_cn: `${hm._tn}List`,
};
}),
...(this.ctx.belongsTo || []).map(bt => ({
...(this.ctx.belongsTo || []).map((bt) => ({
uidt: UITypes.LinkToAnotherRecord,
type: 'bt',
bt,
_cn: `${bt._rtn}Read`
}))
_cn: `${bt._rtn}Read`,
})),
];
const oldVirtualCols = this.ctx?.oldMeta?.v || [];

12
packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaMssql.ts

@ -29,8 +29,8 @@ class ModelXcMetaMssql extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -39,8 +39,8 @@ class ModelXcMetaMssql extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
hasMany: this.ctx.hasMany
}
hasMany: this.ctx.hasMany,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -49,8 +49,8 @@ class ModelXcMetaMssql extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
belongsTo: this.ctx.belongsTo
}
belongsTo: this.ctx.belongsTo,
},
};
return data;

12
packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaMysql.ts

@ -29,8 +29,8 @@ class ModelXcMetaMysql extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -39,8 +39,8 @@ class ModelXcMetaMysql extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
hasMany: this.ctx.hasMany
}
hasMany: this.ctx.hasMany,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -50,8 +50,8 @@ class ModelXcMetaMysql extends BaseModelXcMeta {
dbType: this.ctx.dbType,
tn: this.ctx.tn,
columns: this.ctx.columns,
belongsTo: this.ctx.belongsTo
}
belongsTo: this.ctx.belongsTo,
},
};
return data;

12
packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaOracle.ts

@ -29,8 +29,8 @@ class ModelXcMetaOracle extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -39,8 +39,8 @@ class ModelXcMetaOracle extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
hasMany: this.ctx.hasMany
}
hasMany: this.ctx.hasMany,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -50,8 +50,8 @@ class ModelXcMetaOracle extends BaseModelXcMeta {
dbType: this.ctx.dbType,
tn: this.ctx.tn,
columns: this.ctx.columns,
belongsTo: this.ctx.belongsTo
}
belongsTo: this.ctx.belongsTo,
},
};
return data;

12
packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaPg.ts

@ -29,8 +29,8 @@ class ModelXcMetaPg extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -39,8 +39,8 @@ class ModelXcMetaPg extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
hasMany: this.ctx.hasMany
}
hasMany: this.ctx.hasMany,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -49,8 +49,8 @@ class ModelXcMetaPg extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
belongsTo: this.ctx.belongsTo
}
belongsTo: this.ctx.belongsTo,
},
};
return data;

12
packages/nocodb/src/lib/db/sql-mgr/code/models/xc/ModelXcMetaSqlite.ts

@ -29,8 +29,8 @@ class ModelXcMetaSqlite extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -39,8 +39,8 @@ class ModelXcMetaSqlite extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
hasMany: this.ctx.hasMany
}
hasMany: this.ctx.hasMany,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -49,8 +49,8 @@ class ModelXcMetaSqlite extends BaseModelXcMeta {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
belongsTo: this.ctx.belongsTo
}
belongsTo: this.ctx.belongsTo,
},
};
return data;

38
packages/nocodb/src/lib/db/sql-mgr/code/policies/xc/ExpressXcPolicy.ts

@ -34,8 +34,8 @@ class ExpressXcMiddleware extends BaseRender {
columns: this.ctx.columns,
hasMany: this.ctx.hasMany,
relations: this.ctx.relations,
routeVersionLetter: this.ctx.routeVersionLetter
}
routeVersionLetter: this.ctx.routeVersionLetter,
},
};
/* for complex code provide a func and args - do derivation within the func cbk */
@ -47,8 +47,8 @@ class ExpressXcMiddleware extends BaseRender {
columns: this.ctx.columns,
belongsTo: this.ctx.belongsTo,
relations: this.ctx.relations,
routeVersionLetter: this.ctx.routeVersionLetter
}
routeVersionLetter: this.ctx.routeVersionLetter,
},
};
return data;
@ -57,10 +57,10 @@ class ExpressXcMiddleware extends BaseRender {
private _renderXcHasManyRoutePermissions(args) {
let str = '';
let hmRelations = args.relations
? args.relations.filter(r => r.rtn === args.tn)
? args.relations.filter((r) => r.rtn === args.tn)
: [];
if (hmRelations.length > 1)
hmRelations = lodash.uniqBy(hmRelations, function(e) {
hmRelations = lodash.uniqBy(hmRelations, function (e) {
return [e.tn, e.rtn].join();
});
for (let i = 0; i < hmRelations.length; ++i) {
@ -83,10 +83,10 @@ class ExpressXcMiddleware extends BaseRender {
let str = '';
//
let btRelations = args.relations
? args.relations.filter(r => r.tn === args.tn)
? args.relations.filter((r) => r.tn === args.tn)
: [];
if (btRelations.length > 1)
btRelations = lodash.uniqBy(btRelations, function(e) {
btRelations = lodash.uniqBy(btRelations, function (e) {
return [e.tn, e.rtn].join();
});
for (let i = 0; i < btRelations.length; ++i) {
@ -103,9 +103,9 @@ class ExpressXcMiddleware extends BaseRender {
? {
create: true,
update: true,
delete: true
delete: true,
}
: {})
: {}),
},
editor: {
read: true,
@ -113,9 +113,9 @@ class ExpressXcMiddleware extends BaseRender {
? {
create: true,
update: true,
delete: true
delete: true,
}
: {})
: {}),
},
commenter: {
read: true,
@ -123,9 +123,9 @@ class ExpressXcMiddleware extends BaseRender {
? {
create: false,
update: false,
delete: false
delete: false,
}
: {})
: {}),
},
viewer: {
read: true,
@ -133,9 +133,9 @@ class ExpressXcMiddleware extends BaseRender {
? {
create: false,
update: false,
delete: false
delete: false,
}
: {})
: {}),
},
guest: {
read: false,
@ -143,10 +143,10 @@ class ExpressXcMiddleware extends BaseRender {
? {
create: false,
update: false,
delete: false
delete: false,
}
: {})
}
: {}),
},
};
}
}

1314
packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXc.ts

File diff suppressed because it is too large Load Diff

39
packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXcBt.ts

@ -28,8 +28,8 @@ class SwaggerXcBt extends BaseRender {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
return data;
@ -54,8 +54,8 @@ class SwaggerXcBt extends BaseRender {
tags: [
{
name: `${this.ctx._tn}BelongsTo${this.ctx._rtn || this.ctx.rtn}`,
description: 'Everything about belongs to relation'
}
description: 'Everything about belongs to relation',
},
],
paths: {
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${
@ -63,8 +63,9 @@ class SwaggerXcBt extends BaseRender {
}/belongs/${this.ctx._rtn || this.ctx.rtn}`]: {
get: {
tags: [`${this.ctx._tn}BelongsTo${this.ctx._rtn || this.ctx.rtn}`],
summary: `Get ${this.ctx._tn} list with ${this.ctx._rtn ||
this.ctx.rtn} parent`,
summary: `Get ${this.ctx._tn} list with ${
this.ctx._rtn || this.ctx.rtn
} parent`,
description: '',
operationId: `${this.ctx._tn}WithParent`,
produces: ['application/json'],
@ -73,28 +74,28 @@ class SwaggerXcBt extends BaseRender {
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression'
description: 'Where expression',
},
{
in: 'query',
name: 'limit',
description: 'Page size limit',
type: 'integer',
format: 'int64'
format: 'int64',
},
{
in: 'query',
name: 'offset',
description: 'Pagination offset',
type: 'integer',
format: 'int64'
format: 'int64',
},
{
in: 'query',
name: 'sort',
description: 'Sort parameter',
type: 'string'
}
type: 'string',
},
],
responses: {
'200': {
@ -102,15 +103,15 @@ class SwaggerXcBt extends BaseRender {
schema: {
type: 'array',
items: {
type: 'object'
}
}
}
}
}
}
type: 'object',
},
},
},
},
},
},
},
definitions: {}
definitions: {},
};
}
}

814
packages/nocodb/src/lib/db/sql-mgr/code/routers/xc-ts/SwaggerXcHm.ts

@ -28,8 +28,8 @@ class SwaggerXcHm extends BaseRender {
args: {
tn: this.ctx.tn,
columns: this.ctx.columns,
relations: this.ctx.relations
}
relations: this.ctx.relations,
},
};
return data;
@ -54,423 +54,429 @@ class SwaggerXcHm extends BaseRender {
tags: [
{
name: `${this.ctx._tn}HasMany${this.ctx._ctn}`,
description: 'Everything about has many relation'
}
description: 'Everything about has many relation',
},
],
paths: {
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/has/${this.ctx._ctn}`]: {
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Get ${this.ctx._tn} list with ${this.ctx._ctn} children`,
description: '',
operationId: `${this.ctx._tn}HasMany${this.ctx._ctn}List`,
produces: ['application/json'],
parameters: [
{
in: 'query',
name: 'fields',
type: 'String',
description: 'Comma separated fields of model'
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression'
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'array',
items: {
type: 'object'
}
}
}
}
}
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}`]: {
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Find ${this.ctx._ctn} list by parent ${this.ctx._tn} id`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `get${this.ctx._ctn}By${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of ${this.ctx._tn} to return`,
required: true,
type: 'integer',
format: 'int64'
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/has/${this.ctx._ctn}`]:
{
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Get ${this.ctx._tn} list with ${this.ctx._ctn} children`,
description: '',
operationId: `${this.ctx._tn}HasMany${this.ctx._ctn}List`,
produces: ['application/json'],
parameters: [
{
in: 'query',
name: 'fields',
type: 'String',
description: 'Comma separated fields of model',
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression',
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'array',
items: {
type: 'object',
},
},
},
},
{
in: 'query',
name: 'fields',
type: 'String',
description: 'Comma separated fields of model'
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression'
},
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}`]:
{
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Find ${this.ctx._ctn} list by parent ${this.ctx._tn} id`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `get${this.ctx._ctn}By${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of ${this.ctx._tn} to return`,
required: true,
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'fields',
type: 'String',
description: 'Comma separated fields of model',
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression',
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'array',
items: 'object',
},
},
'400': {
description: 'Invalid ID supplied',
},
'404': {
description: `${this.ctx._tn} not found`,
},
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64'
},
post: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Insert ${this.ctx._ctn} under a parent ${this.ctx._tn}`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `insert${this.ctx._ctn}By${this.ctx._tn}Id`,
consumes: ['application/json'],
produces: ['application/json'],
parameters: [
{
in: 'body',
name: 'body',
description: `${this.ctx._ctn} object to insert`,
required: true,
schema: {
type: 'object',
},
},
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of ${this.ctx._tn} to return`,
required: true,
type: 'integer',
format: 'int64',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object',
},
},
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64'
},
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/{${this.ctx._ctn}Id}`]:
{
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Get by ${this.ctx._ctn} id parent ${this.ctx._tn} id`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `get${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64',
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of ${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'array',
items: 'object',
},
},
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'array',
items: 'object'
}
},
delete: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Delete by ${this.ctx._ctn} id parent ${this.ctx._tn} id`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `delete${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64',
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of c${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64',
},
],
responses: {
'200': {
description: 'successful operation',
},
},
'400': {
description: 'Invalid ID supplied'
},
put: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Update ${this.ctx._ctn} under a parent ${this.ctx._tn}`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `update${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
consumes: ['application/json'],
produces: ['application/json'],
parameters: [
{
in: 'body',
name: 'body',
description: `${this.ctx._ctn} object to insert`,
required: true,
schema: {
type: 'object',
},
},
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of ${this.ctx._tn} to return`,
required: true,
type: 'integer',
format: 'int64',
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of ${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object',
},
},
},
'404': {
description: `${this.ctx._tn} not found`
}
}
},
},
post: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Insert ${this.ctx._ctn} under a parent ${this.ctx._tn}`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `insert${this.ctx._ctn}By${this.ctx._tn}Id`,
consumes: ['application/json'],
produces: ['application/json'],
parameters: [
{
in: 'body',
name: 'body',
description: `${this.ctx._ctn} object to insert`,
required: true,
schema: {
type: 'object'
}
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/{${this.ctx._ctn}Id}/exists`]:
{
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Check row exists by ${this.ctx._ctn} id and parent ${this.ctx._tn} id`,
description: '',
operationId: `exists${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64',
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of ${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'boolean',
},
},
},
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of ${this.ctx._tn} to return`,
required: true,
type: 'integer',
format: 'int64'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object'
}
}
}
}
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/{${this.ctx._ctn}Id}`]: {
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Get by ${this.ctx._ctn} id parent ${this.ctx._tn} id`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `get${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64'
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of ${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'array',
items: 'object'
}
}
}
},
},
delete: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Delete by ${this.ctx._ctn} id parent ${this.ctx._tn} id`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `delete${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64'
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/findOne`]:
{
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Find one ${this.ctx._ctn} by parent ${this.ctx._tn} id and filters`,
description: '',
operationId: `findOne${this.ctx._ctn}By${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'fields',
type: 'String',
description: 'Comma separated fields of model',
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression',
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object',
},
},
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of c${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64'
}
],
responses: {
'200': {
description: 'successful operation'
}
}
},
},
put: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Update ${this.ctx._ctn} under a parent ${this.ctx._tn}`,
description: `Returns a single ${this.ctx._tn}`,
operationId: `update${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
consumes: ['application/json'],
produces: ['application/json'],
parameters: [
{
in: 'body',
name: 'body',
description: `${this.ctx._ctn} object to insert`,
required: true,
schema: {
type: 'object'
}
},
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of ${this.ctx._tn} to return`,
required: true,
type: 'integer',
format: 'int64'
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/count`]:
{
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Get ${this.ctx._ctn} count by parent id and filter`,
description: '',
operationId: `getCountWithin${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression',
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64',
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string',
},
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object',
},
},
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of ${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object'
}
}
}
}
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/{${this.ctx._ctn}Id}/exists`]: {
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Check row exists by ${this.ctx._ctn} id and parent ${this.ctx._tn} id`,
description: '',
operationId: `exists${this.ctx._ctn}ByIdAnd${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64'
},
{
name: `${this.ctx._ctn}Id`,
in: 'path',
description: `ID of ${this.ctx._ctn}`,
required: true,
type: 'integer',
format: 'int64'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'boolean'
}
}
}
}
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/findOne`]: {
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Find one ${this.ctx._ctn} by parent ${this.ctx._tn} id and filters`,
description: '',
operationId: `findOne${this.ctx._ctn}By${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'fields',
type: 'String',
description: 'Comma separated fields of model'
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression'
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object'
}
}
}
}
},
[`/nc/${this.ctx.project_id}/api/${this.ctx.routeVersionLetter}/${this.ctx._tn}/{${this.ctx._tn}Id}/${this.ctx._ctn}/count`]: {
get: {
tags: [`${this.ctx._tn}HasMany${this.ctx._ctn}`],
summary: `Get ${this.ctx._ctn} count by parent id and filter`,
description: '',
operationId: `getCountWithin${this.ctx._tn}Id`,
produces: ['application/json'],
parameters: [
{
name: `${this.ctx._tn}Id`,
in: 'path',
description: `ID of parent ${this.ctx._tn}`,
required: true,
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'where',
type: 'String',
description: 'Where expression'
},
{
in: 'query',
name: 'limit',
description: 'page size limit',
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'offset',
description: 'pagination offset',
type: 'integer',
format: 'int64'
},
{
in: 'query',
name: 'sort',
description: 'sort parameter',
type: 'string'
}
],
responses: {
'200': {
description: 'successful operation',
schema: {
type: 'object'
}
}
}
}
}
},
},
},
definitions: {}
definitions: {},
};
}
}

104
packages/nocodb/src/lib/db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutes.ts

@ -36,7 +36,7 @@ class ExpressXcTsRoutes extends BaseRender {
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -44,8 +44,8 @@ async function(req, res){
const data = await req.model.list(req.query);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/findOne`,
@ -54,7 +54,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -62,8 +62,8 @@ async function(req, res){
const data = await req.model.findOne(req.query);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/m2mNotChildren/:assoc/:pid`,
@ -72,12 +72,12 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/groupby/:column_name`,
@ -86,7 +86,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -97,8 +97,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/count`,
@ -107,7 +107,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -117,8 +117,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/bulk`,
@ -127,7 +127,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -135,8 +135,8 @@ async function(req, res){
const data = await req.model.insertb(req.body);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/bulk`,
@ -145,7 +145,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -153,8 +153,8 @@ async function(req, res){
const data = await req.model.updateb(req.body);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/bulk`,
@ -163,7 +163,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -171,8 +171,8 @@ async function(req, res){
const data = await req.model.delb(req.body)
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/:id/exists`,
@ -181,7 +181,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -189,8 +189,8 @@ async function(req, res){
const data = await req.model.exists(req.params.id);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/distinct`,
@ -199,7 +199,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -209,8 +209,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/distribute`,
@ -219,7 +219,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -229,8 +229,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/aggregate`,
@ -239,7 +239,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -250,8 +250,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/groupby`,
@ -260,7 +260,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -271,8 +271,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/:id`,
@ -281,7 +281,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -289,8 +289,8 @@ async function(req, res){
const data = await req.model.readByPk(req.params.id);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}`,
@ -299,7 +299,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -307,8 +307,8 @@ async function(req, res){
const data = await req.model.insert(req.body, null, req);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/:id`,
@ -317,7 +317,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -325,8 +325,8 @@ async function(req, res){
const data = await req.model.updateByPk(req.params.id, req.body, null, req);
res.json(data);
}
`
]
`,
],
},
{
path: `/api/${this.ctx.routeVersionLetter}/${ejsData._tn}/:id`,
@ -335,7 +335,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -343,9 +343,9 @@ async function(req, res){
const data = await req.model.delByPk(req.params.id, null, req);
res.json(data);
}
`
]
}
`,
],
},
];
if (this.ctx.type === 'view') {

8
packages/nocodb/src/lib/db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutesBt.ts

@ -36,7 +36,7 @@ class ExpressXcTsRoutesBt extends BaseRender {
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -47,9 +47,9 @@ async function(req, res){
});
res.json(data);
}
`
]
}
`,
],
},
];
}

56
packages/nocodb/src/lib/db/sql-mgr/code/routes/xc-ts/ExpressXcTsRoutesHm.ts

@ -36,7 +36,7 @@ class ExpressXcTsRoutesHm extends BaseRender {
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -47,8 +47,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}`,
@ -57,7 +57,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -69,8 +69,8 @@ async function(req, res){
})
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}`,
@ -79,7 +79,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -91,8 +91,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}/findOne`,
@ -101,7 +101,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -113,8 +113,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}/count`,
@ -123,7 +123,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -135,8 +135,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}/:id`,
@ -145,7 +145,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -157,8 +157,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}/:id`,
@ -167,7 +167,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -180,8 +180,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}/:id`,
@ -190,7 +190,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: false
guest: false,
},
functions: [
`
@ -202,8 +202,8 @@ async function(req, res){
});
res.json(data);
}
`
]
`,
],
},
{
path: `/api/v1/${ejsData._tn}/:parentId/${ejsData._ctn}/:id/exists`,
@ -212,7 +212,7 @@ async function(req, res){
acl: {
admin: true,
user: true,
guest: true
guest: true,
},
functions: [
`
@ -225,9 +225,9 @@ async function(req, res){
});
res.json(data);
}
`
]
}
`,
],
},
];
}

72
packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigrator.ts

@ -48,7 +48,7 @@ export default class KnexMigrator extends SqlMigrator {
log.api(data);
evt.evt.emit('UI', {
status: 0,
data: `Migrator : ${data}`
data: `Migrator : ${data}`,
});
}
@ -56,7 +56,7 @@ export default class KnexMigrator extends SqlMigrator {
log.warn(data);
evt.evt.emit('UI', {
status: 1,
data
data,
});
}
@ -64,7 +64,7 @@ export default class KnexMigrator extends SqlMigrator {
log.error(data);
evt.evt.emit('UI', {
status: -1,
data
data,
});
}
@ -94,7 +94,7 @@ export default class KnexMigrator extends SqlMigrator {
for (let i = 0; i < envs[workingEnv].db.length; ++i) {
const { dbAlias } = envs[workingEnv].db[i].meta;
await this._initDbOnFs({
dbAlias
dbAlias,
});
}
}
@ -109,7 +109,7 @@ export default class KnexMigrator extends SqlMigrator {
const { dbAlias } = envs[toCleanEnv].db[i].meta;
await this._cleanFs({
dbAlias
dbAlias,
});
}
}
@ -387,21 +387,21 @@ export default class KnexMigrator extends SqlMigrator {
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.user}`
);
await sqlClient.createDatabaseIfNotExists({
database: connectionConfig.connection.user
database: connectionConfig.connection.user,
});
} else if (connectionConfig.client !== 'sqlite3') {
this.emit(
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.database}`
);
await sqlClient.createDatabaseIfNotExists({
database: connectionConfig.connection.database
database: connectionConfig.connection.database,
});
} else {
this.emit(
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.connection.filename}`
);
await sqlClient.createDatabaseIfNotExists({
database: connectionConfig.connection.connection.filename
database: connectionConfig.connection.connection.filename,
});
}
@ -409,7 +409,7 @@ export default class KnexMigrator extends SqlMigrator {
if (!('NC_MIGRATIONS_DISABLED' in process.env)) {
await sqlClient.createTableIfNotExists({
tn: connectionConfig.meta.tn
tn: connectionConfig.meta.tn,
});
}
// if (connectionConfig.client === "pg") {
@ -431,19 +431,19 @@ export default class KnexMigrator extends SqlMigrator {
if (connectionConfig.client === 'oracledb') {
this.emit(`Dropping DB : ${connectionConfig.connection.user}`);
await sqlClient.dropDatabase({
database: connectionConfig.connection.user
database: connectionConfig.connection.user,
});
} else if (connectionConfig.client === 'sqlite3') {
this.emit(
`Dropping DB : ${connectionConfig.connection.connection.filename}`
);
await sqlClient.dropDatabase({
database: connectionConfig.connection.connection.filename
database: connectionConfig.connection.connection.filename,
});
} else {
this.emit(`Dropping DB : ${connectionConfig.connection.database}`);
await sqlClient.dropDatabase({
database: connectionConfig.connection.database
database: connectionConfig.connection.database,
});
}
@ -554,7 +554,7 @@ export default class KnexMigrator extends SqlMigrator {
filesDown = files = await this.metaDb('nc_migrations')
.where({
project_id: this.project_id,
db_alias: args.dbAlias
db_alias: args.dbAlias,
})
.orderBy('id', 'asc');
} else {
@ -574,7 +574,7 @@ export default class KnexMigrator extends SqlMigrator {
);
if (this.suffix) {
migrations = migrations.filter(m => m.title.includes(this.suffix));
migrations = migrations.filter((m) => m.title.includes(this.suffix));
}
/** ************** END : get files and migrations *************** */
@ -587,16 +587,16 @@ export default class KnexMigrator extends SqlMigrator {
result.data.object.list.push({
title: migrations[i].title,
titleDown: migrations[i].titleDown,
status: false
status: false,
});
}
result.data.object.pending = files.length - migrations.length;
} else if (files.length > migrations.length || onlyList) {
this.emit(
`Number of evolutions pending for '${args.env}:${
args.dbAlias
}': '${files.length - migrations.length}'`
`Number of evolutions pending for '${args.env}:${args.dbAlias}': '${
files.length - migrations.length
}'`
);
result.data.object.pending = files.length - migrations.length;
@ -659,7 +659,7 @@ export default class KnexMigrator extends SqlMigrator {
result.data.object.list.push({
title: files[i].title,
titleDown: filesDown[i].title_down,
status: false
status: false,
});
}
} else {
@ -669,7 +669,7 @@ export default class KnexMigrator extends SqlMigrator {
result.data.object.list.push({
title: fileParts[fileParts.length - 1],
titleDown: downFileParts[fileParts.length - 1],
status: false
status: false,
});
}
}
@ -704,7 +704,7 @@ export default class KnexMigrator extends SqlMigrator {
result.data.object.list.push({
title: fileName,
titleDown: fileNameDown,
status: true
status: true,
});
} else {
let upStatement;
@ -718,7 +718,7 @@ export default class KnexMigrator extends SqlMigrator {
upStatements.push(
...upStatement
.split(/\/\*\s*xc[\s\S]*?\s*\*\//)
.filter(s => s.trim())
.filter((s) => s.trim())
);
}
@ -726,7 +726,7 @@ export default class KnexMigrator extends SqlMigrator {
title: fileName,
titleDown: fileNameDown,
// description: files[i],
status: 0
status: 0,
// created: Date.now()
});
}
@ -808,7 +808,7 @@ export default class KnexMigrator extends SqlMigrator {
files = await this.metaDb('nc_migrations')
.where({
project_id: this.project_id,
db_alias: args.dbAlias
db_alias: args.dbAlias,
})
.orderBy('title', 'asc');
} else {
@ -879,11 +879,11 @@ export default class KnexMigrator extends SqlMigrator {
downStatements.push(
...downStatement
.split(/\/\*\s*xc[\s\S]*?\s*\*\//)
.filter(s => s.trim())
.filter((s) => s.trim())
);
metaDownDeletes.push({
titleDown: fileName
titleDown: fileName,
});
}
}
@ -1057,7 +1057,7 @@ export default class KnexMigrator extends SqlMigrator {
up: '',
down: '',
title: upFileName,
title_down: downFileName
title_down: downFileName,
});
} else {
// create files
@ -1079,7 +1079,7 @@ export default class KnexMigrator extends SqlMigrator {
return {
up: upFileName,
down: downFileName
down: downFileName,
};
} catch (e) {
log.debug(e);
@ -1176,7 +1176,7 @@ export default class KnexMigrator extends SqlMigrator {
),
tn: this._getEvolutionsTablename(args), //`${this.toolDir}`,
sqlContentMigrate: args.sqlContentMigrate,
sqlClient: args.sqlClient
sqlClient: args.sqlClient,
});
}
@ -1230,7 +1230,7 @@ export default class KnexMigrator extends SqlMigrator {
'*.down.sql'
),
tn: this._getEvolutionsTablename(args), //`_evolutions`,
sqlContentMigrate: args.sqlContentMigrate
sqlContentMigrate: args.sqlContentMigrate,
});
}
@ -1281,19 +1281,19 @@ export default class KnexMigrator extends SqlMigrator {
.where({
project_id: this.project_id,
db_alias: args.dbAlias,
title: args.up
title: args.up,
})
.first()
) {
await this.metaDb('nc_migrations')
.update({
up: upStatement,
down: downStatement
down: downStatement,
})
.where({
project_id: this.project_id,
db_alias: args.dbAlias,
title: args.up
title: args.up,
});
} else {
await this.metaDb('nc_migrations').insert({
@ -1302,7 +1302,7 @@ export default class KnexMigrator extends SqlMigrator {
up: upStatement,
down: downStatement,
title: args.up,
title_down: args.down
title_down: args.down,
});
}
} else {
@ -1365,7 +1365,7 @@ export default class KnexMigrator extends SqlMigrator {
try {
result.data.object = {
up: '',
down: ''
down: '',
};
// if (!this.project) {
@ -1380,7 +1380,7 @@ export default class KnexMigrator extends SqlMigrator {
.where({
db_alias: args.dbAlias,
project_id: this.project.id,
title: args.title
title: args.title,
})
.first();

68
packages/nocodb/src/lib/db/sql-migrator/lib/KnexMigratorv2.ts

@ -53,7 +53,7 @@ export default class KnexMigratorv2 {
log.api(data);
evt.evt.emit('UI', {
status: 0,
data: `Migrator : ${data}`
data: `Migrator : ${data}`,
});
}
@ -61,7 +61,7 @@ export default class KnexMigratorv2 {
log.warn(data);
evt.evt.emit('UI', {
status: 1,
data
data,
});
}
@ -69,7 +69,7 @@ export default class KnexMigratorv2 {
log.error(data);
evt.evt.emit('UI', {
status: -1,
data
data,
});
}
@ -389,21 +389,21 @@ export default class KnexMigratorv2 {
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.user}`
);
await sqlClient.createDatabaseIfNotExists({
database: connectionConfig.connection.user
database: connectionConfig.connection.user,
});
} else if (connectionConfig.client !== 'sqlite3') {
this.emit(
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.database}`
);
await sqlClient.createDatabaseIfNotExists({
database: connectionConfig.connection.database
database: connectionConfig.connection.database,
});
} else {
this.emit(
`${connectionConfig.client}: Creating DB if not exists ${connectionConfig.connection.connection.filename}`
);
await sqlClient.createDatabaseIfNotExists({
database: connectionConfig.connection.connection.filename
database: connectionConfig.connection.connection.filename,
});
}
@ -411,7 +411,7 @@ export default class KnexMigratorv2 {
if (!('NC_MIGRATIONS_DISABLED' in process.env)) {
await sqlClient.createTableIfNotExists({
tn: 'nc_evolutions'
tn: 'nc_evolutions',
});
}
// if (connectionConfig.client === "pg") {
@ -437,19 +437,19 @@ export default class KnexMigratorv2 {
if (connectionConfig.client === 'oracledb') {
this.emit(`Dropping DB : ${connectionConfig.connection.user}`);
await sqlClient.dropDatabase({
database: connectionConfig.connection.user
database: connectionConfig.connection.user,
});
} else if (connectionConfig.client === 'sqlite3') {
this.emit(
`Dropping DB : ${connectionConfig.connection.connection.filename}`
);
await sqlClient.dropDatabase({
database: connectionConfig.connection.connection.filename
database: connectionConfig.connection.connection.filename,
});
} else {
this.emit(`Dropping DB : ${connectionConfig.connection.database}`);
await sqlClient.dropDatabase({
database: connectionConfig.connection.database
database: connectionConfig.connection.database,
});
}
@ -571,7 +571,7 @@ export default class KnexMigratorv2 {
filesDown = files = await this.metaDb(NC_MIGRATION)
.where({
project_id: this.projectId,
db_alias: base.id
db_alias: base.id,
})
.orderBy('id', 'asc');
} else {
@ -592,7 +592,7 @@ export default class KnexMigratorv2 {
);
if (this.suffix) {
migrations = migrations.filter(m => m.title.includes(this.suffix));
migrations = migrations.filter((m) => m.title.includes(this.suffix));
}
/** ************** END : get files and migrations *************** */
@ -603,16 +603,16 @@ export default class KnexMigratorv2 {
result.data.object.list.push({
title: migrations[i].title,
titleDown: migrations[i].titleDown,
status: false
status: false,
});
}
result.data.object.pending = files.length - migrations.length;
} else if (files.length > migrations.length || onlyList) {
this.emit(
`Number of evolutions pending for '${'env'}:${
base.alias
}': '${files.length - migrations.length}'`
`Number of evolutions pending for '${'env'}:${base.alias}': '${
files.length - migrations.length
}'`
);
result.data.object.pending = files.length - migrations.length;
@ -675,7 +675,7 @@ export default class KnexMigratorv2 {
result.data.object.list.push({
title: files[i].title,
titleDown: filesDown[i].title_down,
status: false
status: false,
});
}
} else {
@ -685,7 +685,7 @@ export default class KnexMigratorv2 {
result.data.object.list.push({
title: fileParts[fileParts.length - 1],
titleDown: downFileParts[fileParts.length - 1],
status: false
status: false,
});
}
}
@ -720,7 +720,7 @@ export default class KnexMigratorv2 {
result.data.object.list.push({
title: fileName,
titleDown: fileNameDown,
status: true
status: true,
});
} else {
let upStatement;
@ -734,7 +734,7 @@ export default class KnexMigratorv2 {
upStatements.push(
...upStatement
.split(/\/\*\s*xc[\s\S]*?\s*\*\//)
.filter(s => s.trim())
.filter((s) => s.trim())
);
}
@ -742,7 +742,7 @@ export default class KnexMigratorv2 {
title: fileName,
titleDown: fileNameDown,
// description: files[i],
status: 0
status: 0,
// created: Date.now()
});
}
@ -837,7 +837,7 @@ export default class KnexMigratorv2 {
files = await this.metaDb(NC_MIGRATION)
.where({
project_id: this.projectId,
db_alias: base.id
db_alias: base.id,
})
.orderBy('title', 'asc');
} else {
@ -908,11 +908,11 @@ export default class KnexMigratorv2 {
downStatements.push(
...downStatement
.split(/\/\*\s*xc[\s\S]*?\s*\*\//)
.filter(s => s.trim())
.filter((s) => s.trim())
);
metaDownDeletes.push({
titleDown: fileName
titleDown: fileName,
});
}
}
@ -1085,7 +1085,7 @@ export default class KnexMigratorv2 {
up: '',
down: '',
title: upFileName,
title_down: downFileName
title_down: downFileName,
});
// } else {
@ -1108,7 +1108,7 @@ export default class KnexMigratorv2 {
return {
up: upFileName,
down: downFileName
down: downFileName,
};
} catch (e) {
log.debug(e);
@ -1216,7 +1216,7 @@ export default class KnexMigratorv2 {
// ),
title: `${this.toolDir}`,
sqlContentMigrate: args.sqlContentMigrate,
sqlClient: args.sqlClient
sqlClient: args.sqlClient,
});
}
@ -1281,7 +1281,7 @@ export default class KnexMigratorv2 {
// '*.down.sql'
// ),
title: `nc_evolutions`,
sqlContentMigrate: args.sqlContentMigrate
sqlContentMigrate: args.sqlContentMigrate,
});
}
@ -1341,19 +1341,19 @@ export default class KnexMigratorv2 {
.where({
project_id: base.project_id,
db_alias: base.id,
title: args.up
title: args.up,
})
.first()
) {
await this.metaDb(NC_MIGRATION)
.update({
up: upStatement,
down: downStatement
down: downStatement,
})
.where({
project_id: this.projectId,
db_alias: base.id,
title: args.up
title: args.up,
});
} else {
await this.metaDb(NC_MIGRATION).insert({
@ -1362,7 +1362,7 @@ export default class KnexMigratorv2 {
up: upStatement,
down: downStatement,
title: args.up,
title_down: args.down
title_down: args.down,
});
}
} else {
@ -1425,7 +1425,7 @@ export default class KnexMigratorv2 {
try {
result.data.object = {
up: '',
down: ''
down: '',
};
// if (!this.project) {
@ -1440,7 +1440,7 @@ export default class KnexMigratorv2 {
.where({
db_alias: args.dbAlias,
project_id: this.projectId,
title: args.title
title: args.title,
})
.first();

26
packages/nocodb/src/lib/db/sql-migrator/lib/templates/mssql.template.ts

@ -13,14 +13,14 @@ module.exports = {
: null || 1433,
user: 'sa',
password: 'Password123.',
database: 'default_dev'
database: 'default_dev',
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
dbAlias: 'primary',
},
},
],
},
test: {
api: {},
@ -32,15 +32,15 @@ module.exports = {
port: DOCKER_DB_PORT ? parseInt(DOCKER_DB_PORT) : null || 1433,
user: 'sa',
password: 'Password123.',
database: 'default_test'
database: 'default_test',
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
}
dbAlias: 'primary',
},
},
],
},
},
workingEnv: '_noco',
meta: {
@ -49,8 +49,8 @@ module.exports = {
queriesFolder: 'queries',
apisFolder: 'apis',
orm: 'sequelize',
router: 'express'
}
router: 'express',
},
};
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd

26
packages/nocodb/src/lib/db/sql-migrator/lib/templates/mysql.template.ts

@ -10,14 +10,14 @@ module.exports = {
port: process.env.DOCKER_DB_PORT || 3306,
user: 'root',
password: 'password',
database: 'default_dev'
database: 'default_dev',
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
dbAlias: 'primary',
},
},
],
},
test: {
api: {},
@ -29,15 +29,15 @@ module.exports = {
port: DOCKER_DB_PORT || 3306,
user: 'root',
password: 'password',
database: 'default_test'
database: 'default_test',
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
}
dbAlias: 'primary',
},
},
],
},
},
workingEnv: '_noco',
meta: {
@ -46,8 +46,8 @@ module.exports = {
queriesFolder: 'queries',
apisFolder: 'apis',
orm: 'sequelize',
router: 'express'
}
router: 'express',
},
};
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd

26
packages/nocodb/src/lib/db/sql-migrator/lib/templates/pg.template.ts

@ -12,14 +12,14 @@ module.exports = {
port: DOCKER_DB_PORT || 5432,
user: 'postgres',
password: 'password',
database: 'default_dev'
database: 'default_dev',
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
dbAlias: 'primary',
},
},
],
},
test: {
db: [
@ -30,15 +30,15 @@ module.exports = {
port: DOCKER_DB_PORT || 5432,
user: 'postgres',
password: 'password',
database: 'default_test'
database: 'default_test',
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
}
dbAlias: 'primary',
},
},
],
},
},
workingEnv: '_noco',
meta: {
@ -47,8 +47,8 @@ module.exports = {
queriesFolder: 'queries',
apisFolder: 'apis',
orm: 'sequelize',
router: 'express'
}
router: 'express',
},
};
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd

30
packages/nocodb/src/lib/db/sql-migrator/lib/templates/sqlite.template.ts

@ -14,16 +14,16 @@ module.exports = {
connection: {
filename:
DOCKER_DB_FILE ||
`${path.join(process.cwd(), 'xmigrator', 'default_dev.db')}`
`${path.join(process.cwd(), 'xmigrator', 'default_dev.db')}`,
},
useNullAsDefault: true
useNullAsDefault: true,
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
dbAlias: 'primary',
},
},
],
},
test: {
api: {},
@ -35,17 +35,17 @@ module.exports = {
connection: {
filename:
DOCKER_DB_FILE ||
`${path.join(process.cwd(), 'xmigrator', 'default_test.db')}`
`${path.join(process.cwd(), 'xmigrator', 'default_test.db')}`,
},
useNullAsDefault: true
useNullAsDefault: true,
},
meta: {
tn: 'nc_evolutions',
dbAlias: 'primary'
}
}
]
}
dbAlias: 'primary',
},
},
],
},
},
workingEnv: '_noco',
meta: {
@ -54,8 +54,8 @@ module.exports = {
queriesFolder: 'queries',
apisFolder: 'apis',
orm: 'sequelize',
router: 'express'
}
router: 'express',
},
};
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd

20
packages/nocodb/src/lib/db/util/Debug.ts

@ -26,20 +26,24 @@ export default class Debug {
ppException(e, func = null) {
let log = '';
log += ` EXCEPTION OCCURED!! in ${this.namespace.red.bold} @ ${func}`;
log += '\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log +=
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log += `MESSAGE:\n`.yellow.bold;
log += `${e.message}\n`.yellow.bold;
log += '\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log +=
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log += `CODE:\n`.yellow.bold;
log += `${e.code}\n`.yellow.bold;
log += '\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log +=
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log += `STACK:\n`.yellow.bold;
log += `${e.stack}\n`.yellow.bold;
log += '\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
log +=
'\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n'
.red.bold;
console.log(boxen(log, { padding: 1, borderStyle: 'double' }));
console.log(e);
return log;

12
packages/nocodb/src/lib/db/util/DebugMgr.ts

@ -7,7 +7,7 @@ const levels = {
info: 'I',
error: 'E',
warn: 'W',
debug: 'D'
debug: 'D',
};
export default class DebugMgr {
static _create(namespace) {
@ -32,23 +32,23 @@ export default class DebugMgr {
namespaces[namespace][`${namespace}_A`] = {
level: 'api',
enabled: debug.enabled(`${namespace}_A`)
enabled: debug.enabled(`${namespace}_A`),
};
namespaces[namespace][`${namespace}_W`] = {
level: 'warn',
enabled: debug.enabled(`${namespace}_W`)
enabled: debug.enabled(`${namespace}_W`),
};
namespaces[namespace][`${namespace}_I`] = {
level: 'info',
enabled: debug.enabled(`${namespace}_I`)
enabled: debug.enabled(`${namespace}_I`),
};
namespaces[namespace][`${namespace}_E`] = {
level: 'error',
enabled: debug.enabled(`${namespace}_E`)
enabled: debug.enabled(`${namespace}_E`),
};
namespaces[namespace][`${namespace}_D`] = {
level: 'debug',
enabled: debug.enabled(`${namespace}_D`)
enabled: debug.enabled(`${namespace}_D`),
};
}
}

4
packages/nocodb/src/lib/db/util/FileCollection.ts

@ -20,7 +20,7 @@ export default class FileCollection {
if (!exists) {
await promisify(jsonfile.writeFile)(this.args.path, [], {
spaces: 2
spaces: 2,
});
}
}
@ -31,7 +31,7 @@ export default class FileCollection {
async write(args) {
await promisify(jsonfile.writeFile)(this.args.path, args.data, {
spaces: 2
spaces: 2,
});
}
}

6
packages/nocodb/src/lib/db/util/file.help.ts

@ -1,14 +1,14 @@
import dayjs from 'dayjs';
const getUniqFilenamePrefix = function() {
const getUniqFilenamePrefix = function () {
return dayjs().format('YYYYMMDD_HHmmssSSS');
};
const getFilenameForUp = function(prefix) {
const getFilenameForUp = function (prefix) {
return prefix + '.up.sql';
};
const getFilenameForDown = function(prefix) {
const getFilenameForDown = function (prefix) {
return prefix + '.down.sql';
};

4
packages/nocodb/src/lib/jobs/EmitteryJobsMgr.ts

@ -20,9 +20,9 @@ export default class EmitteryJobsMgr extends JobsMgr {
progressCbk?: (payload: any, msg?: string) => void
) => void
) {
this.emitter.on(jobName, async payload => {
this.emitter.on(jobName, async (payload) => {
try {
await workerFn(payload, msg =>
await workerFn(payload, (msg) =>
this.invokeProgressCbks(jobName, payload, msg)
);
await this.invokeSuccessCbks(jobName, payload);

6
packages/nocodb/src/lib/jobs/JobsMgr.ts

@ -43,7 +43,7 @@ export default abstract class JobsMgr {
protected async invokeSuccessCbks(jobName: string, payload: any) {
await Promise.all(
this.successCbks?.[jobName]?.map(cb => cb(payload)) || []
this.successCbks?.[jobName]?.map((cb) => cb(payload)) || []
);
}
protected async invokeFailureCbks(
@ -52,7 +52,7 @@ export default abstract class JobsMgr {
error?: Error
) {
await Promise.all(
this.failureCbks?.[jobName]?.map(cb => cb(payload, error)) || []
this.failureCbks?.[jobName]?.map((cb) => cb(payload, error)) || []
);
}
protected async invokeProgressCbks(
@ -61,7 +61,7 @@ export default abstract class JobsMgr {
data?: any
) {
await Promise.all(
this.progressCbks?.[jobName]?.map(cb => cb(payload, data)) || []
this.progressCbks?.[jobName]?.map((cb) => cb(payload, data)) || []
);
}
}

4
packages/nocodb/src/lib/jobs/RedisJobsMgr.ts

@ -12,7 +12,7 @@ export default class RedisJobsMgr extends JobsMgr {
this.queue = {};
this.workers = {};
this.connection = new Redis(config, {
maxRetriesPerRequest: null
maxRetriesPerRequest: null,
});
}
@ -40,7 +40,7 @@ export default class RedisJobsMgr extends JobsMgr {
) {
this.workers[jobName] = new Worker(
jobName,
async payload => {
async (payload) => {
try {
await workerFn(payload.data, (...args) =>
this.invokeProgressCbks(jobName, ...args)

16
packages/nocodb/src/lib/meta/MetaAPILogger.ts

@ -9,16 +9,16 @@ export default class MetaAPILogger {
this.knex = XKnex({
client: 'sqlite3',
connection: {
filename: 'noco_log.db'
filename: 'noco_log.db',
},
useNullAsDefault: true
useNullAsDefault: true,
});
}
async init() {
await this.knex.migrate.latest({
migrationSource: new XcLoggerMigrationSource(),
tableName: 'xc_knex_migrations'
tableName: 'xc_knex_migrations',
});
}
@ -29,14 +29,14 @@ export default class MetaAPILogger {
const chunks = [];
res.write = function(chunk) {
res.write = function (chunk) {
chunks.push(chunk);
// eslint-disable-next-line prefer-rest-params
oldWrite.apply(res, arguments);
};
res.end = function(chunk) {
res.end = function (chunk) {
if (chunk) chunks.push(chunk);
const body = Buffer.concat(chunks).toString('utf8');
@ -64,7 +64,7 @@ export default class MetaAPILogger {
headers: JSON.stringify(req.headers),
method: req.method,
operation: req.body?.api,
response: typeof res === 'string' ? res : JSON.stringify(res)
response: typeof res === 'string' ? res : JSON.stringify(res),
});
}
}
@ -87,7 +87,7 @@ class XcLoggerMigrationSource {
case 'logger':
return {
async up(knex: XKnex) {
await knex.schema.createTable('nc_log', table => {
await knex.schema.createTable('nc_log', (table) => {
table.increments();
table.string('path');
table.string('method');
@ -102,7 +102,7 @@ class XcLoggerMigrationSource {
},
async down(knex) {
await knex.schema.dropTable('nc_log');
}
},
};
}
}

8
packages/nocodb/src/lib/meta/NcMetaIO.ts

@ -18,7 +18,7 @@ const META_TABLES = {
'nc_shared_views',
'nc_shared_bases',
'nc_cron',
'nc_audit'
'nc_audit',
],
grpc: [
'nc_models',
@ -33,7 +33,7 @@ const META_TABLES = {
'nc_disabled_models_for_role',
'nc_shared_views',
'nc_cron',
'nc_shared_bases'
'nc_shared_bases',
],
rest: [
'nc_models',
@ -49,8 +49,8 @@ const META_TABLES = {
'nc_shared_views',
'nc_cron',
'nc_audit',
'nc_shared_bases'
]
'nc_shared_bases',
],
};
export default abstract class NcMetaIO {

66
packages/nocodb/src/lib/meta/NcMetaIOImpl.ts

@ -66,7 +66,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
return {
list: await query,
count: Object.values(await countQuery.count().first())?.[0] as any
count: Object.values(await countQuery.count().first())?.[0] as any,
};
}
@ -85,7 +85,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
this.connection = trx || XKnex(this.config?.meta?.db);
} else {
let dbIndex = this.config.envs?.[this.config.workingEnv]?.db.findIndex(
c => c.meta.dbAlias === this.config?.auth?.jwt?.dbAlias
(c) => c.meta.dbAlias === this.config?.auth?.jwt?.dbAlias
);
dbIndex = dbIndex === -1 ? 0 : dbIndex;
this.connection = XKnex(
@ -107,11 +107,11 @@ export default class NcMetaIOImpl extends NcMetaIO {
public async metaInit(): Promise<boolean> {
await this.connection.migrate.latest({
migrationSource: new XcMigrationSource(),
tableName: 'xc_knex_migrations'
tableName: 'xc_knex_migrations',
});
await this.connection.migrate.latest({
migrationSource: new XcMigrationSourcev2(),
tableName: 'xc_knex_migrationsv2'
tableName: 'xc_knex_migrationsv2',
});
return true;
}
@ -246,7 +246,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
project_id,
created_at: this.knexConnection?.fn?.now(),
updated_at: this.knexConnection?.fn?.now(),
...data
...data,
});
}
@ -260,14 +260,14 @@ export default class NcMetaIOImpl extends NcMetaIO {
const id = data?.id || this.genNanoid(target);
const insertObj = {
...data,
...(ignoreIdGeneration ? {} : { id })
...(ignoreIdGeneration ? {} : { id }),
};
if (base_id !== null) insertObj.base_id = base_id;
if (project_id !== null) insertObj.project_id = project_id;
await this.knexConnection(target).insert({
...insertObj,
created_at: insertObj?.created_at || this.knexConnection?.fn?.now(),
updated_at: insertObj?.updated_at || this.knexConnection?.fn?.now()
updated_at: insertObj?.updated_at || this.knexConnection?.fn?.now(),
});
return insertObj;
}
@ -454,7 +454,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
if (apiType) {
await Promise.all(
META_TABLES?.[apiType]?.map(table => {
META_TABLES?.[apiType]?.map((table) => {
return (async () => {
try {
await this.knexConnection(table)
@ -492,19 +492,19 @@ export default class NcMetaIOImpl extends NcMetaIO {
config: CryptoJS.AES.encrypt(
JSON.stringify(config),
this.config?.auth?.jwt?.secret
).toString()
).toString(),
};
// todo: check project name used or not
await this.knexConnection('nc_projects').insert({
...project,
created_at: this.knexConnection?.fn?.now(),
updated_at: this.knexConnection?.fn?.now()
updated_at: this.knexConnection?.fn?.now(),
});
// todo
await this.knexConnection(MetaTable.PROJECT).insert({
id,
title: projectName
title: projectName,
});
project.prefix = config.prefix;
@ -520,21 +520,19 @@ export default class NcMetaIOImpl extends NcMetaIO {
config: CryptoJS.AES.encrypt(
JSON.stringify(config, null, 2),
this.config?.auth?.jwt?.secret
).toString()
).toString(),
};
// todo: check project name used or not
await this.knexConnection('nc_projects')
.update(project)
.where({
id: projectId
});
await this.knexConnection('nc_projects').update(project).where({
id: projectId,
});
} catch (e) {
console.log(e);
}
}
public async projectList(): Promise<any[]> {
return (await this.knexConnection('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
@ -578,7 +576,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
'=',
'xc_users.id'
)
.where(qb => {
.where((qb) => {
qb.where('nc_projects_users.roles', 'like', '%creator%').orWhere(
'nc_projects_users.roles',
'like',
@ -590,7 +588,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
.first()
.as('is_creator')
)
).map(p => {
).map((p) => {
p.allowed = p.user_id === userId;
p.config = CryptoJS.AES.decrypt(
p.config,
@ -607,7 +605,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
return !!(await this.knexConnection('nc_projects_users')
.where({
project_id: projectId,
user_id: userId
user_id: userId,
})
.first());
}
@ -615,7 +613,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
public async projectGet(projectName: string, encrypt?): Promise<any> {
const project = await this.knexConnection('nc_projects')
.where({
title: projectName
title: projectName,
})
.first();
@ -631,7 +629,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
public async projectGetById(projectId: string, encrypt?): Promise<any> {
const project = await this.knexConnection('nc_projects')
.where({
id: projectId
id: projectId,
})
.first();
if (project && !encrypt) {
@ -646,7 +644,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
public projectDelete(title: string): Promise<any> {
return this.knexConnection('nc_projects')
.where({
title
title,
})
.delete();
}
@ -654,7 +652,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
public projectDeleteById(id: string): Promise<any> {
return this.knexConnection('nc_projects')
.where({
id
id,
})
.delete();
}
@ -665,10 +663,10 @@ export default class NcMetaIOImpl extends NcMetaIO {
): Promise<any> {
return this.knexConnection('nc_projects')
.update({
status
status,
})
.where({
id: projectId
id: projectId,
});
}
@ -681,7 +679,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
await this.knexConnection('nc_projects_users')
.where({
user_id: userId,
project_id: projectId
project_id: projectId,
})
.first()
) {
@ -690,7 +688,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
return this.knexConnection('nc_projects_users').insert({
user_id: userId,
project_id: projectId,
roles
roles,
});
}
@ -698,7 +696,7 @@ export default class NcMetaIOImpl extends NcMetaIO {
return this.knexConnection('nc_projects_users')
.where({
user_id: userId,
project_id: projectId
project_id: projectId,
})
.delete();
}
@ -706,26 +704,26 @@ export default class NcMetaIOImpl extends NcMetaIO {
public removeXcUser(userId: any): Promise<any> {
return this.knexConnection('xc_users')
.where({
id: userId
id: userId,
})
.delete();
}
get isRest(): boolean {
return this.config?.envs?.[this.config.workingEnv]?.db?.some(
db => db?.meta?.api?.type === 'rest'
(db) => db?.meta?.api?.type === 'rest'
);
}
get isGql(): boolean {
return this.config?.envs?.[this.config.workingEnv]?.db?.some(
db => db?.meta?.api?.type === 'graphql'
(db) => db?.meta?.api?.type === 'graphql'
);
}
get isGrpc(): boolean {
return this.config?.envs?.[this.config.workingEnv]?.db?.some(
db => db?.meta?.api?.type === 'grpc'
(db) => db?.meta?.api?.type === 'grpc'
);
}

1012
packages/nocodb/src/lib/meta/NcMetaMgr.ts

File diff suppressed because it is too large Load Diff

94
packages/nocodb/src/lib/meta/NcMetaMgrEE.ts

@ -67,12 +67,12 @@ export default class NcMetaMgrEE extends NcMetaMgr {
let tables = await this.xcVisibilityMetaGet({
...args,
args: { type: 'table', ...args.args }
args: { type: 'table', ...args.args },
});
tables = tables.filter((table: any) => {
return Object.keys(roles).some(
role => roles[role] && !table.disabled[role]
(role) => roles[role] && !table.disabled[role]
);
});
@ -89,10 +89,10 @@ export default class NcMetaMgrEE extends NcMetaMgr {
dbAlias,
'nc_acl',
{
acl: JSON.stringify(args.args.acl)
acl: JSON.stringify(args.args.acl),
},
{
tn: args.args.tn || args.args.name
tn: args.args.tn || args.args.name,
}
);
@ -101,7 +101,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
op_sub_type: 'UPDATED',
user: req.user.email,
description: `updated table ${args.args.tn || args.args.name} acl `,
ip: req.clientIp
ip: req.clientIp,
});
Tele.emit('evt', { evt_type: 'acl:updated' });
@ -117,7 +117,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
const sharedViewMeta = await this.xcMeta
.knex('nc_shared_views')
.where({
view_id: args.args.view_id
view_id: args.args.view_id,
})
.first();
@ -130,7 +130,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
sharedViewMeta.base_id,
'nc_models',
{
title: sharedViewMeta.view_name
title: sharedViewMeta.view_name,
}
);
@ -143,8 +143,8 @@ export default class NcMetaMgrEE extends NcMetaMgr {
}
const apiBuilder = this.app?.projectBuilders
?.find(pb => pb.id === sharedViewMeta.project_id)
?.apiBuilders?.find(ab => ab.dbAlias === sharedViewMeta.base_id);
?.find((pb) => pb.id === sharedViewMeta.project_id)
?.apiBuilders?.find((ab) => ab.dbAlias === sharedViewMeta.base_id);
const model = apiBuilder?.xcModels?.[sharedViewMeta.model_name];
let meta = apiBuilder?.getMeta(sharedViewMeta.model_name);
@ -160,7 +160,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
meta = {
...meta,
columns: meta.columns.filter(c => queryParams?.showFields?.[c._cn])
columns: meta.columns.filter((c) => queryParams?.showFields?.[c._cn]),
};
let where = '';
@ -188,7 +188,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
sort.push(...req.query.sort.split(','));
}
const fields = meta.columns.map(c => c._cn).join(',');
const fields = meta.columns.map((c) => c._cn).join(',');
const nestedParams = this.serializeNestedParams(meta, queryParams);
return {
@ -200,14 +200,14 @@ export default class NcMetaMgrEE extends NcMetaMgr {
where,
fields,
sort: sort.join(','),
...nestedParams
...nestedParams,
}),
...(await model.countByPk({
...req.query,
where,
fields
fields,
})),
client: apiBuilder?.client
client: apiBuilder?.client,
};
} catch (e) {
console.log(e);
@ -234,7 +234,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
{
model_name: args.args.model_name,
view_name: args.args.view_name,
view_type: args.args.show_as
view_type: args.args.show_as,
},
['id', 'view_id', 'view_type']
);
@ -249,7 +249,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
// query_params: JSON.stringify(args.args.query_params),
view_id: uuidv4(),
password: args.args.password,
view_type: args.args.show_as
view_type: args.args.show_as,
};
await this.xcMeta.metaInsert(
@ -291,7 +291,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
this.getDbAlias(args),
'nc_shared_views',
{
password: args.args?.password
password: args.args?.password,
},
args.args.id
);
@ -331,7 +331,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
rtn: d.rtn,
cn: d.cn,
rcn: d.rcn,
relation_type: d.relationType
relation_type: d.relationType,
});
}
for (const role of Object.keys(d.disabled)) {
@ -343,7 +343,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
type: args.args.type,
title: d[field],
role,
...props
...props,
}
);
if (dataInDb) {
@ -354,13 +354,13 @@ export default class NcMetaMgrEE extends NcMetaMgr {
this.getDbAlias(args),
'nc_disabled_models_for_role',
{
disabled: d.disabled[role]
disabled: d.disabled[role],
},
{
type: args.args.type,
title: d[field],
role,
...props
...props,
}
);
}
@ -373,7 +373,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
type: args.args.type,
title: d[field],
role,
...props
...props,
}
);
}
@ -387,7 +387,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
type: args.args.type,
title: d[field],
role,
...props
...props,
}
);
}
@ -414,7 +414,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
title: d[field],
role,
parent_model_title: d.ptn,
...props
...props,
}
);
if (dataInDb) {
@ -425,14 +425,14 @@ export default class NcMetaMgrEE extends NcMetaMgr {
this.getDbAlias(args),
'nc_disabled_models_for_role',
{
disabled: d.disabled[role]
disabled: d.disabled[role],
},
{
parent_model_title: d.ptn,
type: d.type,
title: d[field],
role,
...props
...props,
}
);
}
@ -446,7 +446,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
type: d.type,
title: d[field],
role,
...props
...props,
}
);
}
@ -461,7 +461,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
type: d.type,
title: d[field],
role,
...props
...props,
}
);
}
@ -482,8 +482,8 @@ export default class NcMetaMgrEE extends NcMetaMgr {
offset: args.args.offset,
sort: {
field: 'created_at',
desc: true
}
desc: true,
},
}
);
}
@ -496,16 +496,16 @@ export default class NcMetaMgrEE extends NcMetaMgr {
dbAlias,
'nc_models',
{
enabled: true
enabled: true,
},
null,
{
title: {
in: args.args
in: args.args,
},
type: {
eq: 'table'
}
eq: 'table',
},
}
);
@ -514,16 +514,16 @@ export default class NcMetaMgrEE extends NcMetaMgr {
dbAlias,
'nc_models',
{
enabled: false
enabled: false,
},
null,
{
title: {
nin: args.args
nin: args.args,
},
type: {
eq: 'table'
}
eq: 'table',
},
}
);
}
@ -536,10 +536,10 @@ export default class NcMetaMgrEE extends NcMetaMgr {
// filter out model names which toggled
const metaTableNames = [
...new Set(
args.args.map(rel => {
args.args.map((rel) => {
return rel.relationType === 'hm' ? rel.rtn : rel.tn;
})
)
),
];
// get current meta from db
@ -551,9 +551,9 @@ export default class NcMetaMgrEE extends NcMetaMgr {
{
xcCondition: {
title: {
in: metaTableNames
}
}
in: metaTableNames,
},
},
}
);
@ -564,7 +564,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
for (const { meta, id, title } of metas) {
metaMap[title] = {
id,
meta: JSON.parse(meta)
meta: JSON.parse(meta),
};
}
@ -572,12 +572,12 @@ export default class NcMetaMgrEE extends NcMetaMgr {
for (const rel of args.args) {
if (rel.relationType === 'hm') {
const relation = metaMap[rel.rtn].meta.hasMany.find(
hmRel => hmRel.tn === rel.tn
(hmRel) => hmRel.tn === rel.tn
);
relation.enabled = rel.enabled;
} else {
const relation = metaMap[rel.tn].meta.belongsTo.find(
btRel => btRel.rtn === rel.rtn
(btRel) => btRel.rtn === rel.rtn
);
relation.enabled = rel.enabled;
}
@ -591,7 +591,7 @@ export default class NcMetaMgrEE extends NcMetaMgr {
dbAlias,
'nc_models',
{
meta: JSON.stringify(meta)
meta: JSON.stringify(meta),
},
id
);

34
packages/nocodb/src/lib/meta/NcMetaMgrv2.ts

@ -61,7 +61,7 @@ export default class NcMetaMgrv2 {
router.use(
bodyParser.json({
limit: process.env.NC_REQUEST_BODY_SIZE || 1024 * 1024
limit: process.env.NC_REQUEST_BODY_SIZE || 1024 * 1024,
})
);
@ -70,7 +70,7 @@ export default class NcMetaMgrv2 {
const upload = multer({
storage: multer.diskStorage({
// dest: path.join(this.config.toolDir, 'uploads')
})
}),
});
// router.post(this.config.dashboardPath, upload.single('file'));
router.post(this.config.dashboardPath, upload.any());
@ -142,8 +142,7 @@ export default class NcMetaMgrv2 {
)
) {
return res.status(401).json({
msg:
'Unauthorized access : xc-auth does not have admin permission'
msg: 'Unauthorized access : xc-auth does not have admin permission',
});
}
} else if (this.config?.auth?.masterKey) {
@ -151,8 +150,7 @@ export default class NcMetaMgrv2 {
req.headers['xc-master-key'] !== this.config.auth.masterKey.secret
) {
return res.status(401).json({
msg:
'Unauthorized access : xc-admin header missing or not matching'
msg: 'Unauthorized access : xc-admin header missing or not matching',
});
}
}
@ -186,8 +184,8 @@ export default class NcMetaMgrv2 {
user: req.user,
ctx: {
req,
res
}
res,
},
});
}
@ -234,8 +232,8 @@ export default class NcMetaMgrv2 {
process.env.NC_GITHUB_CLIENT_SECRET
),
oneClick: !!process.env.NC_ONE_CLICK,
connectToExternalDB: !process.env
.NC_CONNECT_TO_EXTERNAL_DB_DISABLED,
connectToExternalDB:
!process.env.NC_CONNECT_TO_EXTERNAL_DB_DISABLED,
version: packageVersion,
defaultLimit: Math.max(
Math.min(
@ -244,7 +242,7 @@ export default class NcMetaMgrv2 {
),
+process.env.DB_QUERY_LIMIT_MIN || 1
),
timezone: defaultConnectionConfig.timezone
timezone: defaultConnectionConfig.timezone,
};
return res.json(result);
}
@ -254,7 +252,7 @@ export default class NcMetaMgrv2 {
// projectHasDb: this.toolMgr.projectHasDb(),
type: this.config.type,
env: this.config.workingEnv,
oneClick: !!process.env.NC_ONE_CLICK
oneClick: !!process.env.NC_ONE_CLICK,
});
}
}
@ -263,7 +261,7 @@ export default class NcMetaMgrv2 {
projectHasDb,
type: this.config.type,
env: this.config.workingEnv,
oneClick: !!process.env.NC_ONE_CLICK
oneClick: !!process.env.NC_ONE_CLICK,
});
} catch (e) {
console.log(e);
@ -376,8 +374,8 @@ export default class NcMetaMgrv2 {
res: result,
ctx: {
req,
res
}
res,
},
});
}
@ -404,11 +402,11 @@ export default class NcMetaMgrv2 {
console.log(e);
if (e instanceof XCEeError) {
res.status(402).json({
msg: e.message
msg: e.message,
});
} else {
res.status(400).json({
msg: e.message
msg: e.message,
});
}
}
@ -429,7 +427,7 @@ export default class NcMetaMgrv2 {
return {
projectId: this.getProjectId(args),
dbAlias: this.getDbAlias(args),
xcMeta: this.xcMeta
xcMeta: this.xcMeta,
};
}
}

32
packages/nocodb/src/lib/meta/api/attachmentApis.ts

@ -19,7 +19,7 @@ export async function upload(req: Request, res: Response) {
const storageAdapter = await NcPluginMgrv2.storageAdapter();
const attachments = await Promise.all(
(req as any).files?.map(async file => {
(req as any).files?.map(async (file) => {
const fileName = `${nanoid(6)}${path.extname(file.originalname)}`;
let url = await storageAdapter.fileCreate(
@ -38,7 +38,7 @@ export async function upload(req: Request, res: Response) {
title: file.originalname,
mimetype: file.mimetype,
size: file.size,
icon: mimeIcons[path.extname(file.originalname).slice(1)] || undefined
icon: mimeIcons[path.extname(file.originalname).slice(1)] || undefined,
};
})
);
@ -56,7 +56,7 @@ export async function uploadViaURL(req: Request, res: Response) {
const storageAdapter = await NcPluginMgrv2.storageAdapter();
const attachments = await Promise.all(
req.body?.map?.(async urlMeta => {
req.body?.map?.(async (urlMeta) => {
const { url, fileName: _fileName } = urlMeta;
const fileName = `${nanoid(6)}${_fileName || url.split('/').pop()}`;
@ -76,7 +76,7 @@ export async function uploadViaURL(req: Request, res: Response) {
title: fileName,
mimetype: urlMeta.mimetype,
size: urlMeta.size,
icon: mimeIcons[path.extname(fileName).slice(1)] || undefined
icon: mimeIcons[path.extname(fileName).slice(1)] || undefined,
};
})
);
@ -91,13 +91,8 @@ export async function fileRead(req, res) {
const storageAdapter = await NcPluginMgrv2.storageAdapter();
// const type = mimetypes[path.extname(req.s.fileName).slice(1)] || 'text/plain';
const type =
mimetypes[
path
.extname(req.params?.[0])
.split('/')
.pop()
.slice(1)
] || 'text/plain';
mimetypes[path.extname(req.params?.[0]).split('/').pop().slice(1)] ||
'text/plain';
// const img = await this.storageAdapter.fileRead(slash(path.join('nc', req.params.projectId, req.params.dbAlias, 'uploads', req.params.fileName)));
const img = await storageAdapter.fileRead(
slash(
@ -106,7 +101,7 @@ export async function fileRead(req, res) {
'uploads',
req.params?.[0]
?.split('/')
.filter(p => p !== '..')
.filter((p) => p !== '..')
.join('/')
)
)
@ -125,13 +120,8 @@ router.get(/^\/dl\/([^/]+)\/([^/]+)\/(.+)$/, async (req, res) => {
try {
// const type = mimetypes[path.extname(req.params.fileName).slice(1)] || 'text/plain';
const type =
mimetypes[
path
.extname(req.params[2])
.split('/')
.pop()
.slice(1)
] || 'text/plain';
mimetypes[path.extname(req.params[2]).split('/').pop().slice(1)] ||
'text/plain';
const storageAdapter = await NcPluginMgrv2.storageAdapter();
// const img = await this.storageAdapter.fileRead(slash(path.join('nc', req.params.projectId, req.params.dbAlias, 'uploads', req.params.fileName)));
@ -154,13 +144,13 @@ router.get(/^\/dl\/([^/]+)\/([^/]+)\/(.+)$/, async (req, res) => {
});
export function sanitizeUrlPath(paths) {
return paths.map(url => url.replace(/[/.?#]+/g, '_'));
return paths.map((url) => url.replace(/[/.?#]+/g, '_'));
}
router.post(
'/api/v1/db/storage/upload',
multer({
storage: multer.diskStorage({})
storage: multer.diskStorage({}),
}).any(),
ncMetaAclMw(upload, 'upload')
);

8
packages/nocodb/src/lib/meta/api/auditApis.ts

@ -12,7 +12,7 @@ export async function commentRow(req: Request<any, any>, res) {
await Audit.insert({
...req.body,
user: (req as any).user?.email,
op_type: AuditOperationTypes.COMMENT
op_type: AuditOperationTypes.COMMENT,
})
);
}
@ -32,7 +32,7 @@ export async function auditRowUpdate(req: Request<any, any>, res) {
: <span class="text-decoration-line-through red px-2 lighten-4 black--text">${req.body.prev_value}</span>
<span class="black--text green lighten-4 px-2">${req.body.value}</span>`),
ip: (req as any).clientIp,
user: (req as any).user?.email
user: (req as any).user?.email,
})
);
}
@ -47,7 +47,7 @@ export async function auditList(req: Request, res: Response) {
await Audit.projectAuditList(req.params.projectId, req.query),
{
count: await Audit.projectAuditCount(req.params.projectId),
...req.query
...req.query,
}
)
);
@ -57,7 +57,7 @@ export async function commentsCount(req: Request<any, any, any>, res) {
res.json(
await Audit.commentsCount({
fk_model_id: req.query.fk_model_id as string,
ids: req.query.ids as string[]
ids: req.query.ids as string[],
})
);
}

2
packages/nocodb/src/lib/meta/api/cacheApis.ts

@ -6,7 +6,7 @@ export async function cacheGet(_, res) {
const data = await NocoCache.export();
res.set({
'Content-Type': 'application/json',
'Content-Disposition': `attachment; filename="cache-export.json"`
'Content-Disposition': `attachment; filename="cache-export.json"`,
});
res.send(JSON.stringify(data));
}

219
packages/nocodb/src/lib/meta/api/columnApis.ts

@ -10,7 +10,7 @@ import { customAlphabet } from 'nanoid';
import LinkToAnotherRecordColumn from '../../models/LinkToAnotherRecordColumn';
import {
getUniqueColumnAliasName,
getUniqueColumnName
getUniqueColumnName,
} from '../helpers/getUniqueName';
import {
AuditOperationSubTypes,
@ -21,7 +21,7 @@ import {
substituteColumnAliasWithIdInFormula,
substituteColumnIdWithAliasInFormula,
TableType,
UITypes
UITypes,
} from 'nocodb-sdk';
import Audit from '../../models/Audit';
import SqlMgrv2 from '../../db/sql-mgr/v2/SqlMgrv2';
@ -41,7 +41,7 @@ const randomID = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz_', 10);
export enum Altered {
NEW_COLUMN = 1,
DELETE_COLUMN = 4,
UPDATE_COLUMN = 8
UPDATE_COLUMN = 8,
}
async function createHmAndBtColumn(
@ -72,7 +72,7 @@ async function createHmAndBtColumn(
fk_parent_column_id: parent.primaryKey.id,
fk_related_model_id: parent.id,
virtual,
system: isSystemCol
system: isSystemCol,
});
}
// save hm column
@ -90,14 +90,14 @@ async function createHmAndBtColumn(
fk_parent_column_id: parent.primaryKey.id,
fk_related_model_id: child.id,
virtual,
system: isSystemCol
system: isSystemCol,
});
}
}
export async function columnAdd(req: Request, res: Response<TableType>) {
const table = await Model.getWithInfo({
id: req.params.tableId
id: req.params.tableId,
});
const base = await Base.get(table.base_id);
const project = await base.getProject();
@ -106,7 +106,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
!isVirtualCol(req.body) &&
!(await Column.checkTitleAvailable({
column_name: req.body.column_name,
fk_model_id: req.params.tableId
fk_model_id: req.params.tableId,
}))
) {
NcError.badRequest('Duplicate column name');
@ -114,7 +114,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
if (
!(await Column.checkAliasAvailable({
title: req.body.title || req.body.column_name,
fk_model_id: req.params.tableId
fk_model_id: req.params.tableId,
}))
) {
NcError.badRequest('Duplicate column alias');
@ -129,14 +129,14 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
'title',
'fk_relation_column_id',
'fk_rollup_column_id',
'rollup_function'
'rollup_function',
],
req.body
);
const relation = await (
await Column.get({
colId: req.body.fk_relation_column_id
colId: req.body.fk_relation_column_id,
})
).getColOptions<LinkToAnotherRecordType>();
@ -148,13 +148,13 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
switch (relation.type) {
case 'hm':
relatedColumn = await Column.get({
colId: relation.fk_child_column_id
colId: relation.fk_child_column_id,
});
break;
case 'mm':
case 'bt':
relatedColumn = await Column.get({
colId: relation.fk_parent_column_id
colId: relation.fk_parent_column_id,
});
break;
}
@ -162,14 +162,14 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
const relatedTable = await relatedColumn.getModel();
if (
!(await relatedTable.getColumns()).find(
c => c.id === req.body.fk_rollup_column_id
(c) => c.id === req.body.fk_rollup_column_id
)
)
throw new Error('Rollup column not found in related table');
await Column.insert({
...colBody,
fk_model_id: table.id
fk_model_id: table.id,
});
}
break;
@ -182,7 +182,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
const relation = await (
await Column.get({
colId: req.body.fk_relation_column_id
colId: req.body.fk_relation_column_id,
})
).getColOptions<LinkToAnotherRecordType>();
@ -194,13 +194,13 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
switch (relation.type) {
case 'hm':
relatedColumn = await Column.get({
colId: relation.fk_child_column_id
colId: relation.fk_child_column_id,
});
break;
case 'mm':
case 'bt':
relatedColumn = await Column.get({
colId: relation.fk_parent_column_id
colId: relation.fk_parent_column_id,
});
break;
}
@ -208,14 +208,14 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
const relatedTable = await relatedColumn.getModel();
if (
!(await relatedTable.getColumns()).find(
c => c.id === req.body.fk_lookup_column_id
(c) => c.id === req.body.fk_lookup_column_id
)
)
throw new Error('Lookup column not found in related table');
await Column.insert({
...colBody,
fk_model_id: table.id
fk_model_id: table.id,
});
}
break;
@ -231,7 +231,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
let childColumn: Column;
const sqlMgr = await ProjectMgrv2.getSqlMgr({
id: base.project_id
id: base.project_id,
});
if (req.body.type === 'hm' || req.body.type === 'bt') {
// populate fk column name
@ -255,22 +255,22 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
dtxp: parent.primaryKey.dtxp,
dtxs: parent.primaryKey.dtxs,
un: parent.primaryKey.un,
altered: Altered.NEW_COLUMN
altered: Altered.NEW_COLUMN,
};
const tableUpdateBody = {
...child,
tn: child.table_name,
originalColumns: child.columns.map(c => ({
originalColumns: child.columns.map((c) => ({
...c,
cn: c.column_name
cn: c.column_name,
})),
columns: [
...child.columns.map(c => ({
...child.columns.map((c) => ({
...c,
cn: c.column_name
cn: c.column_name,
})),
newColumn
]
newColumn,
],
};
await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody);
@ -278,7 +278,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
const { id } = await Column.insert({
...newColumn,
uidt: UITypes.ForeignKey,
fk_model_id: child.id
fk_model_id: child.id,
});
childColumn = await Column.get({ colId: id });
@ -293,7 +293,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
type: 'real',
parentColumn: parent.primaryKey.column_name
parentColumn: parent.primaryKey.column_name,
});
}
@ -303,10 +303,10 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
await createColumnIndex({
column: new Column({
...newColumn,
fk_model_id: child.id
fk_model_id: child.id,
}),
base,
sqlMgr
sqlMgr,
});
}
}
@ -344,7 +344,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
dtxs: childPK.dtxs,
un: childPK.un,
altered: 1,
uidt: UITypes.ForeignKey
uidt: UITypes.ForeignKey,
},
{
cn: parentCn,
@ -359,14 +359,14 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
dtxs: parentPK.dtxs,
un: parentPK.un,
altered: 1,
uidt: UITypes.ForeignKey
uidt: UITypes.ForeignKey,
}
);
await sqlMgr.sqlOpPlus(base, 'tableCreate', {
tn: aTn,
_tn: aTnAlias,
columns: associateTableCols
columns: associateTableCols,
});
const assocModel = await Model.insert(project.id, base.id, {
@ -374,7 +374,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
title: aTnAlias,
// todo: sanitize
mm: true,
columns: associateTableCols
columns: associateTableCols,
});
if (!req.body.virtual) {
@ -384,7 +384,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
childColumn: parentCn,
parentTable: parent.table_name,
parentColumn: parentPK.column_name,
type: 'real'
type: 'real',
};
const rel2Args = {
...req.body,
@ -392,17 +392,17 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
childColumn: childCn,
parentTable: child.table_name,
parentColumn: childPK.column_name,
type: 'real'
type: 'real',
};
await sqlMgr.sqlOpPlus(base, 'relationCreate', rel1Args);
await sqlMgr.sqlOpPlus(base, 'relationCreate', rel2Args);
}
const parentCol = (await assocModel.getColumns())?.find(
c => c.column_name === parentCn
(c) => c.column_name === parentCn
);
const childCol = (await assocModel.getColumns())?.find(
c => c.column_name === childCn
(c) => c.column_name === childCn
);
await createHmAndBtColumn(
@ -442,7 +442,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
fk_mm_model_id: assocModel.id,
fk_mm_child_column_id: childCol.id,
fk_mm_parent_column_id: parentCol.id,
fk_related_model_id: parent.id
fk_related_model_id: parent.id,
});
await Column.insert({
title: getUniqueColumnAliasName(
@ -461,7 +461,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
fk_mm_model_id: assocModel.id,
fk_mm_child_column_id: parentCol.id,
fk_mm_parent_column_id: childCol.id,
fk_related_model_id: child.id
fk_related_model_id: child.id,
});
// todo: create index for virtual relations as well
@ -470,18 +470,18 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
await createColumnIndex({
column: new Column({
...associateTableCols[0],
fk_model_id: assocModel.id
fk_model_id: assocModel.id,
}),
base,
sqlMgr
sqlMgr,
});
await createColumnIndex({
column: new Column({
...associateTableCols[1],
fk_model_id: assocModel.id
fk_model_id: assocModel.id,
}),
base,
sqlMgr
sqlMgr,
});
}
}
@ -496,7 +496,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
);
await Column.insert({
...colBody,
fk_model_id: table.id
fk_model_id: table.id,
});
break;
@ -512,31 +512,33 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
const tableUpdateBody = {
...table,
tn: table.table_name,
originalColumns: table.columns.map(c => ({
originalColumns: table.columns.map((c) => ({
...c,
cn: c.column_name
cn: c.column_name,
})),
columns: [
...table.columns.map(c => ({ ...c, cn: c.column_name })),
...table.columns.map((c) => ({ ...c, cn: c.column_name })),
{
...colBody,
cn: colBody.column_name,
altered: Altered.NEW_COLUMN
}
]
altered: Altered.NEW_COLUMN,
},
],
};
const sqlClient = NcConnectionMgrv2.getSqlClient(base);
const sqlMgr = await ProjectMgrv2.getSqlMgr({ id: base.project_id });
await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody);
const columns: Array<Omit<Column, 'column_name' | 'title'> & {
cn: string;
system?: boolean;
}> = (await sqlClient.columnList({ tn: table.table_name }))?.data?.list;
const columns: Array<
Omit<Column, 'column_name' | 'title'> & {
cn: string;
system?: boolean;
}
> = (await sqlClient.columnList({ tn: table.table_name }))?.data?.list;
const insertedColumnMeta =
columns.find(c => c.cn === colBody.column_name) || ({} as any);
columns.find((c) => c.cn === colBody.column_name) || ({} as any);
if (
colBody.uidt === UITypes.SingleSelect ||
@ -553,7 +555,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
)
? colBody.dtxp
: insertedColumnMeta.dtxp,
fk_model_id: table.id
fk_model_id: table.id,
});
}
break;
@ -567,7 +569,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
op_sub_type: AuditOperationSubTypes.CREATED,
user: (req as any)?.user?.email,
description: `created column ${colBody.column_name} with alias ${colBody.title} from table ${table.table_name}`,
ip: (req as any).clientIp
ip: (req as any).clientIp,
}).then(() => {});
Tele.emit('evt', { evt_type: 'column:created' });
@ -584,7 +586,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
const column = await Column.get({ colId: req.params.columnId });
const table = await Model.getWithInfo({
id: column.fk_model_id
id: column.fk_model_id,
});
const base = await Base.get(table.base_id);
@ -593,7 +595,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
!(await Column.checkTitleAvailable({
column_name: req.body.column_name,
fk_model_id: column.fk_model_id,
exclude_id: req.params.columnId
exclude_id: req.params.columnId,
}))
) {
NcError.badRequest('Duplicate column name');
@ -602,7 +604,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
!(await Column.checkAliasAvailable({
title: req.body.title,
fk_model_id: column.fk_model_id,
exclude_id: req.params.columnId
exclude_id: req.params.columnId,
}))
) {
NcError.badRequest('Duplicate column alias');
@ -615,7 +617,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
UITypes.Rollup,
UITypes.LinkToAnotherRecord,
UITypes.Formula,
UITypes.ForeignKey
UITypes.ForeignKey,
].includes(column.uidt)
) {
if (column.uidt === colBody.uidt) {
@ -627,11 +629,11 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
await Column.update(column.id, {
// title: colBody.title,
...column,
...colBody
...colBody,
});
} else if (colBody.title !== column.title) {
await Column.updateAlias(req.params.columnId, {
title: colBody.title
title: colBody.title,
});
}
} else {
@ -645,7 +647,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
UITypes.Rollup,
UITypes.LinkToAnotherRecord,
UITypes.Formula,
UITypes.ForeignKey
UITypes.ForeignKey,
].includes(colBody.uidt)
) {
NcError.notImplemented(
@ -656,20 +658,20 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
const tableUpdateBody = {
...table,
tn: table.table_name,
originalColumns: table.columns.map(c => ({
originalColumns: table.columns.map((c) => ({
...c,
cn: c.column_name,
cno: c.column_name
cno: c.column_name,
})),
columns: await Promise.all(
table.columns.map(async c => {
table.columns.map(async (c) => {
if (c.id === req.params.columnId) {
const res = {
...c,
...colBody,
cn: colBody.column_name,
cno: c.column_name,
altered: Altered.UPDATE_COLUMN
altered: Altered.UPDATE_COLUMN,
};
// update formula with new column name
@ -690,7 +692,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
[new_column]
);
await FormulaColumn.update(c.id, {
formula_raw: new_formula_raw
formula_raw: new_formula_raw,
});
}
}
@ -701,14 +703,14 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
}
return Promise.resolve(c);
})
)
),
};
const sqlMgr = await ProjectMgrv2.getSqlMgr({ id: base.project_id });
await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody);
await Column.update(req.params.columnId, {
...colBody
...colBody,
});
}
Audit.insert({
@ -717,7 +719,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
op_sub_type: AuditOperationSubTypes.UPDATED,
user: (req as any)?.user?.email,
description: `updated column ${column.column_name} with alias ${column.title} from table ${table.table_name}`,
ip: (req as any).clientIp
ip: (req as any).clientIp,
}).then(() => {});
await table.getColumns();
@ -729,7 +731,7 @@ export async function columnUpdate(req: Request, res: Response<TableType>) {
export async function columnDelete(req: Request, res: Response<TableType>) {
const column = await Column.get({ colId: req.params.columnId });
const table = await Model.getWithInfo({
id: column.fk_model_id
id: column.fk_model_id,
});
const base = await Base.get(table.base_id);
@ -750,9 +752,8 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
break;
case UITypes.LinkToAnotherRecord:
{
const relationColOpt = await column.getColOptions<
LinkToAnotherRecordColumn
>();
const relationColOpt =
await column.getColOptions<LinkToAnotherRecordColumn>();
const childColumn = await relationColOpt.getChildColumn();
const childTable = await childColumn.getModel();
@ -770,7 +771,7 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
childTable,
parentColumn,
parentTable,
sqlMgr
sqlMgr,
// ncMeta
});
}
@ -789,7 +790,7 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
sqlMgr,
parentTable: parentTable,
childColumn: mmParentCol,
base
base,
// ncMeta
},
true
@ -803,20 +804,19 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
sqlMgr,
parentTable: childTable,
childColumn: mmChildCol,
base
base,
// ncMeta
},
true
);
const columnsInRelatedTable: Column[] = await relationColOpt
.getRelatedTable()
.then(m => m.getColumns());
.then((m) => m.getColumns());
for (const c of columnsInRelatedTable) {
if (c.uidt !== UITypes.LinkToAnotherRecord) continue;
const colOpt = await c.getColOptions<
LinkToAnotherRecordColumn
>();
const colOpt =
await c.getColOptions<LinkToAnotherRecordColumn>();
if (
colOpt.type === 'mm' &&
colOpt.fk_parent_column_id === childColumn.id &&
@ -836,9 +836,8 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
await mmTable.getColumns();
for (const c of mmTable.columns) {
if (c.uidt !== UITypes.LinkToAnotherRecord) continue;
const colOpt = await c.getColOptions<
LinkToAnotherRecordColumn
>();
const colOpt =
await c.getColOptions<LinkToAnotherRecordColumn>();
if (colOpt.type === 'bt') {
await Column.delete(c.id);
}
@ -848,9 +847,8 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
await parentTable.getColumns();
for (const c of parentTable.columns) {
if (c.uidt !== UITypes.LinkToAnotherRecord) continue;
const colOpt = await c.getColOptions<
LinkToAnotherRecordColumn
>();
const colOpt =
await c.getColOptions<LinkToAnotherRecordColumn>();
if (colOpt.fk_related_model_id === mmTable.id) {
await Column.delete(c.id);
}
@ -860,9 +858,8 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
await childTable.getColumns();
for (const c of childTable.columns) {
if (c.uidt !== UITypes.LinkToAnotherRecord) continue;
const colOpt = await c.getColOptions<
LinkToAnotherRecordColumn
>();
const colOpt =
await c.getColOptions<LinkToAnotherRecordColumn>();
if (colOpt.fk_related_model_id === mmTable.id) {
await Column.delete(c.id);
}
@ -889,24 +886,24 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
const tableUpdateBody = {
...table,
tn: table.table_name,
originalColumns: table.columns.map(c => ({
originalColumns: table.columns.map((c) => ({
...c,
cn: c.column_name,
cno: c.column_name
cno: c.column_name,
})),
columns: table.columns.map(c => {
columns: table.columns.map((c) => {
if (c.id === req.params.columnId) {
return {
...c,
cn: c.column_name,
cno: c.column_name,
altered: Altered.DELETE_COLUMN
altered: Altered.DELETE_COLUMN,
};
} else {
(c as any).cn = c.column_name;
}
return c;
})
}),
};
await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody);
@ -921,7 +918,7 @@ export async function columnDelete(req: Request, res: Response<TableType>) {
op_sub_type: AuditOperationSubTypes.DELETED,
user: (req as any)?.user?.email,
description: `deleted column ${column.column_name} with alias ${column.title} from table ${table.table_name}`,
ip: (req as any).clientIp
ip: (req as any).clientIp,
}).then(() => {});
await table.getColumns();
@ -955,7 +952,7 @@ const deleteHmOrBtRelation = async (
parentColumn,
parentTable,
sqlMgr,
ncMeta = Noco.ncMeta
ncMeta = Noco.ncMeta,
}: {
relationColOpt: LinkToAnotherRecordColumn;
base: Base;
@ -974,7 +971,7 @@ const deleteHmOrBtRelation = async (
childColumn: childColumn.column_name,
childTable: childTable.table_name,
parentTable: parentTable.table_name,
parentColumn: parentColumn.column_name
parentColumn: parentColumn.column_name,
// foreignKeyName: relation.fkn
});
} catch (e) {
@ -984,7 +981,7 @@ const deleteHmOrBtRelation = async (
if (!relationColOpt) return;
const columnsInRelatedTable: Column[] = await relationColOpt
.getRelatedTable()
.then(m => m.getColumns());
.then((m) => m.getColumns());
const relType = relationColOpt.type === 'bt' ? 'hm' : 'bt';
for (const c of columnsInRelatedTable) {
if (c.uidt !== UITypes.LinkToAnotherRecord) continue;
@ -1004,29 +1001,29 @@ const deleteHmOrBtRelation = async (
if (!ignoreFkDelete) {
const cTable = await Model.getWithInfo({
id: childTable.id
id: childTable.id,
});
const tableUpdateBody = {
...cTable,
tn: cTable.table_name,
originalColumns: cTable.columns.map(c => ({
originalColumns: cTable.columns.map((c) => ({
...c,
cn: c.column_name,
cno: c.column_name
cno: c.column_name,
})),
columns: cTable.columns.map(c => {
columns: cTable.columns.map((c) => {
if (c.id === childColumn.id) {
return {
...c,
cn: c.column_name,
cno: c.column_name,
altered: Altered.DELETE_COLUMN
altered: Altered.DELETE_COLUMN,
};
} else {
(c as any).cn = c.column_name;
}
return c;
})
}),
};
await sqlMgr.sqlOpPlus(base, 'tableUpdate', tableUpdateBody);
@ -1040,7 +1037,7 @@ async function createColumnIndex({
sqlMgr,
base,
indexName = null,
nonUnique = true
nonUnique = true,
}: {
column: Column;
sqlMgr: SqlMgrv2;
@ -1053,7 +1050,7 @@ async function createColumnIndex({
columns: [column.column_name],
tn: model.table_name,
non_unique: nonUnique,
indexName
indexName,
};
sqlMgr.sqlOpPlus(base, 'indexCreate', indexArgs);
}

10
packages/nocodb/src/lib/meta/api/dataApis/bulkDataAliasApis.ts

@ -14,7 +14,7 @@ async function bulkDataInsert(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.bulkInsert(req.body));
@ -27,7 +27,7 @@ async function bulkDataUpdate(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.bulkUpdate(req.body));
@ -40,7 +40,7 @@ async function bulkDataUpdateAll(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.bulkUpdateAll(req.query, req.body));
@ -52,7 +52,7 @@ async function bulkDataDelete(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.bulkDelete(req.body));
@ -64,7 +64,7 @@ async function bulkDataDeleteAll(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.bulkDeleteAll(req.query));

22
packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts

@ -33,7 +33,7 @@ async function dataCount(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const countArgs: any = { ...req.query };
@ -54,7 +54,7 @@ async function dataInsert(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.insert(req.body, null, req));
@ -67,7 +67,7 @@ async function dataUpdate(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.updateByPk(req.params.rowId, req.body, null, req));
@ -79,7 +79,7 @@ async function dataDelete(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.delByPk(req.params.rowId, null, req));
@ -90,7 +90,7 @@ async function getDataList(model, view: View, req) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const requestObj = await getAst({ model, query: req.query, view });
@ -114,7 +114,7 @@ async function getDataList(model, view: View, req) {
return new PagedResponseImpl(data, {
...req.query,
count
count,
});
}
@ -124,7 +124,7 @@ async function getFindOne(model, view: View, req) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const args: any = { ...req.query };
@ -152,7 +152,7 @@ async function getDataGroupBy(model, view: View, req) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const listArgs: any = { ...req.query };
@ -161,7 +161,7 @@ async function getDataGroupBy(model, view: View, req) {
return new PagedResponseImpl(data, {
...req.query,
count
count,
});
}
@ -173,7 +173,7 @@ async function dataRead(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(
@ -194,7 +194,7 @@ async function dataExist(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.exist(req.params.rowId));

4
packages/nocodb/src/lib/meta/api/dataApis/dataAliasExportApis.ts

@ -2,7 +2,7 @@ import { Request, Response, Router } from 'express';
import ncMetaAclMw from '../../helpers/ncMetaAclMw';
import {
extractCsvData,
getViewAndModelFromRequestByAliasOrId
getViewAndModelFromRequestByAliasOrId,
} from './helpers';
import apiMetrics from '../../helpers/apiMetrics';
import View from '../../../models/View';
@ -21,7 +21,7 @@ async function csvDataExport(req: Request, res: Response) {
'nc-export-elapsed-time': elapsed,
'Content-Disposition': `attachment; filename="${encodeURI(
targetView.title
)}-export.csv"`
)}-export.csv"`,
});
res.send(data);
}

50
packages/nocodb/src/lib/meta/api/dataApis/dataAliasNestedApis.ts

@ -18,7 +18,7 @@ export async function mmList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
@ -26,19 +26,19 @@ export async function mmList(req: Request, res: Response, next) {
const data = await baseModel.mmList(
{
colId: column.id,
parentId: req.params.rowId
parentId: req.params.rowId,
},
req.query as any
);
const count: any = await baseModel.mmListCount({
colId: column.id,
parentId: req.params.rowId
parentId: req.params.rowId,
});
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -52,14 +52,14 @@ export async function mmExcludedList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
const data = await baseModel.getMmChildrenExcludedList(
{
colId: column.id,
pid: req.params.rowId
pid: req.params.rowId,
},
req.query
);
@ -67,7 +67,7 @@ export async function mmExcludedList(req: Request, res: Response, next) {
const count = await baseModel.getMmChildrenExcludedListCount(
{
colId: column.id,
pid: req.params.rowId
pid: req.params.rowId,
},
req.query
);
@ -75,7 +75,7 @@ export async function mmExcludedList(req: Request, res: Response, next) {
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -90,7 +90,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
@ -98,7 +98,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
const data = await baseModel.getHmChildrenExcludedList(
{
colId: column.id,
pid: req.params.rowId
pid: req.params.rowId,
},
req.query
);
@ -106,7 +106,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
const count = await baseModel.getHmChildrenExcludedListCount(
{
colId: column.id,
pid: req.params.rowId
pid: req.params.rowId,
},
req.query
);
@ -114,7 +114,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -128,7 +128,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
@ -136,7 +136,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
const data = await baseModel.getBtChildrenExcludedList(
{
colId: column.id,
cid: req.params.rowId
cid: req.params.rowId,
},
req.query
);
@ -144,7 +144,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
const count = await baseModel.getBtChildrenExcludedListCount(
{
colId: column.id,
cid: req.params.rowId
cid: req.params.rowId,
},
req.query
);
@ -152,7 +152,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -166,7 +166,7 @@ export async function hmList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
@ -174,20 +174,20 @@ export async function hmList(req: Request, res: Response, next) {
const data = await baseModel.hmList(
{
colId: column.id,
id: req.params.rowId
id: req.params.rowId,
},
req.query
);
const count = await baseModel.hmListCount({
colId: column.id,
id: req.params.rowId
id: req.params.rowId,
});
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
} as any)
);
}
@ -203,7 +203,7 @@ async function relationDataRemove(req, res) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
@ -211,7 +211,7 @@ async function relationDataRemove(req, res) {
await baseModel.removeChild({
colId: column.id,
childId: req.params.refRowId,
rowId: req.params.rowId
rowId: req.params.rowId,
});
res.json({ msg: 'success' });
@ -227,14 +227,14 @@ async function relationDataAdd(req, res) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const column = await getColumnByIdOrName(req.params.columnName, model);
await baseModel.addChild({
colId: column.id,
childId: req.params.refRowId,
rowId: req.params.rowId
rowId: req.params.rowId,
});
res.json({ msg: 'success' });
@ -242,7 +242,7 @@ async function relationDataAdd(req, res) {
async function getColumnByIdOrName(columnNameOrId: string, model: Model) {
const column = (await model.getColumns()).find(
c =>
(c) =>
c.title === columnNameOrId ||
c.id === columnNameOrId ||
c.column_name === columnNameOrId

114
packages/nocodb/src/lib/meta/api/dataApis/dataApis.ts

@ -14,7 +14,7 @@ export async function dataList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -26,7 +26,7 @@ export async function mmList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -36,27 +36,27 @@ export async function mmList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const key = `${model.title}List`;
const requestObj: any = {
[key]: 1
[key]: 1,
};
const data = (
await nocoExecute(
requestObj,
{
[key]: async args => {
[key]: async (args) => {
return await baseModel.mmList(
{
colId: req.params.colId,
parentId: req.params.rowId
parentId: req.params.rowId,
},
args
);
}
},
},
{},
@ -66,13 +66,13 @@ export async function mmList(req: Request, res: Response, next) {
const count: any = await baseModel.mmListCount({
colId: req.params.colId,
parentId: req.params.rowId
parentId: req.params.rowId,
});
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -81,7 +81,7 @@ export async function mmExcludedList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -91,27 +91,27 @@ export async function mmExcludedList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const key = 'List';
const requestObj: any = {
[key]: 1
[key]: 1,
};
const data = (
await nocoExecute(
requestObj,
{
[key]: async args => {
[key]: async (args) => {
return await baseModel.getMmChildrenExcludedList(
{
colId: req.params.colId,
pid: req.params.rowId
pid: req.params.rowId,
},
args
);
}
},
},
{},
@ -122,7 +122,7 @@ export async function mmExcludedList(req: Request, res: Response, next) {
const count = await baseModel.getMmChildrenExcludedListCount(
{
colId: req.params.colId,
pid: req.params.rowId
pid: req.params.rowId,
},
req.query
);
@ -130,7 +130,7 @@ export async function mmExcludedList(req: Request, res: Response, next) {
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -139,7 +139,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -149,27 +149,27 @@ export async function hmExcludedList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const key = 'List';
const requestObj: any = {
[key]: 1
[key]: 1,
};
const data = (
await nocoExecute(
requestObj,
{
[key]: async args => {
[key]: async (args) => {
return await baseModel.getHmChildrenExcludedList(
{
colId: req.params.colId,
pid: req.params.rowId
pid: req.params.rowId,
},
args
);
}
},
},
{},
@ -180,7 +180,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
const count = await baseModel.getHmChildrenExcludedListCount(
{
colId: req.params.colId,
pid: req.params.rowId
pid: req.params.rowId,
},
req.query
);
@ -188,7 +188,7 @@ export async function hmExcludedList(req: Request, res: Response, next) {
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -197,7 +197,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -207,27 +207,27 @@ export async function btExcludedList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const key = 'List';
const requestObj: any = {
[key]: 1
[key]: 1,
};
const data = (
await nocoExecute(
requestObj,
{
[key]: async args => {
[key]: async (args) => {
return await baseModel.getBtChildrenExcludedList(
{
colId: req.params.colId,
cid: req.params.rowId
cid: req.params.rowId,
},
args
);
}
},
},
{},
@ -238,7 +238,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
const count = await baseModel.getBtChildrenExcludedListCount(
{
colId: req.params.colId,
cid: req.params.rowId
cid: req.params.rowId,
},
req.query
);
@ -246,7 +246,7 @@ export async function btExcludedList(req: Request, res: Response, next) {
res.json(
new PagedResponseImpl(data, {
count,
...req.query
...req.query,
})
);
}
@ -255,7 +255,7 @@ export async function hmList(req: Request, res: Response, next) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -265,27 +265,27 @@ export async function hmList(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const key = `${model.title}List`;
const requestObj: any = {
[key]: 1
[key]: 1,
};
const data = (
await nocoExecute(
requestObj,
{
[key]: async args => {
[key]: async (args) => {
return await baseModel.hmList(
{
colId: req.params.colId,
id: req.params.rowId
id: req.params.rowId,
},
args
);
}
},
},
{},
{ nested: { [key]: req.query } }
@ -294,12 +294,12 @@ export async function hmList(req: Request, res: Response, next) {
const count = await baseModel.hmListCount({
colId: req.params.colId,
id: req.params.rowId
id: req.params.rowId,
});
res.json(
new PagedResponseImpl(data, {
totalRows: count
totalRows: count,
} as any)
);
}
@ -307,7 +307,7 @@ export async function hmList(req: Request, res: Response, next) {
async function dataRead(req: Request, res: Response, next) {
try {
const model = await Model.getByIdOrName({
id: req.params.viewId
id: req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -315,7 +315,7 @@ async function dataRead(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(
@ -335,7 +335,7 @@ async function dataRead(req: Request, res: Response, next) {
async function dataInsert(req: Request, res: Response, next) {
try {
const model = await Model.getByIdOrName({
id: req.params.viewId
id: req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -343,7 +343,7 @@ async function dataInsert(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.insert(req.body, null, req));
@ -382,7 +382,7 @@ async function dataInsert(req: Request, res: Response, next) {
async function dataUpdate(req: Request, res: Response, next) {
try {
const model = await Model.getByIdOrName({
id: req.params.viewId
id: req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -390,7 +390,7 @@ async function dataUpdate(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.updateByPk(req.params.rowId, req.body, null, req));
@ -415,7 +415,7 @@ async function dataUpdate(req: Request, res: Response, next) {
async function dataDelete(req: Request, res: Response, next) {
try {
const model = await Model.getByIdOrName({
id: req.params.viewId
id: req.params.viewId,
});
if (!model) return next(new Error('Table not found'));
@ -423,7 +423,7 @@ async function dataDelete(req: Request, res: Response, next) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.delByPk(req.params.rowId, null, req));
@ -439,7 +439,7 @@ async function getDataList(model, view: View, req) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const requestObj = await getAst({ query: req.query, model, view });
@ -463,7 +463,7 @@ async function getDataList(model, view: View, req) {
return new PagedResponseImpl(data, {
count,
...req.query
...req.query,
});
}
//@ts-ignore
@ -471,7 +471,7 @@ async function relationDataDelete(req, res) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) NcError.notFound('Table not found');
@ -481,13 +481,13 @@ async function relationDataDelete(req, res) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
await baseModel.removeChild({
colId: req.params.colId,
childId: req.params.childId,
rowId: req.params.rowId
rowId: req.params.rowId,
});
res.json({ msg: 'success' });
@ -498,7 +498,7 @@ async function relationDataAdd(req, res) {
const view = await View.get(req.params.viewId);
const model = await Model.getByIdOrName({
id: view?.fk_model_id || req.params.viewId
id: view?.fk_model_id || req.params.viewId,
});
if (!model) NcError.notFound('Table not found');
@ -508,13 +508,13 @@ async function relationDataAdd(req, res) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
await baseModel.addChild({
colId: req.params.colId,
childId: req.params.childId,
rowId: req.params.rowId
rowId: req.params.rowId,
});
res.json({ msg: 'success' });

37
packages/nocodb/src/lib/meta/api/dataApis/helpers.ts

@ -24,13 +24,13 @@ export async function getViewAndModelFromRequestByAliasOrId(
const model = await Model.getByAliasOrId({
project_id: project.id,
base_id: project.bases?.[0]?.id,
aliasOrId: req.params.tableName
aliasOrId: req.params.tableName,
});
const view =
req.params.viewName &&
(await View.getByTitleOrId({
titleOrId: req.params.viewName,
fk_model_id: model.id
fk_model_id: model.id,
}));
if (!model) NcError.notFound('Table not found');
return { model, view };
@ -43,17 +43,17 @@ export async function extractCsvData(view: View, req: Request) {
await view.getColumns();
view.model.columns = view.columns
.filter(c => c.show)
.filter((c) => c.show)
.map(
c =>
(c) =>
new Column({ ...c, ...view.model.columnsById[c.fk_column_id] } as any)
)
.filter(column => !isSystemColumn(column) || view.show_system_fields);
.filter((column) => !isSystemColumn(column) || view.show_system_fields);
const baseModel = await Model.getBaseModelSQL({
id: view.model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
let offset = +req.query.offset || 0;
@ -76,7 +76,7 @@ export async function extractCsvData(view: View, req: Request) {
query: req.query,
includePkByDefault: false,
model: view.model,
view
view,
}),
await baseModel.list({ ...req.query, offset, limit }),
{},
@ -95,7 +95,7 @@ export async function extractCsvData(view: View, req: Request) {
if (isSystemColumn(column) && !view.show_system_fields) continue;
csvRow[column.title] = await serializeCellValue({
value: row[column.title],
column
column,
});
}
csvRows.push(csvRow);
@ -104,11 +104,11 @@ export async function extractCsvData(view: View, req: Request) {
const data = papaparse.unparse(
{
fields: view.model.columns.map(c => c.title),
data: csvRows
fields: view.model.columns.map((c) => c.title),
data: csvRows,
},
{
escapeFormulae: true
escapeFormulae: true,
}
);
@ -117,7 +117,7 @@ export async function extractCsvData(view: View, req: Request) {
export async function serializeCellValue({
value,
column
column,
}: {
column?: Column;
value: any;
@ -138,7 +138,7 @@ export async function serializeCellValue({
} catch {}
return (data || []).map(
attachment =>
(attachment) =>
`${encodeURI(attachment.title)}(${encodeURI(attachment.url)})`
);
}
@ -148,10 +148,10 @@ export async function serializeCellValue({
const lookupColumn = await colOptions.getLookupColumn();
return (
await Promise.all(
[...(Array.isArray(value) ? value : [value])].map(async v =>
[...(Array.isArray(value) ? value : [value])].map(async (v) =>
serializeCellValue({
value: v,
column: lookupColumn
column: lookupColumn,
})
)
)
@ -160,13 +160,12 @@ export async function serializeCellValue({
break;
case UITypes.LinkToAnotherRecord:
{
const colOptions = await column.getColOptions<
LinkToAnotherRecordColumn
>();
const colOptions =
await column.getColOptions<LinkToAnotherRecordColumn>();
const relatedModel = await colOptions.getRelatedTable();
await relatedModel.getColumns();
return [...(Array.isArray(value) ? value : [value])]
.map(v => {
.map((v) => {
return v[relatedModel.primaryValue?.title];
})
.join(', ');

2
packages/nocodb/src/lib/meta/api/dataApis/index.ts

@ -11,5 +11,5 @@ export {
dataAliasApis,
bulkDataAliasApis,
dataAliasNestedApis,
dataAliasExportApis
dataAliasExportApis,
};

22
packages/nocodb/src/lib/meta/api/dataApis/oldDataApis.ts

@ -17,13 +17,13 @@ export async function dataList(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const requestObj = await getAst({
query: req.query,
model,
view
view,
});
const listArgs: any = { ...req.query };
@ -50,7 +50,7 @@ export async function dataCount(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
const listArgs: any = { ...req.query };
@ -61,7 +61,7 @@ export async function dataCount(req: Request, res: Response) {
const count = await baseModel.count(listArgs);
res.json({
count
count,
});
}
@ -73,7 +73,7 @@ async function dataInsert(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.insert(req.body, null, req));
@ -86,7 +86,7 @@ async function dataUpdate(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.updateByPk(req.params.rowId, req.body, null, req));
@ -98,7 +98,7 @@ async function dataDelete(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(await baseModel.delByPk(req.params.rowId, null, req));
@ -109,13 +109,13 @@ async function getViewAndModelFromRequest(req) {
const model = await Model.getByAliasOrId({
project_id: project.id,
base_id: project.bases?.[0]?.id,
aliasOrId: req.params.tableName
aliasOrId: req.params.tableName,
});
const view =
req.params.viewName &&
(await View.getByTitleOrId({
titleOrId: req.params.viewName,
fk_model_id: model.id
fk_model_id: model.id,
}));
if (!model) NcError.notFound('Table not found');
return { model, view };
@ -129,7 +129,7 @@ async function dataRead(req: Request, res: Response) {
const baseModel = await Model.getBaseModelSQL({
id: model.id,
viewId: view?.id,
dbDriver: NcConnectionMgrv2.get(base)
dbDriver: NcConnectionMgrv2.get(base),
});
res.json(
@ -137,7 +137,7 @@ async function dataRead(req: Request, res: Response) {
await getAst({
query: req.query,
model,
view
view,
}),
await baseModel.readByPk(req.params.rowId),
{},

2
packages/nocodb/src/lib/meta/api/exportApis.ts

@ -13,7 +13,7 @@ async function exportCsv(req: Request, res: Response) {
'nc-export-elapsed-time': elapsed,
'Content-Disposition': `attachment; filename="${encodeURI(
view.title
)}-export.csv"`
)}-export.csv"`,
});
res.send(data);
}

10
packages/nocodb/src/lib/meta/api/filterApis.ts

@ -50,7 +50,7 @@ export async function filterChildrenRead(
try {
const filter = await Filter.parentFilterList({
viewId: req.params.viewId,
parentId: req.params.filterParentId
parentId: req.params.filterParentId,
});
res.json(filter);
@ -68,7 +68,7 @@ export async function filterCreate(
try {
const filter = await Filter.insert({
...req.body,
fk_view_id: req.params.viewId
fk_view_id: req.params.viewId,
});
Tele.emit('evt', { evt_type: 'filter:created' });
@ -84,7 +84,7 @@ export async function filterUpdate(req, res, next) {
try {
const filter = await Filter.update(req.params.filterId, {
...req.body,
fk_view_id: req.params.viewId
fk_view_id: req.params.viewId,
});
Tele.emit('evt', { evt_type: 'filter:updated' });
res.json(filter);
@ -111,7 +111,7 @@ export async function hookFilterList(
res: Response
) {
const filter = await Filter.rootFilterListByHook({
hookId: req.params.hookId
hookId: req.params.hookId,
});
res.json(filter);
@ -120,7 +120,7 @@ export async function hookFilterList(
export async function hookFilterCreate(req: Request<any, any, TableReq>, res) {
const filter = await Filter.insert({
...req.body,
fk_hook_id: req.params.hookId
fk_hook_id: req.params.hookId,
});
Tele.emit('evt', { evt_type: 'hookFilter:created' });

2
packages/nocodb/src/lib/meta/api/formViewApis.ts

@ -26,7 +26,7 @@ export async function formViewCreate(req: Request<any, any>, res) {
...req.body,
// todo: sanitize
fk_model_id: req.params.tableId,
type: ViewTypes.FORM
type: ViewTypes.FORM,
});
res.json(view);
}

2
packages/nocodb/src/lib/meta/api/galleryViewApis.ts

@ -15,7 +15,7 @@ export async function galleryViewCreate(req: Request<any, any>, res) {
...req.body,
// todo: sanitize
fk_model_id: req.params.tableId,
type: ViewTypes.GALLERY
type: ViewTypes.GALLERY,
});
res.json(view);
}

2
packages/nocodb/src/lib/meta/api/gridViewApis.ts

@ -19,7 +19,7 @@ export async function gridViewCreate(req: Request<any, any>, res) {
...req.body,
// todo: sanitize
fk_model_id: req.params.tableId,
type: ViewTypes.GRID
type: ViewTypes.GRID,
});
Tele.emit('evt', { evt_type: 'vtable:created', show_as: 'grid' });
res.json(view);

4
packages/nocodb/src/lib/meta/api/hookApis.ts

@ -27,7 +27,7 @@ export async function hookCreate(
Tele.emit('evt', { evt_type: 'webhooks:created' });
const hook = await Hook.insert({
...req.body,
fk_model_id: req.params.tableId
fk_model_id: req.params.tableId,
});
res.json(hook);
}
@ -54,7 +54,7 @@ export async function hookTest(req: Request<any, any>, res: Response) {
const {
hook,
payload: { data, user }
payload: { data, user },
} = req.body;
await invokeWebhook(
new Hook(hook),

8
packages/nocodb/src/lib/meta/api/hookFilterApis.ts

@ -34,7 +34,7 @@ export async function filterList(
) {
try {
const filter = await Filter.rootFilterListByHook({
hookId: req.params.hookId
hookId: req.params.hookId,
});
res.json(filter);
@ -52,7 +52,7 @@ export async function filterChildrenRead(
try {
const filter = await Filter.parentFilterListByHook({
hookId: req.params.hookId,
parentId: req.params.filterParentId
parentId: req.params.filterParentId,
});
res.json(filter);
@ -70,7 +70,7 @@ export async function filterCreate(
try {
const filter = await Filter.insert({
...req.body,
fk_hook_id: req.params.hookId
fk_hook_id: req.params.hookId,
});
Tele.emit('evt', { evt_type: 'hookFilter:created' });
@ -86,7 +86,7 @@ export async function filterUpdate(req, res, next) {
try {
const filter = await Filter.update(req.params.filterId, {
...req.body,
fk_hook_id: req.params.hookId
fk_hook_id: req.params.hookId,
});
Tele.emit('evt', { evt_type: 'hookFilter:updated' });
res.json(filter);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save