<commit_before>/* 
 * Copyright 2006-2022 www.anyline.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *          
 */


package org.anyline.jdbc.config.db.impl;

 
import org.anyline.dao.PrimaryCreater;
import org.anyline.entity.AnylineEntity;
import org.anyline.entity.DataRow;
import org.anyline.entity.DataSet;
import org.anyline.jdbc.config.ConfigStore;
import org.anyline.jdbc.config.db.SQL;
import org.anyline.jdbc.config.db.SQLCreater;
import org.anyline.jdbc.config.db.run.RunSQL;
import org.anyline.jdbc.config.db.run.impl.TableRunSQLImpl;
import org.anyline.jdbc.config.db.run.impl.TextRunSQLImpl;
import org.anyline.jdbc.config.db.run.impl.XMLRunSQLImpl;
import org.anyline.jdbc.config.db.sql.auto.TableSQL;
import org.anyline.jdbc.config.db.sql.auto.TextSQL;
import org.anyline.jdbc.config.db.sql.auto.impl.TableSQLImpl;
import org.anyline.jdbc.config.db.sql.xml.XMLSQL;
import org.anyline.jdbc.ds.DataSourceHolder;
import org.anyline.jdbc.exception.SQLException;
import org.anyline.jdbc.exception.SQLUpdateException;
import org.anyline.util.BasicUtil;
import org.anyline.util.BeanUtil;
import org.anyline.util.ConfigTable;
import org.anyline.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;


/**
 * SQL生成 子类主要实现与分页相关的SQL 以及delimiter
 */

public abstract class BasicSQLCreaterImpl implements SQLCreater{
	protected static final Logger log = LoggerFactory.getLogger(BasicSQLCreaterImpl.class);
	@Autowired(required=false)
	protected PrimaryCreater primaryCreater; 
	public String delimiterFr = "";
	public String delimiterTo = "";
	public DB_TYPE type(){
		return null;
	}
	/** 
	 * 创建查询SQL 
	 */ 
	@Override 
	public RunSQL createQueryRunSQL(SQL sql, ConfigStore configs, String ... conditions){ 
		RunSQL run = null; 
		if(sql instanceof TableSQL){ 
			run = new TableRunSQLImpl(); 
		}else if(sql instanceof XMLSQL){ 
			run = new XMLRunSQLImpl();
		}else if(sql instanceof TextSQL){ 
			run = new TextRunSQLImpl(); 
		} 
		if(null != run){
			run.setStrict(sql.isStrict()); 
			run.setCreater(this); 
			run.setSql(sql);
			run.setConfigStore(configs); 
			run.addConditions(conditions);
			run.init();
			run.createRunQueryTxt();
		} 
		return run; 
	}
	@Override
	public RunSQL createExecuteRunSQL(SQL sql, ConfigStore configs, String ... conditions){
		RunSQL run = null;
		if(sql instanceof XMLSQL){
			run = new XMLRunSQLImpl();
		}else if(sql instanceof TextSQL){
			run = new TextRunSQLImpl();
		}
		if(null != run){
			run.setCreater(this);
			run.setSql(sql);
			run.setConfigStore(configs);
			run.addConditions(conditions);
			run.init();
		}
		return run;
	}
	@Override
	public RunSQL createDeleteRunSQL(String table, String key, Object values){
		return createDeleteRunSQLFromTable(table, key, values);
	}
	@Override 
	public RunSQL createDeleteRunSQL(String dest, Object obj, String ... columns){ 
		if(null == obj){ 
			return null; 
		} 
		RunSQL run = null; 
		if(null == dest){ 
			dest = DataSourceHolder.parseDataSource(dest,obj);
		}
		if(obj instanceof DataRow){
			run = createDeleteRunSQLFromDataRow(dest, (DataRow)obj, columns);
		}else if(obj instanceof ConfigStore){
			run = new TableRunSQLImpl();
			run.setCreater(this);
			SQL sql = new TableSQLImpl();
			sql.setDataSource(dest);
			run.setSql(sql);
			run.setConfigStore((ConfigStore)obj);
			run.addConditions(columns);
			run.init();
			run.createRunDeleteTxt();
		}else if(obj instanceof AnylineEntity){
			run = createDeleteRunSQLFromEntity(dest, (AnylineEntity)obj, columns);
		}
		return run; 
	}
	@SuppressWarnings("rawtypes")
	private RunSQL createDeleteRunSQLFromTable(String table, String key, Object values){
		if(null == table || null == key || null == values){
			return null;
		}
		StringBuilder builder = new StringBuilder();
		TableRunSQLImpl run = new TableRunSQLImpl();
		builder.append("DELETE FROM ").append(table).append(" WHERE ");
		if(values instanceof Collection){
			Collection cons = (Collection)values;
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			if(cons.size() > 1){
				builder.append(" IN(");
				int idx = 0;
				for(Object obj:cons){
					if(idx > 0){
						builder.append(",");
					}
					builder.append("'").append(obj).append("'");
					idx ++;
				}
				builder.append(")");
			}else if(cons.size() == 1){
				for(Object obj:cons){
					builder.append("=?");
					run.addValue(obj);
				}
			}else{
				throw new SQLUpdateException("删除异常:删除条件为空,delete方法不支持删除整表操作.");
			}
		}else{
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			builder.append("=?");
			run.addValue(values);
		}
		run.setBuilder(builder);
		return run;
	}
	private RunSQL createDeleteRunSQLFromDataRow(String dest, DataRow obj, String ... columns){ 
		TableRunSQLImpl run = new TableRunSQLImpl();
		StringBuilder builder = new StringBuilder();
		builder.append("DELETE FROM ").append(parseTable(dest)).append(" WHERE ");
		List<String> keys = new ArrayList<>();
		if(null != columns && columns.length>0){
			for(String col:columns){
				keys.add(col);
			}
		}else{
			keys = obj.getPrimaryKeys();
		}
		int size = keys.size();
		if(size >0){
			for(int i=0; i<size; i++){
				if(i > 0){
					builder.append("\nAND ");
				}
				String key = keys.get(i);
				builder.append(getDelimiterFr()).append(key).append(getDelimiterTo()).append(" = ? ");
				run.addValue(obj.get(key)); 
			}
		}else{
			throw new SQLUpdateException("删除异常:删除条件为空,delete方法不支持删除整表操作.");
		}
		run.setBuilder(builder);
		return run; 
	} 
 
