package foundation.data.object;
|
|
import java.util.Date;
|
import java.util.List;
|
import java.util.Set;
|
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
|
import foundation.dao.Filter;
|
import foundation.dao.ILineLimit;
|
import foundation.dao.LineLimitManager;
|
import foundation.dao.LineLimitType;
|
import foundation.dao.OrderBy;
|
import foundation.dao.Page;
|
import foundation.dao.bizlogic.ICodeProvider;
|
import foundation.data.entity.Entity;
|
import foundation.data.entity.EntitySet;
|
import foundation.data.entity.EntityTree;
|
import foundation.data.entity.LineOperator;
|
import foundation.data.getter.EntityGetter;
|
import foundation.data.getter.EntitySetGetter;
|
import foundation.data.getter.EntityTreeGetter;
|
import foundation.data.loader.DataObjectLoader;
|
import foundation.data.loader.FieldRuleLoader;
|
import foundation.data.meta.MetaMonitor;
|
import foundation.data.meta.ReloadCheckResult;
|
import foundation.data.meta.field.Field;
|
import foundation.data.meta.field.FieldRuntimeCreator;
|
import foundation.data.meta.field.FieldWriter;
|
import foundation.data.meta.field.FieldsRuntime;
|
import foundation.data.meta.field.TableFieldExtensionLoader;
|
import foundation.data.meta.field.TableFieldLoader;
|
import foundation.data.rule.FieldDefaultValueRule;
|
import foundation.data.rule.FieldRules;
|
import foundation.data.rule.FieldValidateRule;
|
import foundation.data.rule.exists.ExistsRule;
|
import foundation.data.rule.exists.ExistsRules;
|
import foundation.data.rule.update.KindredRule;
|
import foundation.data.rule.update.KindredRules;
|
import foundation.handler.IMessageReporter;
|
import foundation.handler.ResultPool;
|
import foundation.persist.NamedSQL;
|
import foundation.persist.SQLRunner;
|
import foundation.persist.source.NamedDataSource;
|
import foundation.server.config.Configer;
|
import foundation.server.config.DBaseType;
|
import foundation.token.IOnlineUser;
|
import foundation.util.ID;
|
import foundation.util.MapList;
|
import foundation.util.Util;
|
import foundation.variant.provider.DataEvent;
|
import foundation.variant.provider.IVariantsProvider;
|
import foundation.variant.provider.VariantProviderType;
|
|
public class DataObject implements IVariantsProvider {
|
|
public static LineLimitType DefaultLineLimitType;
|
|
private static Logger logger;
|
private static DataObjectContainer container;
|
private static boolean IsSequenceActive;
|
|
private NamedDataSource dataSource;
|
private String id;
|
private String dataName;
|
private String title;
|
private String tableName;
|
private String viewName;
|
private DefaultFilter defaultFilter;
|
private DataJoins dataJoins;
|
private OrderBy defaultOrderBy;
|
private String batchSQL;
|
private String oneSQL;
|
private String countSQL;
|
private SQLGuide sqlGuide;
|
|
private FieldsRuntime tableFieldMetas;
|
private FieldsRuntime batchBrowseFieldMetas;
|
private FieldsRuntime oneBrowseFieldMetas;
|
private FieldRules fieldRules;
|
private ExistsRules existsRules;
|
private KindredRules kindredRules;
|
private DataObjectVariantsProvider variantsProvider;
|
private Sequence sequence;
|
private Object tableFieldLocker;
|
private Object browseFieldLocker;
|
private MetaMonitor fieldMonitor;
|
private MetaMonitor propertyMonitor;
|
private Date lastObjectUpdateTime;
|
private Date lastFieldLoadTime;
|
|
static {
|
logger = LogManager.getLogger(DataObject.class);
|
container = DataObjectContainer.getInstance();
|
IsSequenceActive = Configer.getBoolean("isSequenctActive", false);
|
DefaultLineLimitType = Configer.getBoolean("IsStrictLineLimit", true) ? LineLimitType.Deny : LineLimitType.Free;
|
}
|
|
public DataObject() throws Exception {
|
defaultFilter = new DefaultFilter();
|
tableFieldLocker = new Object();
|
browseFieldLocker = new Object();
|
|
variantsProvider = new DataObjectVariantsProvider(this);
|
}
|
|
public static DataObject getInstance(String dataName) {
|
return container.get(dataName);
|
}
|
|
public static DataObject getInstance(String dataName, boolean force) {
|
return container.get(dataName, force);
|
}
|
|
public static DataObject refresh(String dataName) throws Exception {
|
return container.refresh(dataName);
|
}
|
|
public void load(Entity entity) throws Exception {
|
// 1.
|
id = entity.getString("id");
|
dataName = entity.getString("name");
|
tableName = entity.getString("table_name");
|
viewName = entity.getString("view_name");
|
|
defaultFilter.load(entity);
|
|
title = entity.getString("title");
|
if (Util.isEmpty(title)) {
|
title = dataName;
|
}
|
|
// 2.
|
String orderBy = entity.getString("order_by");
|
if (!Util.isEmpty(orderBy)) {
|
defaultOrderBy = new OrderBy(orderBy);
|
}
|
|
// 4.
|
batchSQL = entity.getString("batchSQL_name", null);
|
oneSQL = entity.getString("oneSQL_name", null);
|
countSQL = entity.getString("countSQL_name", null);
|
|
// 5.
|
dataSource = NamedDataSource.getInstance();
|
|
// 6.
|
lastObjectUpdateTime = entity.getDate("last_update_time", null);
|
if (lastObjectUpdateTime == null) {
|
lastObjectUpdateTime = new Date();
|
}
|
}
|
|
public void build() throws Exception {
|
// 1. build Data Joins
|
if (dataJoins != null) {
|
dataJoins.build();
|
}
|
|
// 2. set SQL Guide
|
sqlGuide = new SQLGuide(this);
|
sqlGuide.setBatchSQL(batchSQL);
|
sqlGuide.setOneSQL(oneSQL);
|
sqlGuide.setCountSQL(countSQL);
|
|
sqlGuide.build();
|
|
// 3.
|
if (!Util.isEmpty(tableName)) {
|
sequence = new Sequence(dataSource, tableName);
|
}
|
|
// 4. 初始化字段描述
|
tableFieldMetas = null;
|
batchBrowseFieldMetas = null;
|
oneBrowseFieldMetas = null;
|
|
//5. 加载规则
|
DBaseType dBaseType = dataSource.getDBaseType();
|
fieldRules = new FieldRules(dataName);
|
existsRules = ExistsRules.getInstance(dataName, dBaseType);
|
kindredRules = KindredRules.getInstance(dataName, dBaseType);
|
|
//6. 创建变更检查监听器
|
fieldMonitor = new MetaMonitor(dataSource, dataName, "getFieldLastUpdateTime");
|
propertyMonitor = new MetaMonitor(dataSource, dataName, "getPropertyLastUpdateTime");
|
}
|
|
public void loadOneDataJoin(DataJoin dataJoin) {
|
if (dataJoins == null) {
|
dataJoins = new DataJoins();
|
}
|
|
dataJoins.loadOne(dataJoin);
|
}
|
|
public Entity getTableEntity(String id) throws Exception {
|
this.getTableFieldMetas();
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), NamedSQL.Code_GetEntity);
|
namedSQL.setTableName(this.tableName);
|
|
Filter filter = new Filter();
|
filter = addDefaultFilter(filter.add("id", id));
|
namedSQL.setFilter(filter);
|
|
Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.tableFieldMetas));
|
return result;
|
}
|
|
public Entity getTableEntity(Filter filter) throws Exception {
|
this.getTableFieldMetas();
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getEntity");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFilter(addDefaultFilter(filter));
|
|
Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.tableFieldMetas));
|
return result;
|
}
|
|
public Entity getBrowseEntity(String id) throws Exception {
|
this.getOneBrowseFieldMetas();
|
|
// 1. get SQL
|
NamedSQL namedSQL = sqlGuide.getBrowseOneSQL();
|
|
// 2. get filter
|
Filter filter = new Filter().add(getTableOrViewName() + ".id", id);
|
filter = addDefaultFilter(filter);
|
namedSQL.setFilter(filter);
|
|
// 3. get data result
|
Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.oneBrowseFieldMetas));
|
return result;
|
}
|
|
public Entity getBrowseEntity(Filter filter) throws Exception {
|
this.getOneBrowseFieldMetas();
|
|
// 1. get SQL
|
NamedSQL namedSQL = sqlGuide.getBrowseOneSQL();
|
|
// 2. get filter
|
filter = addDefaultFilter(filter);
|
namedSQL.setFilter(filter);
|
|
// 3. get data result
|
Entity result = SQLRunner.getEntity(dataSource, namedSQL, new EntityGetter(this.oneBrowseFieldMetas));
|
return result;
|
}
|
|
public EntitySet getTableEntitySet(IVariantsProvider... providers) throws Exception {
|
this.getTableFieldMetas();
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getEntity");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.overWriteVariants(addDefaultFilter(providers));
|
|
Page page = null;
|
for (IVariantsProvider provider : providers) {
|
if (provider instanceof Page) {
|
page = (Page) provider;
|
}
|
}
|
|
EntitySet dataSet = SQLRunner.getEntitySet(dataSource, namedSQL, new EntitySetGetter(this.tableFieldMetas));
|
return getDataByPage(dataSet, page);
|
}
|
|
private EntitySet getDataByPage(EntitySet dataSet, Page page) {
|
if ((!dataSource.isOracle()) || page == null) {
|
return dataSet;
|
}
|
|
int pageFrom = page.getBeginRecordNo(), batchStep = page.getPageSize();
|
int count = dataSet.size(), resultCount = 0;
|
|
if (pageFrom >= count) {
|
return dataSet;
|
}
|
|
EntitySet result = new EntitySet(dataSet.getEntityMeta());
|
for (int recordNo = pageFrom-1; recordNo < count && resultCount < batchStep; recordNo++) {
|
resultCount ++;
|
result.append(dataSet.getEntity(recordNo));
|
}
|
|
return result;
|
}
|
|
public EntitySet getBrowseEntitySet(IVariantsProvider... providers) throws Exception {
|
this.getBatchBrowseFieldMetas();
|
|
// 1. get SQL
|
NamedSQL namedSQL = sqlGuide.getBrowseBatchSQL();
|
|
// 2. set variants
|
providers = addDefaultFilter(providers);
|
providers = addDefaultOrderBy(providers);
|
namedSQL.setVariants(providers);
|
|
// 3. try get batch counter
|
BatchCounter counter = null;
|
Page page = null;
|
|
for (IVariantsProvider provider : providers) {
|
if (provider instanceof BatchCounter) {
|
counter = (BatchCounter) provider;
|
break;
|
}else if (provider instanceof Page) {
|
page = (Page) provider;
|
}
|
}
|
|
// 4. get data result
|
EntitySet dataSet = SQLRunner.getEntitySet(dataSource, namedSQL, new EntitySetGetter(this.batchBrowseFieldMetas, counter));
|
return getDataByPage(dataSet, page);
|
}
|
|
public EntityTree getTableEntityTree(IVariantsProvider... providers) throws Exception {
|
this.getTableFieldMetas();
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getEntity");
|
namedSQL.setTableName(getTableOrViewName());
|
namedSQL.setVariants(addDefaultFilter(providers));
|
|
EntityTree entityTree = SQLRunner.getEntityTree(dataSource, namedSQL, new EntityTreeGetter(this.tableFieldMetas));
|
return entityTree;
|
}
|
|
public EntityTree getBrowseEntityTree(IVariantsProvider... providers) throws Exception {
|
this.getBatchBrowseFieldMetas();
|
|
// 1. get SQL
|
NamedSQL namedSQL = sqlGuide.getBrowseBatchSQL();
|
|
// 2. get table name and variants
|
providers = addDefaultFilter(providers);
|
namedSQL.setVariants(providers);
|
|
// 3. get data result
|
EntityTree entityTree = SQLRunner.getEntityTree(dataSource, namedSQL, new EntityTreeGetter(this.batchBrowseFieldMetas));
|
return entityTree;
|
}
|
|
public Entity createTableEntity(boolean createDefaultValues) throws Exception {
|
this.getTableFieldMetas();
|
|
Entity entity = new Entity(this.tableFieldMetas);
|
|
if (!createDefaultValues) {
|
return entity;
|
}
|
|
if (!defaultFilter.isEmpty()) {
|
entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue());
|
}
|
|
setEntityDefaultValues(DataEvent.New, entity);
|
return entity;
|
}
|
|
public Entity cloneEntity(Entity source) throws Exception {
|
if (source == null) {
|
return null;
|
}
|
|
// 1. 也许是 Table Entity,也许是 Browse Entity,因此取源的字段
|
Entity result = new Entity(source.getFieldsMeta());
|
|
// 2. 填写默认值
|
if (!defaultFilter.isEmpty()) {
|
result.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue());
|
}
|
|
setEntityDefaultValues(DataEvent.New, result);
|
|
// 3. 复制值 (只复制没有默认值的字段)
|
Object[] dataArray = result.getDataArray();
|
Object[] sourceArray = source.getDataArray();
|
|
int max = dataArray.length;
|
for (int i = 0; i < max; i++) {
|
if (dataArray[i] != null) {
|
continue;
|
}
|
|
dataArray[i] = sourceArray[i];
|
}
|
|
// 4. 重新设置 ID
|
result.set("id", ID.newValue());
|
return result;
|
}
|
|
public EntitySet cloneEntitySet(EntitySet source) throws Exception {
|
EntitySet result = new EntitySet(source.getEntityMeta());
|
|
for (Entity entity : source) {
|
Entity newOne = cloneEntity(entity);
|
result.append(newOne);
|
}
|
|
return result;
|
}
|
|
public Entity createTableEmptyEntity() throws Exception {
|
this.getTableFieldMetas();
|
Entity entity = new Entity(this.tableFieldMetas);
|
return entity;
|
}
|
|
public EntitySaver createEntitySaver(Entity original) throws Exception {
|
return new EntitySaver(this, original);
|
}
|
|
public EntitySaver createEntitySaver(String id) throws Exception {
|
return new EntitySaver(this, id);
|
}
|
|
public EntitySaver createEntitySaver() throws Exception {
|
return new EntitySaver(this);
|
}
|
|
public Entity createBrowseEntity(boolean createDefaultValues) throws Exception {
|
this.getOneBrowseFieldMetas();
|
|
Entity entity = new Entity(this.oneBrowseFieldMetas);
|
|
if (!createDefaultValues) {
|
return entity;
|
}
|
|
if (!defaultFilter.isEmpty()) {
|
entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue());
|
}
|
|
setEntityDefaultValues(DataEvent.New, entity);
|
return entity;
|
}
|
|
public Entity createEmptyBrowseEntity() throws Exception {
|
this.getOneBrowseFieldMetas();
|
Entity result = new Entity(this.oneBrowseFieldMetas);
|
return result;
|
}
|
|
public EntitySet createTableEntitySet(int size) throws Exception {
|
this.getTableFieldMetas();
|
EntitySet result = new EntitySet(this.tableFieldMetas, size);
|
return result;
|
}
|
|
public EntitySet createTableEntitySet() throws Exception {
|
this.getTableFieldMetas();
|
EntitySet result = new EntitySet(this.tableFieldMetas);
|
return result;
|
}
|
|
public EntitySet createBrowseEntitySet() throws Exception {
|
this.getBatchBrowseFieldMetas();
|
EntitySet result = new EntitySet(this.batchBrowseFieldMetas);
|
return result;
|
}
|
|
public boolean validateEntity(Entity entity) {
|
return validateEntity(entity, null);
|
}
|
|
public boolean validateEntity(Entity entity, IMessageReporter reporter) {
|
List<FieldValidateRule> validateRules = fieldRules.getValudateRules();
|
|
boolean success = true;
|
|
if (validateRules == null || validateRules.isEmpty()) {
|
return success;
|
}
|
|
for (FieldValidateRule validateRule : validateRules) {
|
success = success && validateRule.exec(entity, reporter);
|
}
|
|
return success;
|
}
|
|
public void setEntityDefaultValues(DataEvent dataEvent, Entity entity) {
|
setEntityDefaultValues(dataEvent, entity, null, null);
|
}
|
|
public void setEntityDefaultValues(DataEvent dataEvent, Entity entity, IParamProvider paramProvider, IMessageReporter reporter) {
|
List<FieldDefaultValueRule> defaultValueRules = fieldRules.getDefaultValueRules();
|
|
for (FieldDefaultValueRule valueRule : defaultValueRules) {
|
valueRule.exec(dataEvent, entity, paramProvider, reporter);
|
}
|
}
|
|
public boolean existsValidate(EntitySet documentSet) throws Exception {
|
boolean detailCheck = false;
|
|
if (existsRules == null) {
|
return detailCheck;
|
}
|
|
for (ExistsRule existsRule: existsRules) {
|
EntitySet errorSet = null;
|
if (documentSet == null || !tableName.equalsIgnoreCase(existsRule.getTargetTableName())) {
|
continue;
|
}
|
|
for (Entity detailEntity : documentSet) {
|
errorSet = existsRule.exec(detailEntity, errorSet);
|
if (errorSet != null && errorSet.size() > 0) {
|
detailCheck = true;
|
}
|
}
|
|
if (detailCheck) {
|
ResultPool existsCheckResult = ResultPool.getInstance();
|
existsCheckResult.reportExistsError("existsCheck", existsRule.getName(), errorSet);
|
}
|
}
|
|
return detailCheck;
|
}
|
|
public boolean existsValidate(Entity documentEntity) throws Exception {
|
boolean entityCheck = false;
|
|
existsRules = ExistsRules.getInstance(dataName, dataSource.getDBaseType());
|
|
if (existsRules == null) {
|
return entityCheck;
|
}
|
|
for (ExistsRule existsRule: existsRules) {
|
if (documentEntity == null || !tableName.equalsIgnoreCase(existsRule.getTargetTableName())) {
|
continue;
|
}
|
|
EntitySet errorSet = null;
|
errorSet = existsRule.exec(documentEntity, errorSet);
|
|
if (errorSet!= null && errorSet.size() > 0) {
|
entityCheck = true;
|
}
|
|
if (entityCheck) {
|
ResultPool existsCheckResult = ResultPool.getInstance();
|
existsCheckResult.reportExistsError("existsCheck", existsRule.getName(), errorSet);
|
}
|
}
|
|
return entityCheck;
|
}
|
|
public void updateKindred(Entity entity, IVariantsProvider... providers) throws Exception {
|
kindredRules = KindredRules.getInstance(dataName, DBaseType.MySQL);
|
|
if (kindredRules == null ){
|
return;
|
}
|
|
//1. 获取原始数据
|
for (KindredRule rule : kindredRules) {
|
if (!rule.isActive()) {
|
logger.info("KindredRule :{}, is not active. Skip", rule.getId());
|
continue;
|
}
|
|
int excuteCount = rule.exec(entity, providers);
|
logger.info("dataName:{}, kindredTable: {},kindredTargetField:{} 更新 {} 条.",
|
dataName, rule.getKindredTableName(), rule.getKindredTargetField(), excuteCount);
|
}
|
}
|
|
public boolean existsEntity(Entity entity) throws Exception {
|
String id = entity.getId();
|
if (Util.isEmpty(id)) {
|
return false;
|
}
|
|
Filter filter = new Filter("id", id);
|
filter = addDefaultFilter(filter);
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getCount");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFilter(filter);
|
|
int cnt = SQLRunner.getInteger(dataSource, namedSQL);
|
return cnt > 0;
|
}
|
|
public boolean existsEntity(String id) throws Exception {
|
if (Util.isEmpty(id)) {
|
return false;
|
}
|
Filter filter = new Filter("id", id);
|
filter = addDefaultFilter(filter);
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getCount");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFilter(filter);
|
|
int cnt = SQLRunner.getInteger(dataSource, namedSQL);
|
return cnt > 0;
|
}
|
|
public boolean existsEntity(Filter filter) throws Exception {
|
if (filter == null) {
|
return false;
|
}
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "getCount");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFilter(addDefaultFilter(filter));
|
|
int cnt = SQLRunner.getInteger(dataSource, namedSQL);
|
return cnt > 0;
|
}
|
|
public int insertEntity(Entity entity) throws Exception {
|
return insertEntity(entity, null, null);
|
}
|
|
public int insertEntity(Entity entity, IParamProvider paramProvider, IMessageReporter reporter) throws Exception {
|
getTableFieldMetas();
|
|
// 1. set id if empty
|
if (entity.isEmptyValue("id")) {
|
String id = ID.newValue();
|
entity.set("id", id);
|
}
|
|
// 2. set sequence
|
if (IsSequenceActive && entity.contains("idx")) {
|
long next = sequence.next();
|
entity.set("idx", next);
|
}
|
|
// 3. default value
|
setEntityDefaultValues(DataEvent.Insert, entity, paramProvider, reporter);
|
|
if (!defaultFilter.isEmpty()) {
|
entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue());
|
}
|
|
// 4. insert
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), NamedSQL.Code_InsertEntity);
|
namedSQL.setTableName(tableName);
|
namedSQL.setFieldNames(DataEvent.Insert, tableFieldMetas, entity);
|
namedSQL.setFieldValues(DataEvent.Insert, tableFieldMetas, entity);
|
|
return SQLRunner.execSQL(dataSource, namedSQL);
|
}
|
|
public int insertEntity(Entity entity, boolean isSimple) throws Exception {
|
if(!isSimple) {
|
return insertEntity(entity);
|
}
|
|
getTableFieldMetas();
|
|
// 1. set id if empty
|
if (entity.isEmptyValue("id")) {
|
String id = ID.newValue();
|
entity.set("id", id);
|
}
|
|
// 2. set sequence
|
if (IsSequenceActive && entity.contains("idx")) {
|
long next = sequence.next();
|
entity.set("idx", next);
|
}
|
|
if (!defaultFilter.isEmpty()) {
|
entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue());
|
}
|
|
// 4. insert
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), NamedSQL.Code_InsertEntity);
|
namedSQL.setTableName(tableName);
|
namedSQL.setFieldNames(DataEvent.Insert, tableFieldMetas, entity);
|
namedSQL.setFieldValues(DataEvent.Insert, tableFieldMetas, entity);
|
|
return SQLRunner.execSQL(dataSource, namedSQL);
|
}
|
|
public int insertEntitySet(EntitySet entitySet) throws Exception {
|
if (entitySet == null || entitySet.isEmpty()) {
|
return 0;
|
}
|
|
// 1. 检查ID是否为空
|
for (Entity entity : entitySet) {
|
if (entity.isEmptyValue("id")) {
|
entity.set("id", ID.newValue());
|
}
|
|
if (!defaultFilter.isEmpty()) {
|
entity.set(defaultFilter.getFieldName(), defaultFilter.getFieldValue());
|
}
|
}
|
|
// 2. 批量插入数据库
|
FieldsRuntime meta = entitySet.getEntityMeta();
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "insertEntity");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFieldNames(DataEvent.Insert, meta);
|
namedSQL.setPlaceHolders(meta.size());
|
|
SQLRunner.saveData(dataSource, namedSQL, entitySet);
|
|
return entitySet.size();
|
}
|
|
public int batchInsertEntitySet(EntitySet entitySet) throws Exception {
|
int result = 0;
|
|
BatchEntitySaver batchSaver = new BatchEntitySaver(dataSource);
|
result = batchSaver.save(entitySet, this);
|
|
return result;
|
}
|
|
public int updateEntity(Entity entity) throws Exception {
|
return updateEntity(entity, DataEvent.Update, null, null);
|
}
|
|
public int updateEntity(Entity entity, DataEvent event, IParamProvider paramProvider, IMessageReporter reporter) throws Exception {
|
getTableFieldMetas();
|
|
// 1. default value
|
if (event == null) {
|
event = DataEvent.Update;
|
}
|
|
// 2. 填写默认值
|
setEntityDefaultValues(event, entity, paramProvider, reporter);
|
|
// 3. 更新数据库
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "updateById");
|
namedSQL.setParam("fieldNameId", "id").setParam("id", entity.getId());
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFieldNameValues(DataEvent.Update, this.tableFieldMetas, entity);
|
|
int execCount = SQLRunner.execSQL(namedSQL);
|
|
// 4. 更新血缘关系表
|
updateKindred(entity, new Filter("id", entity.getId()));
|
return execCount;
|
}
|
|
public int updateEntity(Entity entity, Filter filter) throws Exception {
|
//1.
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "updateByCriteria");
|
namedSQL.setFilter(filter);
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFieldNameValues(DataEvent.Update, this.tableFieldMetas, entity);
|
|
int execCount = SQLRunner.execSQL(namedSQL);
|
|
//2.
|
updateKindred(entity, filter);
|
return execCount;
|
}
|
|
public void updateByEntity(Entity entity, Filter filter) throws Exception {
|
EntitySaver saver = createEntitySaver();
|
Object[] dataArray = entity.getDataArray();
|
FieldsRuntime fieldsMeta = entity.getFieldsMeta();
|
String[] fieldNames = fieldsMeta.getFieldNames();
|
|
for (int i = 0; i < dataArray.length; i++) {
|
saver.set(fieldNames[i], dataArray[i]);
|
}
|
|
saver.update(filter);
|
}
|
|
public int saveEntity(Entity entity) throws Exception {
|
return saveEntity(entity, null, null);
|
}
|
|
public int saveEntity(Entity entity, boolean checkExists) throws Exception {
|
LineOperator operator = entity.getOperator();
|
|
if (LineOperator.Delete != operator) {
|
if(existsValidate(entity)) {
|
return 0;
|
}
|
}
|
|
return saveEntity(entity, null, null);
|
}
|
|
public int saveEntity(Entity entity, IParamProvider paramProvider, IMessageReporter reporter) throws Exception {
|
if (entity == null) {
|
return 0;
|
}
|
|
// 1. delete
|
LineOperator operator = entity.getOperator();
|
if (LineOperator.Delete == operator) {
|
String id = entity.getId();
|
return this.deleteEntity(id);
|
}
|
|
// 2. update
|
if (LineOperator.Update == operator) {
|
return this.updateEntity(entity, DataEvent.Update, paramProvider, reporter);
|
}
|
|
// 3. insert
|
if (LineOperator.Insert == operator) {
|
return this.insertEntity(entity, paramProvider, reporter);
|
}
|
|
// 4. save
|
boolean exists = this.existsEntity(entity);
|
if (exists) {
|
return this.updateEntity(entity, DataEvent.Update, paramProvider, reporter);
|
}
|
else {
|
return this.insertEntity(entity, paramProvider, reporter);
|
}
|
}
|
|
public int deleteEntity(String id) throws Exception {
|
if (Util.isEmpty(id)) {
|
return 0;
|
}
|
else {
|
Filter filter = new Filter("id", id);
|
filter = addDefaultFilter(filter);
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "deleteByID");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setParam("id", id);
|
namedSQL.setFilter(filter);
|
return SQLRunner.execSQL(dataSource, namedSQL);
|
}
|
}
|
|
public int deleteEntity(Filter filter) throws Exception {
|
filter = addDefaultFilter(filter);
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "deleteByCriteria");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFilter(filter);
|
|
int cnt = SQLRunner.execSQL(dataSource, namedSQL);
|
|
if (cnt > 1) {
|
logger.error("delete entity {} error: {} deleted", this.tableName, cnt);
|
}
|
|
return cnt;
|
}
|
|
public int deleteEntitySet(Filter filter) throws Exception {
|
filter = addDefaultFilter(filter);
|
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "deleteByCriteria");
|
namedSQL.setTableName(this.tableName);
|
namedSQL.setFilter(filter);
|
return SQLRunner.execSQL(dataSource, namedSQL);
|
}
|
|
public int emptyTable() throws Exception {
|
NamedSQL namedSQL = NamedSQL.getInstance(dataSource.getDBaseType(), "emptyTable");
|
namedSQL.setTableName(tableName);
|
|
return SQLRunner.execSQL(dataSource, namedSQL);
|
}
|
|
public int getCount(IVariantsProvider... providers) throws Exception {
|
getTableFieldMetas();
|
|
// 1. get SQL
|
NamedSQL namedSQL = sqlGuide.getCountSQL(providers);
|
|
// 2. set variants
|
namedSQL.setTableName(getTableOrViewName());
|
|
providers = addDefaultFilter(providers);
|
namedSQL.setVariants(null, providers);
|
|
// 3. get result
|
return SQLRunner.getInteger(dataSource, namedSQL);
|
}
|
|
public Entity getSummary(String sum, IVariantsProvider... providers) throws Exception {
|
getTableFieldMetas();
|
NamedDataSource source = dataSource;
|
|
// 1. get SQL
|
NamedSQL namedSQL = NamedSQL.getInstance(source.getDBaseType(), "getSummary");
|
|
// 2. set variants
|
namedSQL.setTableName(getTableOrViewName());
|
|
providers = addDefaultFilter(providers);
|
namedSQL.setVariants(null, providers);
|
namedSQL.setParam("sum", sum);
|
|
// 3. get result
|
Entity entity = SQLRunner.getEntity(source, namedSQL);
|
return entity;
|
}
|
|
public FieldsRuntime getTableFieldMetas() throws Exception {
|
if (tableFieldMetas == null) {
|
synchronized (tableFieldLocker) {
|
if (tableFieldMetas == null) {
|
loadTableFieldMetas();
|
}
|
}
|
}
|
|
return tableFieldMetas;
|
}
|
|
public FieldsRuntime getBatchBrowseFieldMetas() throws Exception {
|
if (batchBrowseFieldMetas == null) {
|
synchronized (browseFieldLocker) {
|
if (batchBrowseFieldMetas == null) {
|
loadBatchBrowseFieldMetas();
|
}
|
}
|
}
|
|
return batchBrowseFieldMetas;
|
}
|
|
public FieldsRuntime getOneBrowseFieldMetas() throws Exception {
|
if (oneBrowseFieldMetas == null) {
|
synchronized (browseFieldLocker) {
|
if (oneBrowseFieldMetas == null) {
|
loadOneBrowseFieldMetas();
|
}
|
}
|
}
|
|
return oneBrowseFieldMetas;
|
}
|
|
public MapList<String, Field> getBrowseFieldMetas() throws Exception {
|
MapList<String, Field> result = new MapList<String, Field>();
|
|
// 1. 先获取 Batch Property
|
FieldsRuntime batchBrowseFieldMetas = getBatchBrowseFieldMetas();
|
|
FieldWriter writer;
|
|
for (Field field : batchBrowseFieldMetas) {
|
writer = field.getWriter();
|
|
// 1.1 字段不需要翻译,直接使用
|
if (!writer.hasDictionaryTranslator()) {
|
result.add(field.getName(), field);
|
continue;
|
}
|
|
// 1.2 需要翻译的字段, 不包括原始字段
|
if (!writer.includeOrighinal()) {
|
result.add(field.getName(), field);
|
continue;
|
}
|
|
// 1.3 需要翻译的字段, 包括原始字段
|
result.add(field.getName(), field);
|
|
Field targetField = writer.getTargetField();
|
if (!batchBrowseFieldMetas.contains(targetField.getName())) {
|
//1.3.1 翻译
|
result.add(targetField.getName(), targetField);
|
}
|
else {
|
//1.3.2 原有表里面已经有了翻译结果字段,不需要翻译
|
writer.setActive(false);
|
}
|
}
|
|
// 2. 如果 One Property 与 Batch Property 不一样,再继续获取
|
if (!sqlGuide.isBatchAndOneSame()) {
|
FieldsRuntime oneBrowseFieldMetas = getOneBrowseFieldMetas();
|
|
for (Field field : oneBrowseFieldMetas) {
|
String fieldName = field.getName();
|
|
if (result.contains(fieldName)) {
|
continue;
|
}
|
|
result.add(fieldName, field);
|
}
|
}
|
|
return result;
|
}
|
|
public synchronized void checkObjectMetasReload() throws Exception {
|
boolean changed = false;
|
|
// 1. 检查Join
|
DataJoins dataJoins = DataObjectLoader.loadOneDataObjectDataJoins(this.dataName);
|
|
if (dataJoinsChanged(this.dataJoins, dataJoins)) {
|
this.dataJoins = dataJoins;
|
changed = true;
|
}
|
|
// 2. 检查本身
|
DataObject objectCreator = DataObjectCreator.ObjectCreator;
|
Entity entity = objectCreator.getTableEntity(id);
|
|
if (entity != null) {
|
Date lastUpdateTime = entity.getDate("last_update_time", this.lastObjectUpdateTime);
|
|
if (this.lastObjectUpdateTime.before(lastUpdateTime)) {
|
load(entity);
|
changed = true;
|
}
|
}
|
|
// 3. 如果需要更新,开始更新
|
if (changed) {
|
build();
|
}
|
}
|
|
private boolean dataJoinsChanged(DataJoins one, DataJoins another) {
|
if (one != null && another != null) {
|
if (one.size() != another.size()) {
|
return true;
|
}
|
|
Date ontUpdateTime = one.getLastUpdateTime();
|
Date anotherUpdateTime = another.getLastUpdateTime();
|
|
if (ontUpdateTime != null && anotherUpdateTime != null) {
|
return one.equals(another);
|
}
|
|
return false;
|
}
|
|
return true;
|
}
|
|
public void checkFieldMetasReload() throws Exception {
|
ReloadCheckResult checkResult = null;
|
|
synchronized (tableFieldLocker) {
|
// 1. 更新当前 DataObject
|
checkResult = fieldMonitor.getReloadCheckResult();
|
|
if (tableFieldMetas == null || checkResult.isNeedReload()) {
|
loadTableFieldMetas();
|
fieldMonitor.setLastUpdateTime(checkResult.getLastUpdateTime());
|
}
|
}
|
|
// 2. Join DataObject
|
if (dataJoins != null) {
|
for (DataJoin dataJoin : dataJoins) {
|
DataObject joinObject = DataObject.getInstance(dataJoin.getJoinDataName());
|
|
synchronized (joinObject.tableFieldLocker) {
|
ReloadCheckResult joinCheckResult = joinObject.fieldMonitor.getReloadCheckResult();
|
|
if (joinObject.tableFieldMetas == null || joinCheckResult.isNeedReload()) {
|
joinObject.loadTableFieldMetas();
|
}
|
}
|
|
}
|
}
|
|
// 3. BatchBrowse Field
|
synchronized (browseFieldLocker) {
|
if (batchBrowseFieldMetas == null || checkResult.isNeedReload()) {
|
loadBatchBrowseFieldMetas();
|
}
|
|
// 4. OneBrowse Field
|
if (oneBrowseFieldMetas == null || checkResult.isNeedReload()) {
|
loadOneBrowseFieldMetas();
|
}
|
}
|
}
|
|
public FieldsRuntime loadTablePhysicsFields() throws Exception {
|
TableFieldLoader fieldLoader = new TableFieldLoader(dataSource, tableName);
|
FieldsRuntime fields = fieldLoader.getFieldsByTableMeta();
|
return fields;
|
}
|
|
public void loadTableFieldMetas() throws Exception {
|
// 1. 加载表结构
|
TableFieldLoader fieldLoader = new TableFieldLoader(dataSource, tableName);
|
tableFieldMetas = fieldLoader.getFieldsByTableResult();
|
|
// 2. 加载字段扩展
|
|
TableFieldExtensionLoader fieldExtensionLoader = new TableFieldExtensionLoader(dataSource, tableName);
|
EntitySet entitySet = fieldExtensionLoader.load();
|
|
// 3. 编译TableFieldMetas
|
FieldRuntimeCreator.buildExtension(tableFieldMetas, entitySet);
|
|
// 4. rules
|
fieldRules.clear();
|
FieldRuleLoader.load(tableFieldMetas, fieldRules);
|
|
// 5. 最后更新时间
|
lastFieldLoadTime = new Date();
|
}
|
|
public void loadBatchBrowseFieldMetas() throws Exception {
|
// 1. 如果 BatchBrowseMeta 与 TableMeta 一样,就取TableMeta
|
if (sqlGuide.isStandard_batch()) {
|
batchBrowseFieldMetas = getTableFieldMetas();
|
return;
|
}
|
|
// 2. 加载 loadBrowseBatchMeta表结构
|
NamedSQL namedSQL = sqlGuide.getBrowseBatchSQL();
|
|
Filter filter = new Filter("1", "<>", "1");
|
namedSQL.setTableName(getTableOrViewName()).setFilter(filter);
|
|
|
TableFieldLoader fieldsMetaLoader = new TableFieldLoader(dataSource, tableName);
|
batchBrowseFieldMetas = fieldsMetaLoader.getMetaByNamedSQL(namedSQL);
|
|
// 3. 加载当前表字段定义
|
FieldRuntimeCreator.buildExtension(batchBrowseFieldMetas, tableFieldMetas);
|
|
// 4. 加载关联表字段定义
|
FieldRuntimeCreator.buildJoinedExtension(batchBrowseFieldMetas);
|
|
// 5. 最后更新时间
|
lastFieldLoadTime = new Date();
|
}
|
|
public void loadOneBrowseFieldMetas() throws Exception {
|
// 1. 如果 BrowseOneMeta 与 TableMeta 一样,就取TableMeta
|
if (sqlGuide.isStandard_one()) {
|
oneBrowseFieldMetas = getTableFieldMetas();
|
return;
|
}
|
|
// 1. 如果 BrowseOneMeta 与 BrowseBatchMeta 一样,就取BrowseBatchMeta
|
if (sqlGuide.isBatchAndOneSame()) {
|
oneBrowseFieldMetas = getBatchBrowseFieldMetas();
|
return;
|
}
|
|
// 3. 加载 BrowseOneMeta
|
NamedSQL namedSQL = sqlGuide.getBrowseOneSQL();
|
|
Filter filter = new Filter("1", "<>", "1");
|
namedSQL.setTableName(getTableOrViewName()).setFilter(filter);
|
|
TableFieldLoader fieldsMetaLoader = new TableFieldLoader(dataSource, tableName);
|
oneBrowseFieldMetas = fieldsMetaLoader.getMetaByNamedSQL(namedSQL);
|
|
// 4. 加载字段定义
|
FieldRuntimeCreator.buildExtension(oneBrowseFieldMetas, tableFieldMetas);
|
|
// 5. 加载关联表字段定义
|
FieldRuntimeCreator.buildJoinedExtension(oneBrowseFieldMetas);
|
|
// 5. 最后更新时间
|
lastFieldLoadTime = new Date();
|
}
|
|
public void loadUserLineFilter(IOnlineUser user, Filter filter) throws Exception {
|
String userId = user.getId();
|
String userCode = user.getCode();
|
|
ILineLimit limit = LineLimitManager.getLimit(user, dataName);
|
LineLimitType type = limit != null ? limit.getType() : DefaultLineLimitType;
|
|
// 1. 如果没有限制
|
if (LineLimitType.Free == type) {
|
logger.trace("【{}】 line no limit", userCode);
|
return;
|
}
|
// 2. 如果没有任何权限
|
else if (LineLimitType.Deny == type) {
|
logger.trace("【{}】 line limit deny", userCode);
|
filter.add("1<>1");
|
return;
|
}
|
// 3. 如果有权限
|
else if (LineLimitType.Limit == type) {
|
logger.trace("【{}】 line limit active", userCode);
|
|
String positionField = user.getPositionField();
|
String positionId = user.getPositionId();
|
String orgId = user.getOrgId();
|
String accountId = user.getAccountId();
|
String companyId = user.getCompanyId();
|
String buId = user.getBUId();
|
String actorId = user.getActorId();
|
|
NamedSQL limitSQL = limit.getLimitSQL();
|
limitSQL.setTableName(getTableOrViewName());
|
limitSQL.setParam("user.id", userId);
|
limitSQL.setParam("user.position_level_field", positionField);
|
limitSQL.setParam("user.position_id", positionId);
|
limitSQL.setParam("user.actor_id", actorId);
|
limitSQL.setParam("user.org_id", orgId);
|
limitSQL.setParam("user.account_id", accountId);
|
limitSQL.setParam("user.company_id", companyId);
|
limitSQL.setParam("user.bu_id", buId);
|
|
String segment = limitSQL.toString();
|
filter.add(segment);
|
}
|
}
|
|
public Filter loadUserLineFilter(IOnlineUser user) throws Exception {
|
Filter filter = new Filter();
|
loadUserLineFilter(user, filter);
|
return filter;
|
}
|
|
public NamedDataSource getDataSource() {
|
return dataSource;
|
}
|
|
public DBaseType getDbaseType() {
|
return dataSource.getDBaseType();
|
}
|
|
public String getDataId() {
|
return this.id;
|
}
|
|
public String getDataName() {
|
return this.dataName;
|
}
|
|
public String getTitle() {
|
return title;
|
}
|
|
public String getTableName() {
|
return this.tableName;
|
}
|
|
public String getViewName() {
|
return this.viewName;
|
}
|
|
public String getTableOrViewName() {
|
return !Util.isEmpty(this.viewName) ? this.viewName : this.tableName;
|
}
|
|
public void clearEntityMeta() {
|
this.batchBrowseFieldMetas = null;
|
this.oneBrowseFieldMetas = null;
|
this.tableFieldMetas = null;
|
}
|
|
public OrderBy getDefaultOrderBy() {
|
return this.defaultOrderBy;
|
}
|
|
public FieldRules getFieldRules() {
|
return fieldRules;
|
}
|
|
public List<FieldValidateRule> getValidateRules() {
|
return fieldRules.getValudateRules();
|
}
|
|
public List<FieldDefaultValueRule> getDefaultValueRules() {
|
return fieldRules.getDefaultValueRules();
|
}
|
|
public ICodeProvider getCodeProvider() throws Exception {
|
getTableFieldMetas();
|
return fieldRules.getCodeProvider();
|
}
|
|
public void setDataJoins(DataJoins dataJoins) {
|
this.dataJoins = dataJoins;
|
}
|
|
public boolean hasDataJoins() {
|
if ((dataJoins == null) || dataJoins.isEmpty()) {
|
return false;
|
}
|
|
return true;
|
}
|
|
public DataJoins getDataJoins() {
|
return dataJoins;
|
}
|
|
public int hashCode() {
|
return this.id.hashCode();
|
}
|
|
public MetaMonitor getFieldMonitor() {
|
return fieldMonitor;
|
}
|
|
public MetaMonitor getPropertyMonitor() {
|
return propertyMonitor;
|
}
|
|
public Date getLastFieldLoadTime() {
|
return lastFieldLoadTime;
|
}
|
|
public String[] getJoinTables() {
|
if (dataJoins == null || dataJoins.isEmpty()) {
|
return null;
|
}
|
|
return dataJoins.getJoinTables();
|
}
|
|
@Override
|
public String getProviderName() {
|
return variantsProvider.getProviderName();
|
}
|
|
@Override
|
public VariantProviderType getProviderType() {
|
return variantsProvider.getProviderType();
|
}
|
|
@Override
|
public boolean containsVariant(String name) {
|
return variantsProvider.containsVariant(name);
|
}
|
|
@Override
|
public Object getVariantValue(DataEvent dataEvent, String name) {
|
return variantsProvider.getVariantValue(dataEvent, name);
|
}
|
|
@Override
|
public Set<String> getVariantNames() {
|
return variantsProvider.getVariantNames();
|
}
|
|
public Filter addDefaultFilter(Filter filter) throws Exception {
|
if (defaultFilter.isEmpty()) {
|
return filter;
|
}
|
|
if (filter == null) {
|
filter = new Filter();
|
}
|
|
filter.add(defaultFilter.getValue(this));
|
return filter;
|
}
|
|
private IVariantsProvider[] addDefaultFilter(IVariantsProvider[] providers) throws Exception {
|
if (defaultFilter.isEmpty()) {
|
return providers;
|
}
|
|
IVariantsProvider[] result = providers;
|
|
// 1. get filter
|
Filter filter = null;
|
int max = providers.length;
|
|
for (int i = 0; i < max; i++) {
|
if (providers[i] instanceof Filter) {
|
filter = (Filter) providers[i];
|
break;
|
}
|
|
}
|
|
if (filter != null && filter.containsMark(this)) {
|
return result;
|
}
|
|
// 2. 如果Provider中没有Filter,需要将Filter加入
|
if (filter == null) {
|
result = new IVariantsProvider[max + 1];
|
|
for (int i = 0; i < max; i++) {
|
result[i] = providers[i];
|
}
|
|
result[max] = filter = new Filter();
|
}
|
|
// 3. 将默认过滤条件加入Filter
|
filter.add(defaultFilter.getValue(this));
|
filter.addMark(this);
|
|
return result;
|
}
|
|
private IVariantsProvider[] addDefaultOrderBy(IVariantsProvider[] providers) throws Exception {
|
if (defaultOrderBy == null ||defaultOrderBy.isEmpty()) {
|
return providers;
|
}
|
|
IVariantsProvider[] result = providers;
|
|
// 1. get filter
|
OrderBy orderBy = defaultOrderBy;
|
int max = providers.length;
|
|
for (int i = 0; i < max; i++) {
|
if(providers[i] instanceof OrderBy) {
|
orderBy = (OrderBy) providers[i];
|
break;
|
}
|
}
|
|
if (orderBy == null) {
|
return result;
|
}
|
|
// 2. 如果Provider中没有OrderBy,需要将OrderBy加入
|
if (orderBy != null) {
|
result = new IVariantsProvider[max + 1];
|
|
for (int i = 0; i < max; i++) {
|
result[i] = providers[i];
|
}
|
|
result[max] = orderBy;
|
}
|
|
// 3. 将默认过滤条件加入Filter
|
|
return result;
|
}
|
|
}
|