protected MetaModel(String dbName, Class<? extends Model> modelClass, String dbType) { this.modelClass = modelClass; this.idName = findIdName(modelClass); this.compositeKeys = findCompositeKeys(modelClass); this.tableName = findTableName(modelClass); this.dbType = dbType; this.cached = isCached(modelClass); this.dbName = dbName; this.idGeneratorCode = findIdGeneratorCode(modelClass); this.versionColumn = findVersionColumn(modelClass); this.partitionIDs = findPartitionIDs(); }
if (metaModel.hasAssociation(child.getClass(), OneToManyAssociation.class) || metaModel.hasAssociation(child.getClass(), OneToManyPolymorphicAssociation.class)) { child.delete(); return 1; } else if (metaModel.hasAssociation(child.getClass(), Many2ManyAssociation.class)) { return new DB(metaModel.getDbName()).exec(metaModel.getDialect().deleteManyToManyAssociation( metaModel.getAssociationForTarget(child.getClass(), Many2ManyAssociation.class)), getId(), child.getId()); } else {
/** * Checks if this model has a named attribute that has the same name as argument. * * Throws <code>IllegalArgumentException</code> in case it does not find it. * * @param attribute name of attribute or association target. */ protected void checkAttribute(String attribute) { if (!hasAttribute(attribute)) { String sb = "Attribute: '" + attribute + "' is not defined in model: '" + getModelClass() + ". " + "Available attributes: " +getAttributeNames(); throw new IllegalArgumentException(sb); } }
@Override public String selectExists(MetaModel metaModel) { return "SELECT " + metaModel.getIdName() + " FROM " + metaModel.getTableName() + " WHERE " + metaModel.getIdName() + " = ?"; }
StringBuilder query = new StringBuilder().append("UPDATE ").append(metaModel.getTableName()).append(" SET "); Set<String> attributeNames = metaModel.getAttributeNamesSkipGenerated(manageTime); attributeNames.retainAll(dirtyAttributeNames); if(attributeNames.size() > 0) { if (manageTime && metaModel.hasAttribute("updated_at")) { if(values.size() > 0) query.append(", "); if(metaModel.isVersioned()){ if(values.size() > 0) query.append(", "); query.append(metaModelLocal.getVersionColumn()).append(" = ?"); values.add(getLong(metaModelLocal.getVersionColumn()) + 1); query.append(" WHERE ").append(metaModel.getIdName()).append(" = ?"); values.add(getId()); if(metaModel.hasPartitionIDs()){ for (String partitionId : metaModel.getPartitionIDs()) { query.append(" AND ").append(partitionId).append(" = ?"); values.add(get(partitionId)); if (metaModel.isVersioned()) { query.append(" AND ").append(metaModelLocal.getVersionColumn()).append(" = ?"); values.add(get(metaModelLocal.getVersionColumn())); int updated = new DB(metaModel.getDbName()).exec(query.toString(), values.toArray()); if(metaModel.isVersioned() && updated == 0){ throw new StaleModelException("Failed to update record for model '" + getClass() +
BelongsToAssociation ass = metaModelLocal.getAssociationForTarget(parentClass, BelongsToAssociation.class); BelongsToPolymorphicAssociation assP = metaModelLocal.getAssociationForTarget(parentClass, BelongsToPolymorphicAssociation.class); String parentTable = parentMM.getTableName(); String parentIdName = parentMM.getIdName(); String query = metaModelLocal.getDialect().selectStarParametrized(parentTable, parentIdName); if (parentMM.cached()) { P parent = parentClass.cast(QueryCache.instance().getItem(parentTable, query, new Object[]{fkValue})); if (parent != null) { List<Map> results = new DB(parentMM.getDbName()).findAll(query, fkValue); P parent = parentClass.newInstance(); parent.hydrate(results.get(0), true); if (parentMM.cached()) { QueryCache.instance().addItem(parentTable, query, new Object[]{fkValue}, parent);
OneToManyAssociation oneToManyAssociation = metaModelLocal.getAssociationForTarget(targetModelClass, OneToManyAssociation.class); MetaModel mm = metaModelLocal; Many2ManyAssociation manyToManyAssociation = metaModelLocal.getAssociationForTarget(targetModelClass, Many2ManyAssociation.class); OneToManyPolymorphicAssociation oneToManyPolymorphicAssociation = metaModelLocal.getAssociationForTarget(targetModelClass, OneToManyPolymorphicAssociation.class); String targetId = metaModelOf(targetModelClass).getIdName(); MetaModel targetMM = metaModelOf(targetModelClass); String targetTable = targetMM.getTableName(); subQuery = "parent_id = ? AND " + " parent_type = '" + oneToManyPolymorphicAssociation.getTypeLabel() + "'" + additionalCriteria; } else { throw new NotAssociatedException(metaModelLocal.getModelClass(), targetModelClass);
protected MetaModel(String dbName, Class<? extends Model> modelClass, String dbType) { this.modelClass = modelClass; this.idName = findIdName(modelClass); this.tableName = findTableName(modelClass); this.dbType = dbType; this.cached = isCached(modelClass); this.dbName = dbName; this.idGeneratorCode = findIdGeneratorCode(modelClass); this.versionColumn = findVersionColumn(modelClass); }
List<Object> values = new ArrayList<>(); for (Map.Entry<String, Object> entry : attributes.entrySet()) { if (entry.getValue() != null && !metaModel.getVersionColumn().equals(entry.getKey())) { columns.add(entry.getKey()); values.add(entry.getValue()); if (metaModel.isVersioned()) { columns.add(metaModel.getVersionColumn()); values.add(1); boolean containsId = (attributes.get(metaModel.getIdName()) != null); // do not use containsKey boolean done; String query = metaModel.getDialect().insertParametrized(metaModel, columns, containsId); if (containsId || getCompositeKeys() != null) { compositeKeyPersisted = done = (1 == new DB(metaModel.getDbName()).exec(query, values.toArray())); } else { Object id = new DB(metaModel.getDbName()).execInsert(query, metaModel.getIdName(), values.toArray()); attributes.put(metaModel.getIdName(), id); done = (id != null); if (metaModel.cached()) { Registry.cacheManager().purgeTableCache(metaModel); if (metaModel.isVersioned()) { attributes.put(metaModel.getVersionColumn(), 1);
private Object tryPolymorphicChildren(String childTable){ MetaModel childMM = inferTargetMetaModel(childTable); if(childMM == null){ return null; }else return getMetaModelLocal().hasAssociation(childMM.getTableName(), OneToManyPolymorphicAssociation.class) ? getAll(childMM.getModelClass()): null; }
protected String toJSON() { List models = new ArrayList(); metaModelsByTableName.values().forEach(metaModel -> { List associations = new ArrayList(); metaModel.getAssociations().forEach(association -> associations.add(association.toMap())); models.add(map( MODEL_CLASS, metaModel.getModelClass().getName(), DB_TYPE, metaModel.getDbType(), DB_NAME, metaModel.getDbName(), COLUMN_METADATA, metaModel.getColumnMetadata(), ASSOCIATIONS, associations )); }); return JsonHelper.toJsonString(models,false); }
private Object tryParent(String parentTable){ MetaModel parentMM = inferTargetMetaModel(parentTable); if(parentMM == null){ return null; }else return metaModelLocal.hasAssociation(parentMM.getModelClass(), BelongsToAssociation.class) ? parent(parentMM.getModelClass()): null; }
private void processManyToMany(Many2ManyAssociation association) { if(delegate.isEmpty()){//no need to process other if no models selected. return; } final MetaModel childMetaModel = metaModelOf(association.getTargetClass()); final Map<Object, List<Model>> childrenByParentId = new HashMap<>(); List<Object> ids = collect(metaModel.getIdName()); List<Map> childResults = new DB(childMetaModel.getDbName()).findAll(childMetaModel.getDialect().selectManyToManyAssociation( association, "the_parent_record_id", ids.size()), ids.toArray()); for(Map res: childResults){ Model child = ModelDelegate.instance(res, childMetaModel); Object parentId = res.get("the_parent_record_id"); if(childrenByParentId.get(parentId) == null){ childrenByParentId.put(parentId, new SuperLazyList<>()); } childrenByParentId.get(parentId).add(child); } for(T parent : delegate){ List<Model> children = childrenByParentId.get(parent.getId()); if (children != null) { parent.setChildren(childMetaModel.getModelClass(), children); } else { parent.setChildren(childMetaModel.getModelClass(), new SuperLazyList<>()); } } }
Set<String> attributeNames = metaModelLocal.getAttributeNames(); for (Map.Entry<String, Object> entry : attributesMap.entrySet()) { if (attributeNames.contains(entry.getKey()) ) { if (entry.getValue() instanceof Clob && metaModelLocal.cached()) { String convertedString = Convert.toString(entry.getValue()); if (willAttributeModifyModel(entry.getKey(), convertedString)) { Object convertedObject = metaModelLocal.getDialect().overrideDriverTypeConversion( metaModelLocal, entry.getKey(), entry.getValue()); if (willAttributeModifyModel(entry.getKey(), convertedObject)) {
/** * Finds all attribute names except for id. * * @return all attribute names except for id. */ public Set<String> getAttributeNamesSkipId() { if (attributeNamesNoId == null) {//no one cares about unfortunate multi-threading timing with 2 instances created //if someone does, use DCL with volatile Set<String> attributesNames = new CaseInsensitiveSet(getAttributeNames()); attributesNames.remove(getIdName()); attributeNamesNoId = attributesNames; } return attributeNamesNoId; }
@Override public String insertParametrized(MetaModel metaModel, List<String> columns, boolean containsId) { StringBuilder query = new StringBuilder().append("INSERT INTO ").append(metaModel.getTableName()).append(' '); if (columns.isEmpty()) { appendEmptyRow(metaModel, query); } else { boolean addIdGeneratorCode = (!containsId && metaModel.getIdGeneratorCode() != null); query.append('('); if (addIdGeneratorCode) { query.append(metaModel.getIdName()).append(", "); } join(query, columns, ", "); query.append(") VALUES ("); if (addIdGeneratorCode) { query.append(metaModel.getIdGeneratorCode()).append(", "); } appendQuestions(query, columns.size()); query.append(')'); } return query.toString(); }
Map metaModelMap = (Map) o; MetaModel metaModel = new MetaModel( (String) metaModelMap.get(DB_NAME), (Class<? extends Model>) Class.forName((String) metaModelMap.get(MODEL_CLASS)), metaModel.setColumnMetadata(columnMetadataMap); metaModel.addAssociation( (Association) lookup.findConstructor( Class.forName((String) map.get(Association.CLASS)), addMetaModel(metaModel, metaModel.getModelClass());
/** * Copies all attribute values (except for ID, created_at and updated_at) from other instance to this one. * * @param other source model. */ public void copyFrom(Model other) { if (!metaModelLocal.getTableName().equals(other.metaModelLocal.getTableName())) { throw new IllegalArgumentException("can only copy between the same types"); } Map<String, Object> otherAttributes = other.getAttributes(); for (String name : metaModelLocal.getAttributeNamesSkipId()) { attributes.put(name, otherAttributes.get(name)); dirtyAttributeNames.add(name); // Why not use setRaw() here? Does the same and avoids duplication of code... (Garagoth) // other.setRaw(name, getRaw(name)); } }
if(!metaModel.isAssociatedTo(clazz)) throw new IllegalArgumentException("Model: " + clazz.getName() + " is not associated with: " + metaModel.getModelClass().getName()); includes.addAll(metaModel.getAssociationsForTarget(includeClass));
throw new NoSuchElementException("No attributes set, can't create an update statement."); StringBuilder query = new StringBuilder().append("UPDATE ").append(metaModel.getTableName()).append(" SET "); String idName = metaModel.getIdName(); if (metaModel.getCompositeKeys() == null){ query.append(" WHERE ").append(idName).append(" = ").append(attributes.get(idName)); } else { String[] compositeKeys = metaModel.getCompositeKeys(); for (int i = 0; i < compositeKeys.length; i++) { query.append(i == 0 ? " WHERE " : " AND ").append(compositeKeys[i]).append(" = ");