	private RunSQL createDeleteRunSQLFromEntity(String dest, AnylineEntity obj, String ... columns){ 
		TableRunSQLImpl run = new TableRunSQLImpl();
		StringBuilder builder = new StringBuilder();
		builder.append("DELETE FROM ").append(parseTable(dest))
		.append(" WHERE ").append(getDelimiterFr()).append(getPrimaryKey(obj)).append(getDelimiterTo())
		.append("=?"); 
		run.addValue(getPrimaryValue(obj));
		run.setBuilder(builder);
		return run; 
	} 
 
	@Override 
	public String getPrimaryKey(Object obj){ 
		if(null == obj){ 
			return null; 
		} 
		if(obj instanceof DataRow){ 
			return ((DataRow)obj).getPrimaryKey(); 
		}else{ 
			return null; 
		} 
	} 
	@Override 
	public Object getPrimaryValue(Object obj){ 
		if(null == obj){ 
			return null; 
		} 
		if(obj instanceof DataRow){ 
			return ((DataRow)obj).getPrimaryValue(); 
		}else{ 
			return null; 
		} 
	} 
	/** 
	 * 基础查询SQL 
	 * RunSQL 反转调用 
	 */ 
	@Override 
	public String parseBaseQueryTxt(RunSQL run){ 
		return run.getBuilder().toString();
	} 
	/** 
	 * 求总数SQL 
	 * RunSQL 反转调用 
	 * @param run  run
	 * @return String
	 */
	@Override
	public String parseTotalQueryTxt(RunSQL run){
		String sql = "SELECT COUNT(0) AS CNT FROM (\n" + run.getBuilder().toString() +"\n) F";
		sql = sql.replaceAll("WHERE\\s*1=1\\s*AND", "WHERE ");
		return sql;
	}

