-
Notifications
You must be signed in to change notification settings - Fork 34
Expand file tree
/
Copy pathindex.php
More file actions
executable file
·506 lines (435 loc) · 26.3 KB
/
index.php
File metadata and controls
executable file
·506 lines (435 loc) · 26.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
<html>
<head>
<title>SQL测试数据生成</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.staticfile.net/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.staticfile.net/bootstrap/3.3.7/js/bootstrap.bundle.js" ></script>
<link href="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/bootstrap-table/1.12.1/bootstrap-table.min.js"></script>
<!-- 下拉列表 1.3有BUG,选2.0版本 -->
<!-- <link href="https://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/css/bootstrap-select.min.css" rel="stylesheet" />-->
<!-- <link href="https://cdn.bootcss.com/bootstrap-select/1.13.0-beta/css/bootstrap-select.min.css" rel="stylesheet">-->
<!-- <script src="https://cdn.bootcss.com/bootstrap-select/1.13.0-beta/js/bootstrap-select.min.js"></script>-->
<link href="https://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/css/bootstrap-select.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/bootstrap-select/2.0.0-beta1/js/bootstrap-select.min.js"></script>
<link rel="shortcut icon" href="./favicon.png">
</head>
<style> </style>
<!--<body style="background-image: url(http://img02.tooopen.com/images/20160601/tooopen_sy_163908772474.jpg);">-->
<body style=" background-color: #f7f8fa;">
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header" >
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button> <a class="navbar-brand" href="#">SQL测试数据生成</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<!-- <li class="active">-->
<!-- <a href="#">Link</a>-->
<!-- </li>-->
</ul>
<ul class="nav navbar-nav navbar-left">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">切换语言<strong class="caret"></strong></a>
<ul class="dropdown-menu">
<li>
<a id="btn_to_chinese" href="./" >中文</a>
</li>
<li>
<a id="btn_to_english" href="./index_en.php">English</a>
</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">保存配置<strong class="caret"></strong></a>
<ul class="dropdown-menu">
<li>
<a id="btn_import" href="javascript:void(0);" onclick="onImportBtnClick()" >导入配置</a>
</li>
<li>
<a id="btn_export" href="#">导出配置</a>
</li>
<!-- <li class="divider">-->
<!-- </li>-->
<!-- <li>-->
<!-- <a href="#">Separated link</a>-->
<!-- </li>-->
</ul>
</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://github.com/wintercoder/datamaker" target="_blank" >Github</a>
</li>
</ul>
</div>
</nav>
<form role="form" >
<div class="form-group">
<label>SQL表结构</label>
<!-- <label style="font-size:12px" class="label label-info">SQL表结构</label>-->
<span class="help-block"> 从 show create table tablename 获得</span>
<textarea id="sql_create" class="form-control" rows="3"
placeholder='CREATE TABLE `im_feed_reply` (
`id` int(11) NOT NULL AUTO_INCREMENT,
) ENGINE=InnoDB AUTO_INCREMENT=1;
'></textarea>
</div>
<button onclick="return false" id="btn_get_default" class="btn btn-default btn-info">下一步</button>
<!--导入导出 已放右上角-->
<!-- <button onclick="return false" id="btn_export" class="btn btn-default btn-info">导出</button>-->
<!-- <button id="btn_import" onclick="onImportBtnClick()" class="btn btn-default btn-info">导入</button>-->
<!--导入时用于传文件的隐藏按钮-->
<input type="file" id="btn_import_hidden" style="display:none">
<!--return false 禁用点击跳转,由js控制,避免点击后刷新页面-->
</form>
<script type="text/javascript" charset="utf-8" >
// 导入: 点击按钮时 触发上传文件
function onImportBtnClick() {
$("#btn_import_hidden").click();
}
// 导入
$("#btn_import_hidden").on("change", function() {
//读取文件内容,转成对象,填充表格
let fileReader = new FileReader();
fileReader.onload = function(e) {
var fileContent = e.target.result;
var jsonObj = JSON.parse(fileContent);
console.log("上传内容:");
console.log(jsonObj);
//这几行关键,否则导入后可能不展示
fillTabelWithData(jsonObj,true);
showTime = 400;
$('#select_table').show(showTime);
$('#btn_group_gen').show(showTime);
$('#tv_group_result').show(showTime);
};
fileReader.readAsText(this.files[0],'utf8');
});
</script>
<!--字段 生成规则 表格-->
<table id="select_table" hidden class="table table-striped" >
<thead >
<tr >
<th data-field="key">列名</th>
<th data-field="method">生成规则</th>
<th data-field="method_option">参数</th>
</tr>
</thead>
<tbody id ="table_tr">
</tbody>
</table>
<!-- 配置 -->
<div id="btn_group_gen" hidden>
<!-- 生成SQL的条数等 -->
<div class="col-md-2 column" >
<button id="btn_commit_sql" type="submit" class="btn btn-info btn-default">生成SQL语句</button>
<input type="checkbox" name="cb_is_download" value="is_download" /> 下载
</div>
<div class="col-md-4 column" >
<form class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-3">
<input type="number" class="form-control" id="tv_count" value="2"/>
</div>
<label class="col-3 control-label">条SQL</label>
</div>
</form>
</div>
<div class="col-md-4 column">
<form class="form-horizontal" role="form">
<div class="form-group">
<div class="col-sm-3 " >
<input type="number" class="form-control" id="tv_group_size" value="3"/>
</div>
<label class="col-2 control-label">行记录合并成一组</label>
</div>
</form>
</div>
<div class="col-md-2 column ">
<form class="form-horizontal form-inline" role="form">
<label class="form-label ">重复Key</label>
<select class="form-horizontal form-control col-xs-12 selectpicker" id="selectpicker_insertway" >
<option value="INSERT INTO " >不处理</option>
<option value="INSERT IGNORE " >跳过</option>
<option value="REPLACE INTO " >替换</option>
</select>
</form>
</div>
</div>
<input type="text" id="tv_tablename_hidden" value="我是表名" style="display:none" > <!-- 存放表名的隐藏字段-->
<script type="text/javascript">
function getList(){
//默认隐藏各种框
var showTime = 400;
$('#select_table').show(showTime);
$('#btn_group_gen').show(showTime);
$('#tv_group_result').show(showTime);
// jquery ajax 请求
$.getJSON({
type:'post',
url :"./sqlparse.php",
data:{
sql: $('#sql_create').val() //输入的SQL表结构字符串
},success:function(response,status){
fillTabelWithData(response.data,false);
},error:function(data,statsu){
alert("网络获取默认值失败!");
}
})
}
//根据数据填充表格,用于默认值和导入,参数样例: {"list":[{"key":"id","method":"ignore","value":""},{"key":"parent_id","method":"rand_int","value":"1,100"}]}
function fillTabelWithData(responseData,isImport) {
$('#tv_tablename_hidden').val(responseData.table_name); //隐藏框 存放表名
$('#table_tr').html('');
var str = '';
$.each(responseData.list,function(i,val){
str = '';
str = str + '<tr id=item_' + i +'>';
str = str + '<td> '+ '<input type="text" class="form-control" id="name_' + i +'" value='+val.key +'></td>';
//无法直接传对象当参数 ,也不能直接json字符串,否则跟onchange的双引号乱套,需要转码
var jsonVal = JSON.stringify(val);
jsonVal = jsonVal.replace(/"/g,'"');
var selectStr = `
<select class="form-control selectpicker" id="method_selectpicker_`+i+`" onchange="selectOnChange(this,`+ jsonVal +`)" >
<optgroup label="数字">
<option value="incr_int" >自增</option>
<option value="rand_int" >随机整数</option>
<option value="rand_float" >随机浮点</option>
<option value="incr_day" >自增日期</option>
<option value="incr_day_grouply" >自增日期(组自增)</option>
<option value="rand_timestamp" >随机时间戳</option>
<option value="rand_timestamp_mysql" >随机时间(Mysql格式)</option>
<option value="ignore" >忽略该列</option>
</optgroup>
<optgroup label="字符串">
<option value="const_str" >常量</option>
<option value="const_str_list" >常量列表(组模式)</option>
<option value="rand_str">随机字符串</option>
<option value="rand_str_list">随机字符串(指定列表)</option>
<option value="incr_str_prefix">前缀 + 数字自增</option>
<option value="rand_pic_url">图片URL</option>
</optgroup>
</select>
`;
str = str + '<td> '+selectStr+' </td>';
str = str + '<td>' + '<input type="text" id="tv_input_'+i+'" class="form-control" data-html="true" data-trigger="hover focus" data-toggle="tooltip" data-placement="top" data-content='+ getHoverContent(jsonVal) +' value="" >' +' </td>';
str = str + '</tr>';
$('#table_tr').append(str);
// 根据返回的method设置默认生成方法
$('#method_selectpicker_'+i).selectpicker();
$('#method_selectpicker_'+i).selectpicker('val',val.method);
$('#method_selectpicker_'+i).selectpicker('refresh');
$('#method_selectpicker_'+i).trigger('change'); //手动触发change事件
//设置接口返回的默认值 和 对应hover
if(isImport){
$("#tv_input_"+i).val( val.value ); //导入时才修改
}
$("#tv_input_"+i).attr('data-content',getHoverContent( val.method ));
});
//开启 hover提示功能
$(function () { $("[data-toggle='tooltip']").popover(); });
}
//对生成规则的解释,鼠标hover在文本框上时显示 http://wiki.jikexueyuan.com/project/bootstrap4/components/tooltips/#section-1
function getHoverContent(method) {
// jsonVal = jsonVal.replace(/\"/g,'"'); var jsonObj = JSON.parse(jsonVal); method = jsonObj.method;
switch (method) {
case 'incr_int':
return '输入:3 </br> 输出:3,4,5 ...';
case 'rand_int':
return "输入:1,100</br> 输出:在闭区间 [1,100] 中随机,可重复";
case 'rand_float':
return "输入:1,100,3</br> 输出:在闭区间 [1,100] 中随机浮点数,保留3位小数";
case 'incr_day':
return "输入:20180401</br> 输出:从 20180401 起日期自增,自动跨月";
case 'incr_day_grouply':
return "输入:20180401,2条SQL,3值合一组</br> 输出: <br />20180401,20180401,20180401<br />20180402,20180402,20180402<br /> 适合与常量列表组成叉积模式,生成每个子店铺每天各一个值";
case 'rand_timestamp':
return "输入:20180401,20180402</br> 输出:从 20180401 到 20180402 这两天里的随机时间戳";
case 'rand_timestamp_mysql':
return "输入:20180401,20180402</br> 输出:这两天里的随机时间 <br /> 格式: 2018-04-01 11:16:16";
case 'ignore':
return "不解释";
case 'const_str':
return "不解释";
case 'const_str_list':
return "输入:百度$#$阿里$#$腾讯;配置2条SQL,3值合一组</br> 输出: <br />百度$#$阿里$#$腾讯<br />百度$#$阿里$#$腾讯<br /> <br /> 按照列表中的元素生成,每个元素按顺序出现,输入元素间用特殊符($#$)分隔。</br> <br />以前是用逗号,但怕内容本身包含逗号</br> <br /> 有多个常量列表则并行出现,输出SQL以 min(元素个数) 为一组";
case 'rand_str':
return '输入:长度</br> 输出:随机字符串,字符集:字母表';
case 'rand_str_list':
return '输入:摩拜,ofo</br> 输出:列表里随机选,可重复';
case 'incr_str_prefix':
return '输入:小王</br> 输出:小王1,小王2';
case 'rand_pic_url':
return '输入:300,400 </br> 输出:宽300,高400的图片地址';
}
}
//选择 生成规则 时 设置默认值,打开网站第一次获取的会被网络请求的返回值覆盖,其他情况走这个逻辑
function selectOnChange(obj,params) {
var method = obj.options[obj.selectedIndex].value;
var parent = obj.parentNode.parentNode;
var brother = obj.parentNode.nextSibling;
var optionTxt = brother.children[0]; //参数文本框
//修改hints
optionTxt.placeholder = getDefaultValueByMethod(method);
//更换 生成规则 后 更新 hover
var currentId = obj.id.split('_')[2]; //当前点击第几行
$("#tv_input_"+currentId).attr('data-content',getHoverContent( method ));
//每次 修改 规则 时 看是否有 常量列表,有就限制组数文本框输入
$('#tv_group_size').attr("disabled",false);
$(".selectpicker").each(function () {
var pickerVal = $(this).val();
if(pickerVal === 'const_str_list'){
$('#tv_group_size').attr("disabled",true);
$('#tv_group_size').val("-1");
}
});
}
$(document).ready(function(){
//TODO 测试时使用,自动填充表结构
// getList();
});
//点击下一步后 根据sql 拉字段信息
$('#btn_get_default').click(function(){
getList();
});
//导出配置,遍历表格拿数据,组成跟解析SQL后的json那样
$('#btn_export').click(function() {
var fieldList = [];
$("#table_tr").find("tr").each(function(){
var tdArr = $(this).children();
var key = tdArr.eq(0).find('input').val(); //字段名
var method = tdArr.eq(1).find('select').val(); //method
var option = tdArr.eq(2).find('input').val(); //参数
var item = new Object();
item['key'] = key;
item['method'] = method;
item['value'] = option;
fieldList.push(item);
});
var exportData = new Object();
exportData['list'] = fieldList;
exportData['table_name'] = $('#tv_tablename_hidden').val();
exportData = JSON.stringify(exportData);
createAndDownloadFile("config_export.txt",exportData);
});
//提交表格,生成SQL
$(function(){
$('#btn_commit_sql').click(function(){
var params = new Object();
var fieldList = [];
var constListSize = 999999999; //常量列表的元素个数,用于固定一组SQL有多少value
//遍历tr拿表格各元素
$("#table_tr").find("tr").each(function(){
var tdArr = $(this).children();
var key = tdArr.eq(0).find('input').val(); //字段名
var method = tdArr.eq(1).find('select').val(); //method
var inputValue = tdArr.eq(2).find('input').val(); //参数
//什么都不填的时候,调接口的默认值
if(inputValue == null || inputValue == "" || inputValue == 'undefined'){
inputValue = getDefaultValueByMethod(method);
}
var item = new Object();
item['key'] = key;
item['method'] = method;
item['value'] = inputValue;
if(method == 'const_str_list'){
constListSize = Math.min(constListSize,inputValue.split('$#$').length);
}
fieldList.push(item);
});
params['insert_way'] = $('#selectpicker_insertway').val();
params['list'] = fieldList;
params['group_size'] = $('#tv_group_size').val();
params['group_size'] = params['group_size'] > 500 ? 500 : params['group_size'] ;
if(constListSize !== 999999999){ //代表存在常量列表,将值固定为列表个数
params['group_size'] = constListSize;
$('#tv_group_size').val(constListSize);
}
params['count'] = $('#tv_count').val();
if(params['count'] > 5000){
$('#sql_result').val('条数超过5000,怕小宽带撑不住,请自行搭建服务');
return;
}
var tablename = $('#tv_tablename_hidden').val();
params['table_name'] = (tablename == '' || tablename == 'undefined') ? 'table_name' : tablename;
//发JSON,生成SQL
params = JSON.stringify(params);
$.post('gensql.php',params,function(data){
if( $('input[name="cb_is_download"]:checked').length == 1){ //下载框被选中
$('#sql_result').val('已触发浏览器下载');
createAndDownloadFile('datamaker_' + params['table_name'] + '.sql',data);
}else{
//正常展示
$('#sql_result').val(data);
}
});
});
});
function getDefaultValueByMethod(methodParams) {
switch (methodParams) {
case 'incr_int':
return 1;
case 'rand_int':
return '1,100';
case 'rand_float':
return '1,100,2';
case 'incr_day':
case 'incr_day_grouply':
return 20180401;
case 'ignore':
return '不生成该列,适合自增列';
case 'rand_timestamp':
case 'rand_timestamp_mysql':
return '20180401,20180404';
case 'const_str':
return 'Goolge';
case 'const_str_list':
return '百度$#$阿里$#$腾讯';
case 'rand_str':
return '5';
case 'rand_str_list':
return '摩拜,ofo,小蓝,悟空,7号电单车';
case 'incr_str_prefix':
// var incrStrPre = ['老王','射击狮','测试店','产品经理','程序员','码农','攻城狮','SB'];
// return incrStrPre[ Math.floor((incrStrPre.length-1) * Math.random()) ] ;
return 'PM-';
case 'rand_pic_url':
return '300,400';
}
}
/**
* 工具函数: 创建并下载文件,用于导出
* @param {String} fileName 文件名
* @param {String} content 文件内容
*/
function createAndDownloadFile(fileName, content) {
var aTag = document.createElement('a');
var blob = new Blob([content]);
aTag.download = fileName;
aTag.href = URL.createObjectURL(blob);
aTag.click();
URL.revokeObjectURL(blob);
}
</script>
<br/><br/><br/><br/>
<!-- SQL结果 -->
<div hidden id ="tv_group_result" class="col-md-12 column">
<textarea id="sql_result" class="form-control" placeholder="我是存放 SQL 结果的地方" rows="8" ></textarea>
</div>
</div>
</div>
</div>
<div style="height: 40px;box-sizing: border-box; position: relative;bottom: 0; width: 100%; margin-top:20px">
<div style="text-align:center;width:100%;height:50;">
<p class="copyright text-muted small">Copyright © 小光 2017. <a href="http://beian.miit.gov.cn/">你的备案号</a></p>
</div>
</div>
</body>
</html>