Skip to content

Commit

Permalink
Merge pull request #10 from seatable/optimize-query-api
Browse files Browse the repository at this point in the history
Optimize query api
  • Loading branch information
shuntian authored Oct 21, 2023
2 parents 1eff9c7 + db035a7 commit 14eabcb
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 12 deletions.
13 changes: 12 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"homepage": "https://github.com/seatable/seatable-api-js#readme",
"dependencies": {
"@babel/runtime": "7.20.13",
"axios": "0.23.0"
"axios": "0.23.0",
"dayjs": "1.11.10"
},
"devDependencies": {
"@babel/cli": "7.15.7",
Expand Down
13 changes: 5 additions & 8 deletions src/base.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import axios from "axios";
import { getAccessToken } from './utils';
import { formatQueryResult, getAccessToken } from './utils';

class Base {

Expand Down Expand Up @@ -65,11 +65,6 @@ class Base {
}
}

if (method === 'post' && lastPath === 'query') {
result = data.results;
return result;
}

return result;
}

Expand Down Expand Up @@ -365,9 +360,11 @@ class Base {
query(sql) {
const url = `api/v1/dtables/${this.dtableUuid}/query/`;
const data = {sql: sql};
return this.req.post(url, {...data});
return this.req.post(url, {...data}).then(result => {
return Promise.resolve(formatQueryResult(result));
});
}

}

export default Base;
export default Base;
10 changes: 9 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const ColumnTypes = {
FILE: 'file',
COLLABORATOR: 'collaborator',
LINK: 'link',
LINK_FORMULA: 'link-formula',
FORMULA: 'formula',
CREATOR: 'creator',
CTIME: 'ctime',
Expand All @@ -20,7 +21,14 @@ const ColumnTypes = {
URL: 'url',
};

const DATE_FORMAT_MAP = {
YYYY_MM_DD: 'YYYY-MM-DD',
YYYY_MM_DD_HH_MM: 'YYYY-MM-DD HH:mm',
YYYY_MM_DD_HH_MM_SS: 'YYYY-MM-DD HH:mm:ss'
};

export {
ColumnTypes
ColumnTypes,
DATE_FORMAT_MAP,
};

53 changes: 53 additions & 0 deletions src/utils/date.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import dayjs from 'dayjs';

/**
* Get formatted date
* @param {string} date e.g. "2023-07-06 11:30"
* @param {string} format e.g. "YYYY-MM-DD"
* @returns formatted date, string
*/
const getDateDisplayString = (date, format) => {
if (!date || typeof date !== 'string') {
return '';
}

const dateObj = dayjs(date);
if (!dateObj.isValid()) return date;
switch (format) {
case 'D/M/YYYY':
case 'DD/MM/YYYY': {
const formatValue = dateObj.format('YYYY-MM-DD');
const formatValueList = formatValue.split('-');
return `${formatValueList[2]}/${formatValueList[1]}/${formatValueList[0]}`;
}
case 'D/M/YYYY HH:mm':
case 'DD/MM/YYYY HH:mm': {
const formatValues = dateObj.format('YYYY-MM-DD HH:mm');
const formatValuesList = formatValues.split(' ');
const formatDateList = formatValuesList[0].split('-');
return `${formatDateList[2]}/${formatDateList[1]}/${formatDateList[0]} ${formatValuesList[1]}`;
}
case 'M/D/YYYY':
return dateObj.format('M/D/YYYY');
case 'M/D/YYYY HH:mm':
return dateObj.format('M/D/YYYY HH:mm');
case 'YYYY-MM-DD':
return dateObj.format('YYYY-MM-DD');
case 'YYYY-MM-DD HH:mm':
return dateObj.format('YYYY-MM-DD HH:mm');
case 'YYYY-MM-DD HH:mm:ss': {
return dateObj.format('YYYY-MM-DD HH:mm:ss');
}
case 'DD.MM.YYYY':
return dateObj.format('DD.MM.YYYY');
case 'DD.MM.YYYY HH:mm':
return dateObj.format('DD.MM.YYYY HH:mm');
default:
// Compatible with older versions: if format is null, use defaultFormat
return dateObj.format('YYYY-MM-DD');
}
};

export {
getDateDisplayString,
};
68 changes: 67 additions & 1 deletion src/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import axios from "axios";
import { ColumnTypes } from "../constants";
import { getDateDisplayString } from "./date";

const getAccessToken = (config) => {
const { server, APIToken } = config;
Expand All @@ -7,6 +9,70 @@ const getAccessToken = (config) => {
return axios.get(url, { headers: headers });
};

const formatQueryResult = (result) => {
const { metadata: columns, results: rows } = result;
const columnMap = columns.reduce((keyMap, column) => {
if (column.type === ColumnTypes.SINGLE_SELECT || column.type === ColumnTypes.MULTIPLE_SELECT) {
const { options = [] } = column.data || {};
let options_map = {};
options.forEach(option => {
options_map[option.id] = option.name;
});
column.options_map = options_map;
}
keyMap[column.key] = column;
return keyMap;
}, {});

let formatRows = [];
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
const formatRow = {};
formatRow['_id'] = row._id;
Object.keys(row).forEach(key => {
if (columnMap[key]) {
const { name, type, options_map, data = {} } = columnMap[key];
let cellValue = row[key];
switch(type) {
case ColumnTypes.SINGLE_SELECT: {
cellValue = options_map[cellValue];
break;
}
case ColumnTypes.MULTIPLE_SELECT: {
if (!Array.isArray(cellValue)) return [];
cellValue = cellValue.map(key => options_map[key]);
break;
}
case ColumnTypes.LINK:
case ColumnTypes.LINK_FORMULA: {
if (!Array.isArray(cellValue)) {
cellValue = [];
} else {
cellValue = cellValue.map(item => item.display_value);
}
break;
}
case ColumnTypes.DATE: {
if (cellValue) {
const { format } = data;
cellValue = getDateDisplayString(cellValue, format);
}
break;
}
default: {
cellValue = row[key];
break;
}
}
formatRow[name] = cellValue;
}
});
formatRows.push(formatRow);
}
return formatRows;
}

export {
getAccessToken
getAccessToken,
formatQueryResult
}
17 changes: 17 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fs = require('fs')
const { Base } = require('../lib');

const config = {
server: 'http://127.0.0.1',
APIToken: '41c667e75ff105563fbea5cf59cb3549d37e51c0'
};


async function testAPI() {
const base = new Base(config);
await base.auth();
const data = await base.query('select * from Table1');
fs.writeFileSync('./abc.json', JSON.stringify(data, null, 2))
}

testAPI();

0 comments on commit 14eabcb

Please sign in to comment.