	@Override
	public String parseExistsTxt(RunSQL run){
		String sql = "SELECT EXISTS(\n" + run.getBuilder().toString() +"\n)  IS_EXISTS";
		sql = sql.replaceAll("WHERE\\s*1=1\\s*AND", "WHERE ");
		return sql;
	}
	 
	 
 

 
	@Override 
	public RunSQL createInsertTxt(String dest, Object obj, boolean checkParimary, String ... columns){ 
		if(null == obj){ 
			return null; 
		} 
		if(null == dest){ 
			dest = DataSourceHolder.parseDataSource(dest,obj);
		}

		if(obj instanceof DataRow){
			DataRow row = (DataRow)obj;
			row.setDataSource(dest); 
			return createInsertTxtFromDataRow(dest,row,checkParimary, columns); 
		} 
		if(obj instanceof AnylineEntity){ 
			return createInsertTxtFromEntity(dest,(AnylineEntity)obj,checkParimary, columns);	 
		}
		if(obj instanceof DataSet){
			DataSet set = (DataSet)obj;
			set.setDataSource(dest);
			if(set.size() >0){
				return createInsertTxtFromDataSet(dest,set,checkParimary, columns);
			}
		}
		if(obj instanceof Collection){
			DataSet set = DataSet.parse((Collection)obj);
			set.setDataSource(dest);
			if(set.size() >0){
				return createInsertTxtFromDataSet(dest,set,checkParimary, columns);
			}
		}
		return null; 
	}
	private RunSQL createInsertTxtFromDataRow(String dest, DataRow row, boolean checkParimary, String ... columns){
		RunSQL run = new TableRunSQLImpl();
		List<Object> values = new ArrayList<Object>();
		StringBuilder builder = new StringBuilder();
		if(BasicUtil.isEmpty(dest)){
			throw new SQLException("未指定表");
		}
		StringBuilder param = new StringBuilder();
		if(row.hasPrimaryKeys() && null != primaryCreater && BasicUtil.isEmpty(row.getPrimaryValue())){
			String pk = row.getPrimaryKey();
			if(null == pk){
				pk = ConfigTable.getString("DEFAULT_PRIMARY_KEY");
			}
			row.put(pk, primaryCreater.createPrimary(type(),dest.replace(getDelimiterFr(), "").replace(getDelimiterTo(), ""), pk, null));
		}
		/*确定需要插入的列*/
		
		List<String> keys = confirmInsertColumns(dest, row, columns);
		if(null == keys || keys.size() == 0){
			throw new SQLException("未指定列");
		}
		builder.append("INSERT INTO ").append(parseTable(dest));
		builder.append("(");
		param.append(") VALUES (");
		List<String> insertColumns = new ArrayList<>();
		int size = keys.size();
		for(int i=0; i<size; i++){
			String key = keys.get(i);
			Object value = row.get(key);
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			if(null != value && value.toString().startsWith("{") && value.toString().endsWith("}") && !BeanUtil.isJson(value)){
				String str = value.toString();
				value = str.substring(1, str.length()-1);
				if(value.toString().startsWith("{") && value.toString().endsWith("}")){
					//保存json时可以{json格式}最终会有两层:{{a:1}}
					param.append("?");
					insertColumns.add(key);
					values.add(value);
				}else {
					param.append(value);
				}
			}else{
				param.append("?");
				insertColumns.add(key);
				if("NULL".equals(value)){
					values.add(null);
				}else{
					values.add(value);
				}
			}
			if(i<size-1){
				builder.append(",");
				param.append(",");
			}
		}
		param.append(")");
		builder.append(param);
		run.addValues(values);
		run.setBuilder(builder);
		run.setInsertColumns(insertColumns);
		return run;
	}
	private RunSQL createInsertTxtFromDataSet(String dest, DataSet set, boolean checkParimary, String ... columns){
		RunSQL run = new TableRunSQLImpl();

		StringBuilder builder = new StringBuilder();
		if(null == set || set.size() ==0){
			throw new SQLException("空数据");
		}
		if(BasicUtil.isEmpty(dest)){
			dest = DataSourceHolder.parseDataSource(dest,set);
		}
		if(BasicUtil.isEmpty(dest)){
			dest = DataSourceHolder.parseDataSource(dest,set.getRow(0));
		}
		if(BasicUtil.isEmpty(dest)){
			throw new SQLException("未指定表");
		}
		DataRow first = set.getRow(0);
		/*确定需要插入的列*/
		
		List<String> keys = confirmInsertColumns(dest, first, columns);
		if(null == keys || keys.size() == 0){
			throw new SQLException("未指定列");
		}
		builder.append("INSERT INTO ").append(parseTable(dest));
		builder.append("(");
		
		int keySize = keys.size();
		for(int i=0; i<keySize; i++){
			String key = keys.get(i);
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			if(i<keySize-1){
				builder.append(",");
			}
		}
		builder.append(") VALUES ");
		int dataSize = set.size();
		for(int i=0; i<dataSize; i++){
			DataRow row = set.getRow(i);
			if(null == row){
				continue;
			}
			if(row.hasPrimaryKeys() && null != primaryCreater && BasicUtil.isEmpty(row.getPrimaryValue())){
				String pk = row.getPrimaryKey();
				if(null == pk){
					pk = ConfigTable.getString("DEFAULT_PRIMARY_KEY");
				}
				row.put(pk, primaryCreater.createPrimary(type(),dest.replace(getDelimiterFr(), "").replace(getDelimiterTo(), ""), pk, null));
			}

			builder.append("(");
			for(int j=0; j<keySize; j++){
				Object value = row.get(keys.get(j));
				
				if(null == value || "NULL".equals(value)){
					builder.append("null");
				}else if(value instanceof String){
					String str = value.toString();
					if(str.startsWith("{") && str.endsWith("}") && !BeanUtil.isJson(value)){
						str = str.substring(1, str.length()-1);
					}else{
						str = "'" + str.replace("'", "''") + "'";
					}
					builder.append(str);
				}else if(value instanceof Timestamp){
					builder.append("'").append(value.toString()).append("'");
				}else if(value instanceof java.sql.Date){
					builder.append("'").append(value.toString()).append("'");
				}else if(value instanceof LocalDate){
					builder.append("'").append(value.toString()).append("'");
				}else if(value instanceof LocalTime){
					builder.append("'").append(value.toString()).append("'");
				}else if(value instanceof LocalDateTime){
					builder.append("'").append(value.toString()).append("'");
				}else if(value instanceof Date){
					builder.append("'").append(DateUtil.format((Date)value,DateUtil.FORMAT_DATE_TIME)).append("'");
				}else if(value instanceof Number || value instanceof Boolean){
					builder.append(value.toString());
				}else{
					builder.append(value.toString());
				}
				if(j<keySize-1){
					builder.append(",");
				}
			}
			builder.append(")");
			if(i<dataSize-1){
				builder.append(",");
			}
		}
		run.setBuilder(builder);
		return run;
	}
	 
