1 3 package jodd.db.orm.sqlgen; 4 5 import jodd.bean.BeanUtil; 6 import jodd.db.orm.DbEntityDescriptor; 7 import jodd.db.orm.DbOrm; 8 import jodd.db.orm.DbOrmException; 9 import jodd.introspector.DefaultIntrospector; 10 import jodd.util.StringUtil; 11 12 import java.lang.reflect.Field ; 13 14 26 public class DbDynamicSqlTemplate extends DbSqlTemplate { 27 28 public DbDynamicSqlTemplate(String template) { 29 this(template, DbOrm.getInstance()); 30 } 31 32 public DbDynamicSqlTemplate(String template, DbOrm dbOrm) { 33 super(template, dbOrm); 34 } 35 36 38 41 public DbDynamicSqlTemplate use(String name, Object value) { 42 super.use(name, value); 43 return this; 44 } 45 46 49 public DbDynamicSqlTemplate columnAliases(boolean aliases) { 50 super.columnAliases(aliases); 51 return this; 52 } 53 54 57 public DbDynamicSqlTemplate setColumnAliasesType(ColumnAliasType aliasesType) { 58 super.setColumnAliasesType(aliasesType); 59 return this; 60 } 61 62 65 public DbDynamicSqlTemplate escape(boolean escape) { 66 super.escape(escape); 67 return this; 68 } 69 70 72 73 97 public String parseWhere(String template) { 98 StringBuilder result = new StringBuilder (template.length()); 99 while (true) { 100 String allConditions = nextRegion(result, template, "$W{", "}"); 101 if (allConditions == null) { 102 break; 103 } 104 String prefix = null; int spaceNdx = allConditions.indexOf(' '); 106 if (spaceNdx != -1) { 107 prefix = allConditions.substring(0, spaceNdx); 108 allConditions = allConditions.substring(spaceNdx + 1).trim(); 109 } 110 111 String [] conds = StringUtil.split(allConditions, ","); 112 int count = 0; 113 for (String condition: conds) { 114 condition = condition.trim(); 115 116 boolean useFinders = false; 117 if (condition.startsWith("!") == true) { 118 condition = condition.substring(1); 119 useFinders = true; 120 } 121 122 String tableAlias; int dotNdx = condition.indexOf('.'); 124 if (dotNdx != -1) { 125 tableAlias = condition.substring(0, dotNdx); 126 condition = condition.substring(dotNdx + 1); 127 } else { 128 tableAlias = condition; 132 } 133 134 Object data = null; 135 if (references != null) { 136 data = references.get(condition); 137 } 138 if (data == null) { 139 throw new DbOrmException("Unable to find object reference '" + condition + "'."); 140 } 141 if (useFinders == false) { 142 count = where(result, prefix, data, tableAlias, count); 143 } else { 144 count = whereWithFinders(result, prefix, data, tableAlias, count); 145 } 146 } 147 } 148 return result.toString(); 149 } 150 151 public static String [][] operators = new String [][] { 152 new String [] {"Like", " like "}, 153 new String [] {"Greater", ">"}, 154 new String [] {"Less", "<"}, 155 new String [] {"GreaterEqual", ">="}, 156 new String [] {"LessEqual", "<="}, 157 new String [] {"Not", "<>"}, 158 }; 159 160 protected int where(StringBuilder result, String prefix, Object object, String tableAlias, int count) { 161 Class type = object.getClass(); 162 DbEntityDescriptor ded = dbOrm.lookup(type); 163 164 String className = StringUtil.uncapitalize(type.getSimpleName()); 165 String [] allProperties = ded.getProperties(); 166 String [] allColumns = ded.getColumns(); 167 168 for (int i = 0; i < allProperties.length; i++) { 169 String property = allProperties[i]; 170 171 Object value = BeanUtil.getDeclaredProperty(object, property); 172 if (value == null) { 173 continue; 174 } 175 176 String propertyName = className + '.' + property; 178 parameters.put(propertyName, value); 179 if ((count == 0) && (prefix != null)) { 180 result.append(prefix).append(' '); 181 } else { 182 result.append(" and "); 183 } 184 count++; 185 if (tableAlias.length() != 0) { 186 result.append(tableAlias).append('.'); 187 } 188 result.append(allColumns[i]).append('=').append(':').append(propertyName); 189 } 190 return count; 191 } 192 193 194 protected int whereWithFinders(StringBuilder result, String prefix, Object object, String tableAlias, int count) { 195 Class type = object.getClass(); 196 DbEntityDescriptor ded = dbOrm.lookup(type); 197 String className = StringUtil.uncapitalize(type.getSimpleName()); 198 199 Field [] allFields = DefaultIntrospector.lookup(type).getAllFields(true); 200 201 for (Field field : allFields) { 202 203 String operator = "="; 204 String lookupFieldName = field.getName(); 205 for (String [] op : operators) { 206 if (lookupFieldName.endsWith(op[0])) { 207 lookupFieldName = lookupFieldName.substring(0, lookupFieldName.length() - op[0].length()); 208 operator = op[1]; 209 break; 210 } 211 } 212 213 Object value = BeanUtil.getDeclaredProperty(object, field.getName()); 215 if (value == null) { 216 continue; 217 } 218 219 String columnName = ded.getColumnName(lookupFieldName); 221 if (columnName == null) { 222 continue; 223 } 224 225 String propertyName = className + '.' + field.getName(); 227 parameters.put(propertyName, value); 228 if ((count == 0) && (prefix != null)) { 229 result.append(prefix).append(' '); 230 } else { 231 result.append(" and "); 232 } 233 count++; 234 if (tableAlias.length() != 0) { 235 result.append(tableAlias).append('.'); 236 } 237 result.append(columnName).append(operator).append(':').append(propertyName); 238 } 239 return count; 240 } 241 242 244 245 249 public String parseValues(String template) { 250 StringBuilder result = new StringBuilder (template.length()); 251 while (true) { 252 String valueRef = nextRegion(result, template, "$V{", "}"); 253 if (valueRef == null) { 254 break; 255 } 256 257 boolean allProperties = false; 258 if (valueRef.startsWith("+")) { 259 allProperties = true; 260 valueRef = valueRef.substring(1); 261 } 262 263 Object data = null; 264 if (references != null) { 265 data = references.get(valueRef); 266 } 267 if (data == null) { 268 throw new DbOrmException("Unable to find object reference '" + valueRef + "'."); 269 } 270 271 Class type = data.getClass(); 272 String className = StringUtil.uncapitalize(type.getSimpleName()); 273 DbEntityDescriptor ded = dbOrm.lookup(type); 274 String [] properties = ded.getProperties(); 275 int size = 0; 276 for (String property : properties) { 277 Object value = BeanUtil.getDeclaredProperty(data, property); 278 if ((allProperties == false) && (value == null)) { 279 continue; 280 } 281 if (size > 0) { 282 result.append(',').append(' '); 283 } 284 size++; 285 result.append(':'); 286 String propertyName = className + '.' + property; 287 result.append(propertyName); 288 parameters.put(propertyName, value); 289 } 290 } 291 return result.toString(); 292 } 293 294 295 297 301 public String parseUpdate(String template) { 302 StringBuilder result = new StringBuilder (template.length()); 303 while (true) { 304 String valueRef = nextRegion(result, template, "$U{", "}"); 305 if (valueRef == null) { 306 break; 307 } 308 boolean allProperties = false; 309 if (valueRef.startsWith("+")) { 310 allProperties = true; 311 valueRef = valueRef.substring(1); 312 } 313 314 String tableRef = null; 315 int dotNdx = valueRef.indexOf('.'); 316 if (dotNdx != -1) { 317 tableRef = valueRef.substring(0, dotNdx); 318 valueRef = valueRef.substring(dotNdx + 1); 319 } 320 321 Object data = null; 322 if (references != null) { 323 data = references.get(valueRef); 324 } 325 if (data == null) { 326 throw new DbOrmException("Unable to find object reference '" + valueRef + "'."); 327 } 328 329 Class type = data.getClass(); 330 String className = StringUtil.uncapitalize(type.getSimpleName()); 331 DbEntityDescriptor ded = dbOrm.lookup(type); 332 String [] properties = ded.getProperties(); 333 String [] columns = ded.getColumns(); 334 int size = 0; 335 for (int i = 0; i < properties.length; i++) { 336 String property = properties[i]; 337 Object value = BeanUtil.getDeclaredProperty(data, property); 338 if ((allProperties == false) && (value == null)) { 339 continue; 340 } 341 if (size > 0) { 342 result.append(',').append(' '); 343 } 344 size++; 345 if (tableRef != null) { 346 if (tableRef.length() != 0) { 347 result.append(tableRef).append('.'); 348 } 349 } 350 result.append(columns[i]).append('='); 351 result.append(':'); 352 String propertyName = className + '.' + property; 353 result.append(propertyName); 354 parameters.put(propertyName, value); 355 } 356 } 357 return result.toString(); 358 } 359 360 361 362 364 public String generateQuery() { 365 return parseUpdate(parseValues(parseWhere(super.generateQuery()))); 366 } 367 368 } 369 | Popular Tags |