package com.smtaiserver.smtaiserver.javaai.duckdb;
|
|
import java.util.HashSet;
|
import java.util.LinkedHashMap;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.Map.Entry;
|
import java.util.Set;
|
|
import com.smtaiserver.smtaiserver.core.SMTAIServerApp;
|
import com.smtaiserver.smtaiserver.core.SMTAIServerRequest;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecord;
|
import com.smtaiserver.smtaiserver.database.SMTDatabase.DBRecords;
|
import com.smtaiserver.smtaiserver.javaai.ast.ASTDimFilter;
|
import com.smtaiserver.smtaiserver.javaai.duckdb.DuckCubeRecs.DuckCubeColTitle;
|
import com.smtaiserver.smtaiserver.javaai.metrics.base.SMTDimensionDef;
|
import com.smtservlet.util.SMTJsonWriter;
|
import com.smtservlet.util.SMTStatic;
|
|
public class DuckMergeGroupRecord extends DuckMergeGroup
|
{
|
private static class OutputColInfo
|
{
|
public String _title;
|
public String _name;
|
public boolean _isGroup;
|
public int _pos;
|
public boolean _showColumn;
|
public boolean _isCount;
|
|
public OutputColInfo(String name, String title, boolean isGroup, boolean showColumn, int pos)
|
{
|
_title = title;
|
_name = name;
|
_isGroup = isGroup;
|
_pos = pos;
|
_showColumn = showColumn;
|
}
|
}
|
|
public String _posXColName;
|
public String _posYColName;
|
public String _devKeyColName;
|
public DuckCubeRecs _astCubeRecs;
|
public List<ASTDimFilter> _listDimFilter;
|
|
@SuppressWarnings("unused")
|
private String getStartDate()
|
{
|
if(_astCubeRecs._timeRange != null && _astCubeRecs._timeRange._startTime != null)
|
return SMTStatic.toString(_astCubeRecs._timeRange._startTime).substring(0, 11);
|
|
return "";
|
}
|
|
private void outputDimFilterToJson(Set<String> setDimNames, DBRecords recsMeta, SMTJsonWriter jsonWr)
|
{
|
if(_listDimFilter != null && _listDimFilter.size() > 0)
|
{
|
jsonWr.beginArray("filter");
|
for(ASTDimFilter dimFilter : _listDimFilter)
|
{
|
if(!recsMeta.getFieldMap().containsKey(dimFilter._dimDef.getId().toUpperCase()) &&
|
!setDimNames.contains(dimFilter._dimDef.getId()))
|
continue;
|
|
jsonWr.beginMap(null);
|
{
|
String type;
|
switch(dimFilter._dimDef.getType())
|
{
|
case 'T':
|
type = "time";
|
break;
|
|
default:
|
type = "string";
|
break;
|
}
|
|
jsonWr.addKeyValue("type", type);
|
jsonWr.addKeyValue("update", "set");
|
jsonWr.addKeyValue("title", dimFilter._dimDef.getName());
|
List<String> listValue = dimFilter._dimDef.getValueList();
|
if(listValue != null)
|
{
|
jsonWr.beginArray("value_list");
|
for(String value : listValue)
|
{
|
jsonWr.addKeyValue(null, value);
|
}
|
jsonWr.endArray();
|
}
|
|
jsonWr.beginArray("path");
|
{
|
jsonWr.addKeyValue(null, dimFilter._dimPath);
|
}
|
jsonWr.endArray();
|
}
|
jsonWr.endMap();
|
}
|
jsonWr.endArray();
|
}
|
|
if(_astCubeRecs._timeRange != null)
|
{
|
jsonWr.beginArray("filter");
|
{
|
jsonWr.beginMap(null);
|
{
|
jsonWr.addKeyValue("type", "time_range");
|
jsonWr.addKeyValue("update", "set");
|
jsonWr.addKeyValue("title", "时间范围");
|
jsonWr.addKeyValue("start_value", _astCubeRecs._timeRange._startTime);
|
jsonWr.addKeyValue("end_value", _astCubeRecs._timeRange._endTime);
|
|
long deltaDays = (_astCubeRecs._timeRange._endTime.getTime() - _astCubeRecs._timeRange._startTime.getTime()) / 1000 / 24 / 3600 - 60;
|
jsonWr.addKeyValue("time_step", deltaDays > 0 ? "month" : "days");
|
|
jsonWr.beginArray("start_path");
|
{
|
jsonWr.addKeyValue(null, _astCubeRecs._timeRange._pathStartTime);
|
}
|
jsonWr.endArray();
|
|
jsonWr.beginArray("end_path");
|
{
|
jsonWr.addKeyValue(null, _astCubeRecs._timeRange._pathEndTime);
|
}
|
jsonWr.endArray();
|
}
|
jsonWr.endMap();
|
|
}
|
jsonWr.endArray();
|
|
}
|
|
|
}
|
|
private void outputHideColumns(LinkedHashMap<String, OutputColInfo> mapName2ColPos, SMTJsonWriter jsonWr)
|
{
|
OutputColInfo posX = null;
|
OutputColInfo posY = null;
|
OutputColInfo posDevKey = null;
|
|
if(!SMTStatic.isNullOrEmpty(_posXColName) && !SMTStatic.isNullOrEmpty(_posYColName))
|
{
|
posX = mapName2ColPos.remove(_posXColName.toUpperCase());
|
posY = mapName2ColPos.remove(_posYColName.toUpperCase());
|
}
|
|
if(!SMTStatic.isNullOrEmpty(_devKeyColName))
|
{
|
posDevKey = mapName2ColPos.remove(_devKeyColName.toUpperCase());
|
|
}
|
|
if(posX != null && posY != null)
|
{
|
jsonWr.beginMap("map");
|
{
|
posX._showColumn = false;
|
jsonWr.addKeyValue("pos_x", mapName2ColPos.size());
|
mapName2ColPos.put(_posXColName.toUpperCase(), posX);
|
|
posY._showColumn = false;
|
jsonWr.addKeyValue("pos_y", mapName2ColPos.size());
|
mapName2ColPos.put(_posYColName.toUpperCase(), posY);
|
}
|
jsonWr.endMap();
|
}
|
|
if(posDevKey != null)
|
{
|
jsonWr.beginMap("quota_chart");
|
{
|
posDevKey._showColumn = false;
|
jsonWr.addKeyValue("col", mapName2ColPos.size());
|
mapName2ColPos.put(_devKeyColName.toUpperCase(), posDevKey);
|
}
|
jsonWr.endMap();
|
}
|
}
|
|
@Override
|
public void outputGroupToJson(String agentKey, SMTAIServerRequest tranReq) throws Exception
|
{
|
SMTJsonWriter jsonWrResult = tranReq.getResultJsonWr();
|
|
int maxRecs = SMTAIServerApp.getApp().getOutputAITableMax();
|
|
// 获取排序SQL
|
String[] orderDim = tranReq.getChatOrderDimName();
|
|
|
// 打开数据库,获取字段列表
|
SMTDatabase dbResult = tranReq.getResultDB();
|
DBRecords recsMeta = dbResult.querySQL("SELECT * FROM " + _astCubeRecs._tableName + " LIMIT 0", null);
|
Map<String, SMTDimensionDef> mapId2DimDef = SMTAIServerApp.getApp().getDimensionDefMap();
|
|
jsonWrResult.beginMap(null);
|
{
|
// 设置基本信息
|
jsonWrResult.addKeyValue("type", "recordset");
|
jsonWrResult.addKeyValue("agent_key", agentKey);
|
jsonWrResult.addKeyValue("chart", "table");
|
jsonWrResult.addKeyValue("title", _title);
|
jsonWrResult.addKeyValue("max_cols", _astCubeRecs._colKeyCount);
|
|
// 获取维度列表
|
Set<String> setDimNames = new HashSet<>();
|
for(String dimName : _astCubeRecs._dimNames)
|
{
|
setDimNames.add(dimName);
|
}
|
|
// 如果存在过滤条件,则将过滤条件输出
|
this.outputDimFilterToJson(setDimNames, recsMeta, jsonWrResult);
|
|
// 生成字段名
|
LinkedHashMap<String, OutputColInfo> mapName2ColPos = new LinkedHashMap<>();
|
|
// 如果存在维度分组,则将分组字段加入
|
for(String dimName : _astCubeRecs._dimNames)
|
{
|
int pos = recsMeta.getColIndex(dimName);
|
if(pos < 0)
|
continue;
|
|
SMTDimensionDef dimDef = mapId2DimDef.get(dimName.toLowerCase());
|
String title = dimDef == null ? dimName : dimDef.getName();
|
|
mapName2ColPos.put(dimName.toUpperCase(), new OutputColInfo(dimName, title, true, true, pos));
|
}
|
|
// 如果存在时间字段,则将时间字段加入
|
if(_astCubeRecs._timeRange != null)
|
{
|
int pos = recsMeta.getColIndex(_astCubeRecs._timeRange._timeField);
|
if(pos >= 0)
|
mapName2ColPos.put(
|
_astCubeRecs._timeRange._timeField.toUpperCase(),
|
new OutputColInfo(_astCubeRecs._timeRange._timeField, "时间", false, true, pos));
|
}
|
|
// 加入其余字段
|
for(Entry<String, Integer> entry : recsMeta.getFieldMap().entrySet())
|
{
|
if(mapName2ColPos.containsKey(entry.getKey()))
|
continue;
|
|
String dimName = entry.getKey();
|
SMTDimensionDef dimDef = mapId2DimDef.get(dimName.toLowerCase());
|
|
String title;
|
boolean isCount = false;
|
if(dimDef != null)
|
{
|
title = dimDef.getName();
|
}
|
else
|
{
|
DuckCubeColTitle titleInfo = _astCubeRecs._mapCol2Title.get(entry.getKey());
|
if(titleInfo != null)
|
{
|
title = titleInfo._title;
|
isCount = titleInfo._isCount;
|
}
|
else
|
title = entry.getKey();
|
}
|
OutputColInfo colInfo = new OutputColInfo(dimName, title, false, true, entry.getValue());
|
colInfo._isCount = isCount;
|
|
mapName2ColPos.put(dimName.toUpperCase(), colInfo);
|
}
|
|
// 输出隐藏字段
|
this.outputHideColumns(mapName2ColPos, jsonWrResult);
|
|
// 输入字段名到前端
|
jsonWrResult.beginArray("cols");
|
|
int colIndex = 0;
|
int colCount = -1;
|
for(OutputColInfo colInfo : mapName2ColPos.values())
|
{
|
if(!colInfo._showColumn)
|
break;
|
|
if(colInfo._isCount)
|
colCount = colIndex;
|
|
jsonWrResult.beginMap(null);
|
{
|
jsonWrResult.addKeyValue("title", colInfo._title);
|
if(!colInfo._isGroup)
|
jsonWrResult.addKeyValue("name", colInfo._name);
|
jsonWrResult.addKeyValue("type", "text");
|
jsonWrResult.addKeyValue("group", colInfo._isGroup);
|
}
|
jsonWrResult.endMap();
|
colIndex ++;
|
}
|
jsonWrResult.endArray();
|
|
// 输出统计个数那列
|
if(colCount >= 0)
|
{
|
jsonWrResult.addKeyValue("agg_count_col", colCount);
|
}
|
|
// 生成查询SQL
|
StringBuilder sbSQL = new StringBuilder();
|
StringBuilder sbSORT = new StringBuilder();
|
sbSQL.append("SELECT * FROM " + this._astCubeRecs._tableName);
|
|
// 如果有维度,则先按维度排序
|
boolean sortInGroup = false;
|
if(_astCubeRecs._dimNames.size() > 0)
|
{
|
for(int i = 0; i < _astCubeRecs._dimNames.size(); i ++)
|
{
|
if(!mapName2ColPos.containsKey(_astCubeRecs._dimNames.get(i).toUpperCase()))
|
continue;
|
|
if(sbSORT.length() > 0)
|
sbSORT.append(",");
|
|
String dimName = _astCubeRecs._dimNames.get(i);
|
if(orderDim != null && orderDim[0].equalsIgnoreCase(dimName))
|
{
|
sortInGroup = true;
|
sbSORT.append(dimName + " " + orderDim[1]);
|
}
|
else
|
{
|
sbSORT.append(dimName);
|
}
|
}
|
}
|
|
// 如果排序字段没在分组里,则单独设置
|
if(!sortInGroup && orderDim != null && mapName2ColPos.containsKey(orderDim[0].toUpperCase()))
|
{
|
if(sbSORT.length() > 0)
|
sbSORT.append(",");
|
sbSORT.append(orderDim[0] + " " + orderDim[1]);
|
}
|
|
// 如果存在流程测排序,则加入
|
if(this._astCubeRecs._orderCol != null)
|
{
|
if(sbSORT.length() > 0)
|
sbSORT.append(",");
|
|
if(recsMeta.getColIndex(this._astCubeRecs._orderCol[0]) >= 0)
|
sbSORT.append(this._astCubeRecs._orderCol[0] + " " + this._astCubeRecs._orderCol[1]);
|
}
|
|
// 如果有时间,则按照时间排序
|
if(_astCubeRecs._timeRange != null && mapName2ColPos.containsKey(_astCubeRecs._timeRange._timeField.toUpperCase()))
|
{
|
if(sbSORT.length() > 0)
|
sbSORT.append(",");
|
sbSORT.append(_astCubeRecs._timeRange._timeField);
|
}
|
|
// 组织出最终的查询sql
|
String sql = sbSQL.toString() + (sbSORT.length() == 0 ? "" : " ORDER BY " + sbSORT.toString()) + " LIMIT " + maxRecs;
|
|
// 查询结果并输出
|
jsonWrResult.beginArray("values");
|
dbResult.querySQLNotify(sql, null, new SMTDatabase.DBQueryNotify()
|
{
|
@Override
|
public boolean onNextRecord(DBRecord rec) throws Exception
|
{
|
jsonWrResult.beginArray(null);
|
for(OutputColInfo colInfo : mapName2ColPos.values())
|
{
|
jsonWrResult.addKeyValue(null, rec.getString(colInfo._pos));
|
}
|
jsonWrResult.endArray();
|
return true;
|
}
|
|
});
|
jsonWrResult.endArray();
|
}
|
jsonWrResult.endMap();
|
|
}
|
}
|