Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:

strategy:
matrix:
node-version: [10.x, 12.x, 14.x]
node-version: [16.x, 18.x, 20.x]

steps:
- uses: actions/checkout@v2
Expand Down
5 changes: 1 addition & 4 deletions assets/src/pages/app-dev/coms/simple-app/app-k.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import React from 'react';
import {connect} from 'dva';
import {Tooltip} from 'antd';
import {Link} from 'dva/router';
import PropTypes from 'prop-types';
import {RiseOutlined, FallOutlined, AlignLeftOutlined} from '@ant-design/icons';

import PAGES from '@lib/pages';

const getTitle = (title, app, clusterCode) => {
const getTitle = (title) => {
return (
<span>
{title} 详情
Expand Down
15 changes: 9 additions & 6 deletions assets/src/pages/app-dev/coms/simple-app/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@ import api from '@api/index';
import PAGES from '@lib/pages';
import {getStatus} from '@lib/util';
import {ADMIN_APP_CODE} from '@lib/consts';
import {useRequest} from '@lib/hooks';
import {useSysUsages, useUpdate} from '../../../sys-monitor/hooks';


import AppK from './app-k';
import VersionOp from './version-op';
Expand Down Expand Up @@ -203,7 +200,9 @@ const SimpleApp = (props) => {
clusterCode={currentClusterCode}
/>
</span>
<span className="cpu" onClick={() => {showAppUsageModal(appId, currentClusterCode)}}>
<span className="cpu" onClick={() => {
showAppUsageModal(appId, currentClusterCode);
}}>
{
isCurrWorking && (
<React.Fragment>
Expand All @@ -212,7 +211,9 @@ const SimpleApp = (props) => {
)
}
</span>
<span className="mem" onClick={() => {showAppUsageModal(appId, currentClusterCode)}}>
<span className="mem" onClick={() => {
showAppUsageModal(appId, currentClusterCode);
}}>
{
isCurrWorking && (
<React.Fragment>
Expand Down Expand Up @@ -271,7 +272,9 @@ SimpleApp.propTypes = {
usage: PropTypes.object,
zIndex: PropTypes.number,
currentClusterCode: PropTypes.string,
onAppCfg: PropTypes.func
onAppCfg: PropTypes.func,
setAppUsageAppId: PropTypes.func,
setIsAppUsageModalOpen: PropTypes.func,
};

export default SimpleApp;
Expand Down
4 changes: 2 additions & 2 deletions assets/src/pages/app-dev/coms/simple-app/version-op.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,15 @@ const VersionOp = (props) => {
<AButton
className="delete"
onClick={() => onClick(MENU_ACTIONS.DELETE, '删除')}
loading={loading === MENU_ACTIONS.DELETE ? "true" : "false"}
loading={loading === MENU_ACTIONS.DELETE ? 'true' : 'false'}
>
删除
</AButton>
<Divider type="vertical" />
<AButton
color="blue"
onClick={() => onClick(MENU_ACTIONS.START, '启动')}
loading={loading === MENU_ACTIONS.START ? "true": "false"}
loading={loading === MENU_ACTIONS.START ? 'true' : 'false'}
>
启动
</AButton>
Expand Down
3 changes: 3 additions & 0 deletions assets/src/pages/app-dev/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const AppDev = (props) => {
if (!currentClusterCode) {
return [];
}

return await api.clusterApi.status(currentClusterCode);
},
onError: (err) => {
Expand All @@ -90,7 +91,9 @@ const AppDev = (props) => {

try {
const {success} = await api.appApi.appList(currentClusterCode);

setAppList(success);

return success;
} catch (e) {
setErrCount(errCount + 1);
Expand Down
27 changes: 27 additions & 0 deletions common/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,33 @@ switch (meta.driver) {
case 'sql.js':
module.exports = require('./sql.js');
break;
case 'dmdb':
module.exports = require('./dmdb');
break;
case 'postgres':
module.exports = require('./postgres');
break;
default:
throw new Error('unknow driver, meta config error');
}

if (!module.exports.quoteIdentifier) {
module.exports.quoteIdentifier = identifier => identifier;
}

module.exports.genSqlWithParamPlaceholder = function (sqlTpl) {
if (!module.exports.placeholder) {
return sqlTpl;
}
let idx = 0;

// /\?+/g 来自 sqlstring.format
return sqlTpl.replaceAll(/\?+/g, function (mysqlPlaceholder) {
idx++;
if (module.exports.placeholder instanceof Function) {
return module.exports.placeholder(mysqlPlaceholder, idx);
} else {
return module.exports.placeholder;
}
});
};
117 changes: 117 additions & 0 deletions common/dmdb.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
'use strict';

const dmdb = require('dmdb');
const fs = require('fs');
const path = require('path');
const {Readable} = require('stream');

const log = require('./log');
const config = require('../config');
const patch = require('../ddl/patch/dmdb');

async function getDataFromReadableStream(readableStream) {
return new Promise(resolve => {
const bufList = [];

readableStream.on('data', chunk => {
bufList.push(chunk);
});
function r() {
resolve(Buffer.concat(bufList).toString());
}
readableStream.on('end', r);
readableStream.on('close', r);
readableStream.on('finish', r);
});
}

let pool;
let readyFn;
let flagReady = false;

exports.ready = async function (cb) {
if (flagReady) {
return cb();
}
readyFn = cb;
try {
if (!config.meta.user) {
config.meta.user = config.meta.username;
}
const {
host,
port,
user,
password,
database,
} = config.meta;

pool = await dmdb.createPool({
connectString: `dm://${user}:${password}@${host}:${port}/${database}?injectArray=true`,
});
const conn = await pool.getConnection();
let statments = fs.readFileSync(path.join(__dirname, '../ddl/ddl_dmdb.sql')).toString();

statments = statments.split(/\n\n/);
for (let i = 0; i < statments.length; i++) {
const sql = statments[i];

await conn.execute(sql);
}

await patch(conn);
await conn.close();
flagReady = true;
readyFn && readyFn();
} catch (err) {
log.error('dmdb ready err:', err);
readyFn(err);
}
};

exports.query = async function (sql, params, callback) {
if (!callback) {
callback = params;
params = [];
}
if (!Array.isArray(params) && Object.prototype.toString.call(params) !== '[object Object]') {
// 参数是单个值, 对应的是 mysql 中的单个位置参数绑定, dmdb 只接受数组
params = [params];
}
let conn;

// dmdb 在绑定参数有数组的情况下 sql 的开头有换行或者空格会报错
sql = sql.trim();
try {
conn = await pool.getConnection();
const result = await conn.execute(sql, params);
const rows = await dmdbResultToRows(result);

callback(null, rows);
} catch (err) {
log.error('dmdb sql err:', sql, params, err);
callback(err);
} finally {
conn && (await conn.close());
}
};

async function dmdbResultToRows(result) {
return await Promise.all((result && result.rows || []).map(async (row) => {
return await row.reduce(async (obj, cur, columnIdx) => {
obj = await obj;
if (cur instanceof Readable) {
cur = await getDataFromReadableStream(cur);
}
obj[result.metaData[columnIdx].name] = cur;

return obj;
}, {});
}));
}

const tickChar = '"';

exports.quoteIdentifier = function (identifier = '') {
return tickChar + identifier.replace(new RegExp(tickChar, 'g'), '') + tickChar;
};
72 changes: 72 additions & 0 deletions common/postgres.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict';
const {Pool} = require('pg');
const fs = require('fs');
const path = require('path');

const log = require('./log');
const config = require('../config');
const patch = require('../ddl/patch/postgres');

let pool;

let readyFn;
let flagReady = false;

// lazy open connection
exports.ready = async function (cb) {
if (flagReady) {
return cb();
}
readyFn = cb;

try {
if (!config.meta.user) {
config.meta.user = config.meta.username;
}

if (!config.meta.connectionLimit) {
config.meta.connectionLimit = 3;
}
pool = new Pool(config.meta);
// exec table create process
// TODO: export async callback function to make sure db ready before main program boot.

let statments = fs.readFileSync(path.join(__dirname, '../ddl/ddl_postgres.sql')).toString();

statments = statments.split(/\n\n/);

for (let i = 0; i < statments.length; i++) {
const st = statments[i];

await pool.query(st);
}
await patch(pool);
flagReady = true;
readyFn && readyFn();
} catch (err) {
log.error('postgres ready err:', err);
readyFn(err);
}
};

exports.query = async function (sql, params, callback) {
if (!callback) {
callback = params;
params = [];
}
if (!Array.isArray(params) && Object.prototype.toString.call(params) !== '[object Object]') {
// 参数是单个值, 对应的是 mysql 中的单个位置参数绑定, pg 只接受数组
params = [params];
}
try {
const result = await pool.query(sql, params);

callback(null, result.rows);
} catch (err) {
callback(err);
}
};

exports.placeholder = function (str, idx) {
return `$${idx}`;
};
8 changes: 8 additions & 0 deletions config/config_default.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ module.exports = {
password : 'secret',
database : 'my_db'
*/

/**
driver: 'dmdb',
host: 'localhost',
port: 5236,
user: 'user',
password: 'password',
*/
},
/**
* 发布存储及记录
Expand Down
2 changes: 1 addition & 1 deletion controller/acl.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ exports.createAcl = function (req, callback) {
}
], function (err) {
log.warn('createAcl', user, req.body);
log.error(err);
if (err) {
log.error(err);
callback({code: 'ERROR', message: '添加权限异常'});
} else {
callback();
Expand Down
Loading