	private RunSQL createInsertTxtFromEntity(String dest, AnylineEntity entity, boolean checkParimary, String ... columns){ 
		RunSQL run = new TableRunSQLImpl();
		StringBuilder builder = new StringBuilder();
		List<Object> values = new ArrayList<Object>();
		if(null == dest){ 
			dest = entity.getDataSource(); 
		} 
		if(BasicUtil.isEmpty(dest)){ 
			throw new SQLException("未指定表"); 
		}
		/*确定需要更新的列*/ 
		List<String> keys = confirmInsertColumns(dest, entity, columns);
		if(null == keys || keys.size() == 0){ 
			throw new SQLException("未指定列"); 
		}
		builder.append("INSERT INTO ").append(parseTable(dest));
		builder.append("(");
		int size = keys.size();
		List<String> insertColumns = new ArrayList<>();
		for(int i=0; i<size; i++){
			builder.append(getDelimiterFr()).append(keys.get(i)).append(getDelimiterTo());
			if(i<size-1){
				builder.append(",");
			} 
		}
		builder.append(") VALUES (");
		for(int i=0; i<size; i++){
			builder.append("?");<commit_msg>SQL Creater<commit_after>/* 
 * Copyright 2006-2022 www.anyline.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *          
 */


package org.anyline.jdbc.config.db.impl;

 
import org.anyline.dao.PrimaryCreater;
import org.anyline.entity.AnylineEntity;
import org.anyline.entity.DataRow;
import org.anyline.entity.DataSet;
import org.anyline.jdbc.config.ConfigStore;
import org.anyline.jdbc.config.db.SQL;
import org.anyline.jdbc.config.db.SQLCreater;
import org.anyline.jdbc.config.db.run.RunSQL;
import org.anyline.jdbc.config.db.run.impl.TableRunSQLImpl;
import org.anyline.jdbc.config.db.run.impl.TextRunSQLImpl;
import org.anyline.jdbc.config.db.run.impl.XMLRunSQLImpl;
import org.anyline.jdbc.config.db.sql.auto.TableSQL;
import org.anyline.jdbc.config.db.sql.auto.TextSQL;
import org.anyline.jdbc.config.db.sql.auto.impl.TableSQLImpl;
import org.anyline.jdbc.config.db.sql.xml.XMLSQL;
import org.anyline.jdbc.ds.DataSourceHolder;
import org.anyline.jdbc.exception.SQLException;
import org.anyline.jdbc.exception.SQLUpdateException;
import org.anyline.util.BasicUtil;
import org.anyline.util.BeanUtil;
import org.anyline.util.ConfigTable;
import org.anyline.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;


/**
 * SQL生成 子类主要实现与分页相关的SQL 以及delimiter
 */

public abstract class BasicSQLCreaterImpl implements SQLCreater{
	protected static final Logger log = LoggerFactory.getLogger(BasicSQLCreaterImpl.class);
	@Autowired(required=false)
	protected PrimaryCreater primaryCreater; 
	public String delimiterFr = "";
	public String delimiterTo = "";
	public DB_TYPE type(){
		return null;
	}
	/** 
	 * 创建查询SQL 
	 */ 
	@Override 
	public RunSQL createQueryRunSQL(SQL sql, ConfigStore configs, String ... conditions){ 
		RunSQL run = null; 
		if(sql instanceof TableSQL){ 
			run = new TableRunSQLImpl(); 
		}else if(sql instanceof XMLSQL){ 
			run = new XMLRunSQLImpl();
		}else if(sql instanceof TextSQL){ 
			run = new TextRunSQLImpl(); 
		} 
		if(null != run){
			run.setStrict(sql.isStrict()); 
			run.setCreater(this); 
			run.setSql(sql);
			run.setConfigStore(configs); 
			run.addConditions(conditions);
			run.init();
			run.createRunQueryTxt();
		} 
		return run; 
	}
	@Override
	public RunSQL createExecuteRunSQL(SQL sql, ConfigStore configs, String ... conditions){
		RunSQL run = null;
		if(sql instanceof XMLSQL){
			run = new XMLRunSQLImpl();
		}else if(sql instanceof TextSQL){
			run = new TextRunSQLImpl();
		}
		if(null != run){
			run.setCreater(this);
			run.setSql(sql);
			run.setConfigStore(configs);
			run.addConditions(conditions);
			run.init();
		}
		return run;
	}
	@Override
	public RunSQL createDeleteRunSQL(String table, String key, Object values){
		return createDeleteRunSQLFromTable(table, key, values);
	}
	@Override 
	public RunSQL createDeleteRunSQL(String dest, Object obj, String ... columns){ 
		if(null == obj){ 
			return null; 
		} 
		RunSQL run = null; 
		if(null == dest){ 
			dest = DataSourceHolder.parseDataSource(dest,obj);
		}
		if(obj instanceof DataRow){
			run = createDeleteRunSQLFromDataRow(dest, (DataRow)obj, columns);
		}else if(obj instanceof ConfigStore){
			run = new TableRunSQLImpl();
			run.setCreater(this);
			SQL sql = new TableSQLImpl();
			sql.setDataSource(dest);
			run.setSql(sql);
			run.setConfigStore((ConfigStore)obj);
			run.addConditions(columns);
			run.init();
			run.createRunDeleteTxt();
		}else if(obj instanceof AnylineEntity){
			run = createDeleteRunSQLFromEntity(dest, (AnylineEntity)obj, columns);
		}
		return run; 
	}
	@SuppressWarnings("rawtypes")
	private RunSQL createDeleteRunSQLFromTable(String table, String key, Object values){
		if(null == table || null == key || null == values){
			return null;
		}
		StringBuilder builder = new StringBuilder();
		TableRunSQLImpl run = new TableRunSQLImpl();
		builder.append("DELETE FROM ").append(table).append(" WHERE ");
		if(values instanceof Collection){
			Collection cons = (Collection)values;
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			if(cons.size() > 1){
				builder.append(" IN(");
				int idx = 0;
				for(Object obj:cons){
					if(idx > 0){
						builder.append(",");
					}
					builder.append("'").append(obj).append("'");
					idx ++;
				}
				builder.append(")");
			}else if(cons.size() == 1){
				for(Object obj:cons){
					builder.append("=?");
					run.addValue(obj);
				}
			}else{
				throw new SQLUpdateException("删除异常:删除条件为空,delete方法不支持删除整表操作.");
			}
		}else{
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			builder.append("=?");
			run.addValue(values);
		}
		run.setBuilder(builder);
		return run;
	}
	private RunSQL createDeleteRunSQLFromDataRow(String dest, DataRow obj, String ... columns){ 
		TableRunSQLImpl run = new TableRunSQLImpl();
		StringBuilder builder = new StringBuilder();
		builder.append("DELETE FROM ").append(parseTable(dest)).append(" WHERE ");
		List<String> keys = new ArrayList<>();
		if(null != columns && columns.length>0){
			for(String col:columns){
				keys.add(col);
			}
		}else{
			keys = obj.getPrimaryKeys();
		}
		int size = keys.size();
		if(size >0){
			for(int i=0; i<size; i++){
				if(i > 0){
					builder.append("\nAND ");
				}
				String key = keys.get(i);
				builder.append(getDelimiterFr()).append(key).append(getDelimiterTo()).append(" = ? ");
				run.addValue(obj.get(key)); 
			}
		}else{
			throw new SQLUpdateException("删除异常:删除条件为空,delete方法不支持删除整表操作.");
		}
		run.setBuilder(builder);
		return run; 
	} 
 
	private RunSQL createDeleteRunSQLFromEntity(String dest, AnylineEntity obj, String ... columns){ 
		TableRunSQLImpl run = new TableRunSQLImpl();
		StringBuilder builder = new StringBuilder();
		builder.append("DELETE FROM ").append(parseTable(dest))
		.append(" WHERE ").append(getDelimiterFr()).append(getPrimaryKey(obj)).append(getDelimiterTo())
		.append("=?"); 
		run.addValue(getPrimaryValue(obj));
		run.setBuilder(builder);
		return run; 
	} 
 
	@Override 
	public String getPrimaryKey(Object obj){ 
		if(null == obj){ 
			return null; 
		} 
		if(obj instanceof DataRow){ 
			return ((DataRow)obj).getPrimaryKey(); 
		}else{ 
			return null; 
		} 
	} 
	@Override 
	public Object getPrimaryValue(Object obj){ 
		if(null == obj){ 
			return null; 
		} 
		if(obj instanceof DataRow){ 
			return ((DataRow)obj).getPrimaryValue(); 
		}else{ 
			return null; 
		} 
	} 
	/** 
	 * 基础查询SQL 
	 * RunSQL 反转调用 
	 */ 
	@Override 
	public String parseBaseQueryTxt(RunSQL run){ 
		return run.getBuilder().toString();
	} 
	/** 
	 * 求总数SQL 
	 * RunSQL 反转调用 
	 * @param run  run
	 * @return String
	 */
	@Override
	public String parseTotalQueryTxt(RunSQL run){
		String sql = "SELECT COUNT(0) AS CNT FROM (\n" + run.getBuilder().toString() +"\n) F";
		sql = sql.replaceAll("WHERE\\s*1=1\\s*AND", "WHERE ");
		return sql;
	}

	@Override
	public String parseExistsTxt(RunSQL run){
		String sql = "SELECT EXISTS(\n" + run.getBuilder().toString() +"\n)  IS_EXISTS";
		sql = sql.replaceAll("WHERE\\s*1=1\\s*AND", "WHERE ");
		return sql;
	}
	 
	 
 

 
	@Override 
	public RunSQL createInsertTxt(String dest, Object obj, boolean checkParimary, String ... columns){ 
		if(null == obj){ 
			return null; 
		} 
		if(null == dest){ 
			dest = DataSourceHolder.parseDataSource(dest,obj);
		}

		if(obj instanceof DataRow){
			DataRow row = (DataRow)obj;
			row.setDataSource(dest); 
			return createInsertTxtFromDataRow(dest,row,checkParimary, columns); 
		} 
		if(obj instanceof AnylineEntity){ 
			return createInsertTxtFromEntity(dest,(AnylineEntity)obj,checkParimary, columns);	 
		}
		if(obj instanceof DataSet){
			DataSet set = (DataSet)obj;
			set.setDataSource(dest);
			if(set.size() >0){
				return createInsertTxtFromDataSet(dest,set,checkParimary, columns);
			}
		}
		if(obj instanceof Collection){
			DataSet set = DataSet.parse((Collection)obj);
			set.setDataSource(dest);
			if(set.size() >0){
				return createInsertTxtFromDataSet(dest,set,checkParimary, columns);
			}
		}
		return null; 
	}

	private RunSQL createInsertTxtFromDataRow(String dest, DataRow row, boolean checkParimary, String ... columns){
		RunSQL run = new TableRunSQLImpl();
		List<Object> values = new ArrayList<Object>();
		StringBuilder builder = new StringBuilder();
		if(BasicUtil.isEmpty(dest)){
			throw new SQLException("未指定表");
		}
		StringBuilder param = new StringBuilder();
		if(row.hasPrimaryKeys() && null != primaryCreater && BasicUtil.isEmpty(row.getPrimaryValue())){
			String pk = row.getPrimaryKey();
			if(null == pk){
				pk = ConfigTable.getString("DEFAULT_PRIMARY_KEY");
			}
			row.put(pk, primaryCreater.createPrimary(type(),dest.replace(getDelimiterFr(), "").replace(getDelimiterTo(), ""), pk, null));
		}
		/*确定需要插入的列*/
		
		List<String> keys = confirmInsertColumns(dest, row, columns);
		if(null == keys || keys.size() == 0){
			throw new SQLException("未指定列");
		}
		builder.append("INSERT INTO ").append(parseTable(dest));
		builder.append("(");
		param.append(") VALUES (");
		List<String> insertColumns = new ArrayList<>();
		int size = keys.size();
		for(int i=0; i<size; i++){
			String key = keys.get(i);
			Object value = row.get(key);
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			if(null != value && value.toString().startsWith("{") && value.toString().endsWith("}") && !BeanUtil.isJson(value)){
				String str = value.toString();
				value = str.substring(1, str.length()-1);
				if(value.toString().startsWith("{") && value.toString().endsWith("}")){
					//保存json时可以{json格式}最终会有两层:{{a:1}}
					param.append("?");
					insertColumns.add(key);
					values.add(value);
				}else {
					param.append(value);
				}
			}else{
				param.append("?");
				insertColumns.add(key);
				if("NULL".equals(value)){
					values.add(null);
				}else{
					values.add(value);
				}
			}
			if(i<size-1){
				builder.append(",");
				param.append(",");
			}
		}
		param.append(")");
		builder.append(param);
		run.addValues(values);
		run.setBuilder(builder);
		run.setInsertColumns(insertColumns);
		return run;
	}
	private RunSQL createInsertTxtFromDataSet(String dest, DataSet set, boolean checkParimary, String ... columns){
		RunSQL run = new TableRunSQLImpl();

		StringBuilder builder = new StringBuilder();
		if(null == set || set.size() ==0){
			throw new SQLException("空数据");
		}
		if(BasicUtil.isEmpty(dest)){
			dest = DataSourceHolder.parseDataSource(dest,set);
		}
		if(BasicUtil.isEmpty(dest)){
			dest = DataSourceHolder.parseDataSource(dest,set.getRow(0));
		}
		if(BasicUtil.isEmpty(dest)){
			throw new SQLException("未指定表");
		}
		DataRow first = set.getRow(0);
		/*确定需要插入的列*/
		
		List<String> keys = confirmInsertColumns(dest, first, columns);
		if(null == keys || keys.size() == 0){
			throw new SQLException("未指定列");
		}
		createInsertsTxt(builder, dest, set, keys);
		run.setBuilder(builder);
		return run;
	}

	@Override
	public void createInsertsTxt(StringBuilder builder, String dest, DataSet set,  List<String> keys){
		builder.append("INSERT INTO ").append(parseTable(dest));
		builder.append("(");

		int keySize = keys.size();
		for(int i=0; i<keySize; i++){
			String key = keys.get(i);
			builder.append(getDelimiterFr()).append(key).append(getDelimiterTo());
			if(i<keySize-1){
				builder.append(",");
			}
		}
		builder.append(") VALUES ");
		int dataSize = set.size();
		for(int i=0; i<dataSize; i++){
			DataRow row = set.getRow(i);
			if(null == row){
				continue;
			}
			if(row.hasPrimaryKeys() && null != primaryCreater && BasicUtil.isEmpty(row.getPrimaryValue())){
				String pk = row.getPrimaryKey();
				if(null == pk){
					pk = ConfigTable.getString("DEFAULT_PRIMARY_KEY");
				}
				row.put(pk, primaryCreater.createPrimary(type(),dest.replace(getDelimiterFr(), "").replace(getDelimiterTo(), ""), pk, null));
			}
			insertValue(builder, row, keys);
			if(i<dataSize-1){
				builder.append(",");
			}
		}
	}

	/**
	 * 生成insert sql的value部分
	 * @param builder builder
	 * @param row row
	 * @param keys keys
	 */
	protected void insertValue(StringBuilder builder, DataRow row, List<String> keys){
		int keySize = keys.size();
		builder.append("(");
		for(int j=0; j<keySize; j++){
			Object value = row.get(keys.get(j));

			if(null == value || "NULL".equals(value)){
				builder.append("null");
			}else if(value instanceof String){
				String str = value.toString();
				if(str.startsWith("{") && str.endsWith("}") && !BeanUtil.isJson(value)){
					str = str.substring(1, str.length()-1);
				}else{
					str = "'" + str.replace("'", "''") + "'";
				}
				builder.append(str);
			}else if(value instanceof Timestamp){
				builder.append("'").append(value.toString()).append("'");
			}else if(value instanceof java.sql.Date){
				builder.append("'").append(value.toString()).append("'");
			}else if(value instanceof LocalDate){
				builder.append("'").append(value.toString()).append("'");
			}else if(value instanceof LocalTime){
				builder.append("'").append(value.toString()).append("'");
			}else if(value instanceof LocalDateTime){
				builder.append("'").append(value.toString()).append("'");
			}else if(value instanceof Date){
				builder.append("'").append(DateUtil.format((Date)value,DateUtil.FORMAT_DATE_TIME)).append("'");
			}else if(value instanceof Number || value instanceof Boolean){
				builder.append(value.toString());
			}else{
				builder.append(value.toString());
			}
			if(j<keySize-1){
				builder.append(",");
			}
		}
		builder.append(")");
	}
	 
	private RunSQL createInsertTxtFromEntity(String dest, AnylineEntity entity, boolean checkParimary, String ... columns){ 
		RunSQL run = new TableRunSQLImpl();
		StringBuilder builder = new StringBuilder();
		List<Object> values = new ArrayList<Object>();
		if(null == dest){ 
			dest = entity.getDataSource(); 
		} 
		if(BasicUtil.isEmpty(dest)){ 
			throw new SQLException("未指定表"); 
		}
		/*确定需要更新的列*/ 
		List<String> keys = confirmInsertColumns(dest, entity, columns);
		if(null == keys || keys.size() == 0){ 
			throw new SQLException("未指定列"); 
		}
		builder.append("INSERT INTO ").append(parseTable(dest));
		builder.append("(");
		int size = keys.size();
		List<String> insertColumns = new ArrayList<>();
		for(int i=0; i<size; i++){
			builder.append(getDelimiterFr()).append(keys.get(i)).append(getDelimiterTo());
			if(i<size-1){
				builder.append(",");
			} 
		}
		builder.append(") VALUES (");
		for(int i=0; i<size; i++){
			builder.append("?");
{'fraction_non_alphanumeric': 0.1578579743888242, 'fraction_numerical': 0.0033926492599368036, 'mean_word_length': 4.059061080262493, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5455371', 'n_tokens_mistral': 11523, 'n_tokens_neox': 10067, 'n_words': 2026}