use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.
the class ModifyBeanHelper method generate.
@Override
public void generate(TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, boolean updateMode, SQLiteModelMethod method, TypeName returnType) {
String beanNameParameter = method.getParameters().get(0).value0;
AssertKripton.assertTrueOrInvalidMethodSignException(!method.hasAdapterForParam(beanNameParameter), method, "method's parameter '%s' can not use a type adapter", beanNameParameter);
SqlAnalyzer analyzer = new SqlAnalyzer();
String whereCondition = ModifyRawHelper.extractWhereConditions(updateMode, method);
if (StringUtils.hasText(whereCondition)) {
whereCondition = whereCondition.trim();
}
analyzer.execute(BaseProcessor.elementUtils, method, whereCondition);
// retrieve content values
if (method.jql.hasDynamicParts() || method.jql.containsSelectOperation) {
methodBuilder.addStatement("$T _contentValues=contentValuesForUpdate()", KriptonContentValues.class);
} else {
String psName = method.buildPreparedStatementName();
// generate SQL for insert
classBuilder.addField(FieldSpec.builder(TypeName.get(SQLiteStatement.class), psName, Modifier.PRIVATE, Modifier.STATIC).build());
methodBuilder.beginControlFlow("if ($L==null)", psName);
SqlBuilderHelper.generateSQLForStaticQuery(method, methodBuilder);
methodBuilder.addStatement("$L = $T.compile(_context, _sql)", psName, KriptonDatabaseWrapper.class);
methodBuilder.endControlFlow();
methodBuilder.addStatement("$T _contentValues=contentValuesForUpdate($L)", KriptonContentValues.class, psName);
}
List<SQLProperty> listUsedProperty;
if (updateMode) {
listUsedProperty = CodeBuilderUtility.extractUsedProperties(methodBuilder, method, BindSqlUpdate.class);
AssertKripton.assertTrueOrInvalidMethodSignException(listUsedProperty.size() > 0, method, "no column was selected for update");
CodeBuilderUtility.generateContentValuesFromEntity(BaseProcessor.elementUtils, method, BindSqlUpdate.class, methodBuilder, analyzer.getUsedBeanPropertyNames());
} else {
listUsedProperty = CodeBuilderUtility.extractUsedProperties(methodBuilder, method, BindSqlDelete.class);
}
// build javadoc
buildJavadoc(methodBuilder, updateMode, method, beanNameParameter, whereCondition, listUsedProperty, analyzer.getUsedBeanPropertyNames());
// build where condition
generateWhereCondition(methodBuilder, method, analyzer);
methodBuilder.addCode("\n");
generateModifyQueryCommonPart(method, classBuilder, methodBuilder);
SQLiteDaoDefinition daoDefinition = method.getParent();
// support for livedata
if (daoDefinition.hasLiveData()) {
methodBuilder.addComment("support for livedata");
methodBuilder.addStatement(BindDaoBuilder.METHOD_NAME_REGISTRY_EVENT + "(result)");
}
// define return value
buildReturnCode(methodBuilder, updateMode, method, returnType);
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.
the class SqlAnalyzer method execute.
/**
* Extract from value string every placeholder ${}, replace it with ? and then convert every field typeName with column typeName. The result is a pair: the first value is the elaborated string. The second is the list of parameters associated to
* ?. This second parameter is the list of parameters and replaced with ?.
*/
public void execute(Elements elementUtils, SQLiteModelMethod method, String sqlStatement) {
SQLiteDaoDefinition daoDefinition = method.getParent();
SQLiteEntity entity = daoDefinition.getEntity();
usedMethodParameters = new HashSet<String>();
paramNames = new ArrayList<String>();
paramGetters = new ArrayList<String>();
usedBeanPropertyNames = new ArrayList<String>();
paramTypeNames = new ArrayList<TypeName>();
// replace placeholder ${ } with ?
{
Matcher matcher = PARAMETER.matcher(sqlStatement);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
matcher.appendReplacement(buffer, "?");
paramNames.add(matcher.group(1));
}
matcher.appendTail(buffer);
sqlStatement = buffer.toString();
}
// replace property typeName to column typeName
{
Matcher matcher = WORD.matcher(sqlStatement);
StringBuffer buffer = new StringBuffer();
while (matcher.find()) {
SQLProperty property = entity.findPropertyByName(matcher.group(1));
if (property != null) {
matcher.appendReplacement(buffer, property.columnName);
}
}
matcher.appendTail(buffer);
sqlStatement = buffer.toString();
}
TypeName rawNameType;
// analyze parametersName
String effectiveName;
for (String rawName : paramNames) {
JQLParameterName pName = JQLParameterName.parse(rawName);
if (!pName.isNested()) {
effectiveName = method.findParameterNameByAlias(pName.getValue());
rawNameType = method.findParameterTypeByAliasOrName(effectiveName);
if (rawNameType == null) {
throw new MethodParameterNotFoundException(method, effectiveName);
}
paramGetters.add(effectiveName);
paramTypeNames.add(rawNameType);
usedMethodParameters.add(effectiveName);
usedBeanPropertyNames.add(null);
} else {
if (method.findParameterTypeByAliasOrName(pName.getBeanName()) == null) {
throw new MethodParameterNotFoundException(method, pName.getBeanName());
}
if (TypeUtility.isEquals(method.findParameterTypeByAliasOrName(pName.getBeanName()), entity) && entity.contains(pName.getValue())) {
// there are nested property invocation
paramGetters.add(method.findParameterNameByAlias(pName.getBeanName()) + "." + getter(entity.findPropertyByName(pName.getValue())));
usedBeanPropertyNames.add(pName.getValue());
paramTypeNames.add(TypeUtility.typeName(entity.findPropertyByName(pName.getValue()).getElement().asType()));
usedMethodParameters.add(method.findParameterNameByAlias(pName.getBeanName()));
} else {
throw (new PropertyInAnnotationNotFoundException(method, pName.getValue()));
}
}
// } else {
// throw (new PropertyInAnnotationNotFoundException(method, rawName));
// }
}
this.sqlStatement = sqlStatement;
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.
the class SqlSelectBuilder method generateSelectForContentProvider.
/**
* <p>
* Generate select used in content provider class.
* </p>
*
* @param elementUtils
* @param builder
* @param method
* @param selectResultType
*/
private static void generateSelectForContentProvider(Builder builder, final SQLiteModelMethod method, SelectType selectResultType) {
final SQLiteDaoDefinition daoDefinition = method.getParent();
final SQLiteEntity entity = daoDefinition.getEntity();
final Set<String> columns = new LinkedHashSet<>();
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.contentProviderMethodName);
// params
methodBuilder.addParameter(ParameterSpec.builder(Uri.class, "uri").build());
methodBuilder.addParameter(ParameterSpec.builder(ArrayTypeName.of(String.class), "projection").build());
methodBuilder.addParameter(ParameterSpec.builder(String.class, "selection").build());
methodBuilder.addParameter(ParameterSpec.builder(ArrayTypeName.of(String.class), "selectionArgs").build());
methodBuilder.addParameter(ParameterSpec.builder(String.class, "sortOrder").build());
methodBuilder.returns(Cursor.class);
SqlBuilderHelper.generateLogForContentProviderBeginning(method, methodBuilder);
JQLChecker jqlChecker = JQLChecker.getInstance();
SplittedSql splittedSql = generateSQL(method, methodBuilder, true);
List<JQLPlaceHolder> placeHolders = jqlChecker.extractFromVariableStatement(method, splittedSql.sqlWhereStatement);
// remove placeholder for dynamic where, we are not interested here
placeHolders = SqlBuilderHelper.removeDynamicPlaceHolder(placeHolders);
AssertKripton.assertTrue(placeHolders.size() == method.contentProviderUriVariables.size(), "In '%s.%s' content provider URI path variables and variables in where conditions are different. If SQL uses parameters, they must be defined in URI path.", daoDefinition.getName(), method.getName());
Set<JQLProjection> projectedColumns = jqlChecker.extractProjections(method, method.jql.value, entity);
for (JQLProjection item : projectedColumns) {
if (item.type == ProjectionType.COLUMN) {
columns.add(entity.get(item.column.trim()).columnName);
} else {
columns.add(item.expression.trim());
}
}
methodBuilder.addStatement("$T _contentValues=contentValues()", KriptonContentValues.class);
methodBuilder.addStatement("$T _sqlBuilder=sqlBuilder()", StringBuilder.class);
SqlModifyBuilder.generateInitForDynamicWhereVariables(method, methodBuilder, "selection", "selectionArgs");
methodBuilder.addStatement("$T _projectionBuffer=new $T()", StringBuilder.class, StringBuilder.class);
if (method.jql.isOrderBy()) {
methodBuilder.addStatement("String _sortOrder=sortOrder");
}
methodBuilder.addStatement("_sqlBuilder.append($S)", splittedSql.sqlBasic);
SqlBuilderHelper.generateWhereCondition(methodBuilder, method, false);
generateDynamicPartOfQuery(method, methodBuilder, splittedSql);
// generate and check columns
{
methodBuilder.addCode("\n// manage projected columns\n");
methodBuilder.addStatement("String _columnSeparator=\"\"");
methodBuilder.beginControlFlow("if (projection!=null && projection.length>0)");
// generate projected column check
String columnCheckSetName = SqlBuilderHelper.generateColumnCheckSet(builder, method, columns);
SqlBuilderHelper.forEachColumnInContentValue(methodBuilder, method, "projection", true, new OnColumnListener() {
@Override
public void onColumnCheck(MethodSpec.Builder methodBuilder, String projectedColumnVariable) {
methodBuilder.addStatement("_projectionBuffer.append(_columnSeparator + $L)", projectedColumnVariable);
methodBuilder.addStatement("_columnSeparator=\", \"");
}
});
methodBuilder.nextControlFlow("else");
methodBuilder.beginControlFlow("for (String column: $L)", columnCheckSetName);
methodBuilder.addStatement("_projectionBuffer.append(_columnSeparator + column)");
methodBuilder.addStatement("_columnSeparator=\", \"");
methodBuilder.endControlFlow();
methodBuilder.endControlFlow();
int i = 0;
// every controls was done in constructor of SQLiteModelMethod
for (ContentUriPlaceHolder variable : method.contentProviderUriVariables) {
AssertKripton.assertTrue(SqlBuilderHelper.validate(variable.value, placeHolders, i), "In '%s.%s' content provider URI path and where conditions must use same set of variables", daoDefinition.getName(), method.getName());
SQLProperty entityProperty = entity.get(variable.value);
TypeName methodParameterType = method.findParameterTypeByAliasOrName(variable.value);
methodBuilder.addCode("// Add parameter $L at path segment $L\n", variable.value, variable.pathSegmentIndex);
// methodBuilder.addStatement("_sqlWhereParams.add(uri.getPathSegments().get($L))",
// variable.pathSegmentIndex);
methodBuilder.addStatement("_contentValues.addWhereArgs(uri.getPathSegments().get($L))", variable.pathSegmentIndex);
if (entityProperty != null) {
AssertKripton.assertTrue(TypeUtility.isTypeIncludedIn(entityProperty.getPropertyType().getTypeName(), String.class, Long.class, Long.TYPE), "In '%s.%s' content provider URI path variables %s must be String of Long type", daoDefinition.getName(), method.getName(), entityProperty.getName());
} else if (methodParameterType != null) {
AssertKripton.assertTrue(TypeUtility.isTypeIncludedIn(methodParameterType, String.class, Long.class, Long.TYPE), "In '%s.%s' content provider URI path variables %s must be String of Long type", daoDefinition.getName(), method.getName(), method.findParameterNameByAlias(variable.value));
}
i++;
}
}
// _sql must be always defined
methodBuilder.addStatement("String _sql=String.format(_sqlBuilder.toString(), _projectionBuffer.toString())");
SqlBuilderHelper.generateLogForSQL(method, methodBuilder);
SqlBuilderHelper.generateLogForWhereParameters(method, methodBuilder);
methodBuilder.addCode("\n// execute query\n");
// methodBuilder.addStatement("Cursor _result =
// database().rawQuery(_sql, _sqlWhereParams.toArray(new
// String[_sqlWhereParams.size()]))");
methodBuilder.addStatement("Cursor _result = database().rawQuery(_sql, _contentValues.whereArgsAsArray())");
methodBuilder.addStatement("return _result");
// we add at last javadoc, because need info is built at last.
SqlBuilderHelper.generateJavaDocForContentProvider(method, methodBuilder);
methodBuilder.addJavadoc("@param uri $S\n", method.contentProviderUriTemplate.replace("*", "[*]"));
methodBuilder.addJavadoc("@param selection dynamic part of <code>where</code> statement $L\n", method.hasDynamicWhereConditions() ? "" : "<b>NOT USED</b>");
methodBuilder.addJavadoc("@param selectionArgs arguments of dynamic part of <code>where</code> statement $L\n", method.hasDynamicWhereConditions() ? "" : "<b>NOT USED</b>");
methodBuilder.addJavadoc("@return number of effected rows\n");
builder.addMethod(methodBuilder.build());
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.
the class SqlSelectBuilder method convertJQL2SQL.
/**
* @param schema
* @param entity
* @param method
* @param jqlChecker
* @return
*/
public static String convertJQL2SQL(final SQLiteModelMethod method, final boolean replaceWithQuestion) {
JQLChecker jqlChecker = JQLChecker.getInstance();
// convert jql to sql
String sql = jqlChecker.replace(method, method.jql, new JQLReplacerListenerImpl(method) {
@Override
public String onBindParameter(String bindParameterName) {
if (replaceWithQuestion) {
return "?";
}
return "${" + bindParameterName + "}";
}
@Override
public String onColumnName(String columnName) {
SQLProperty tempProperty = currentEntity.get(columnName);
AssertKripton.assertTrueOrUnknownPropertyInJQLException(tempProperty != null, method, columnName);
return tempProperty.columnName;
}
});
return sql;
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLProperty in project kripton by xcesco.
the class JavadocUtility method generateJavaDocForSelect.
public static void generateJavaDocForSelect(MethodSpec.Builder methodBuilder, List<String> sqlParams, final SQLiteModelMethod method, ModelAnnotation annotation, Set<JQLProjection> fieldList, SelectType selectResultType, JavadocPart... javadocParts) {
final SQLiteDaoDefinition daoDefinition = method.getParent();
final SQLiteEntity entity = daoDefinition.getEntity();
TypeName beanTypeName = TypeName.get(daoDefinition.getEntity().getElement().asType());
String sql = JQLChecker.getInstance().replace(method, method.jql, new JQLReplacerListenerImpl(method) {
@Override
public String onColumnName(String columnName) {
SQLProperty tempProperty = daoDefinition.getEntity().get(columnName);
AssertKripton.assertTrueOrUnknownPropertyInJQLException(tempProperty != null, method, columnName);
return tempProperty.columnName;
}
});
Set<JQLProjection> projectedColumns = JQLChecker.getInstance().extractProjections(method, method.jql.value, entity);
methodBuilder.addJavadoc("<h2>Select SQL:</h2>\n\n", annotation.getSimpleName());
methodBuilder.addJavadoc("<pre>$L</pre>", sql);
methodBuilder.addJavadoc("\n\n");
// there will be alway some projected column
{
methodBuilder.addJavadoc("<h2>Projected columns:</h2>\n");
methodBuilder.addJavadoc("<dl>\n");
for (JQLProjection column : projectedColumns) {
// KRIPTON_DEBUG field info only it exists
if (column.column != null) {
methodBuilder.addJavadoc("\t<dt>$L</dt>", column.property.columnName);
// SQLProperty attribute = fieldList.value1.get(i);
methodBuilder.addJavadoc("<dd>is associated to bean's property <strong>$L</strong></dd>", column.column);
} else {
methodBuilder.addJavadoc("\t<dt>$L</dt>", column.expression);
methodBuilder.addJavadoc("<dd>no bean's property is associated</dd>");
}
methodBuilder.addJavadoc("\n");
}
methodBuilder.addJavadoc("</dl>");
methodBuilder.addJavadoc("\n\n");
}
// dynamic parts
if (method.hasDynamicOrderByConditions() || method.hasDynamicWhereConditions() || method.hasDynamicPageSizeConditions()) {
methodBuilder.addJavadoc("<h2>Method's parameters and associated dynamic parts:</h2>\n");
methodBuilder.addJavadoc("<dl>\n");
if (method.hasDynamicWhereConditions()) {
methodBuilder.addJavadoc("<dt>$L</dt><dd>is part of where conditions resolved at runtime. In above SQL it is displayed as #{$L}</dd>\n", method.dynamicWhereParameterName, JQLDynamicStatementType.DYNAMIC_WHERE);
}
if (method.hasDynamicOrderByConditions()) {
methodBuilder.addJavadoc("<dt>$L</dt>is part of order statement resolved at runtime. In above SQL it is displayed as #{$L}</dd>\n", method.dynamicOrderByParameterName, JQLDynamicStatementType.DYNAMIC_ORDER_BY);
}
if (method.hasDynamicPageSizeConditions()) {
methodBuilder.addJavadoc("<dt>$L</dt>is part of limit statement resolved at runtime. In above SQL it is displayed as #{$L}</dd>\n", method.dynamicPageSizeName, JQLDynamicStatementType.DYNAMIC_PAGE_SIZE);
}
methodBuilder.addJavadoc("</dl>");
methodBuilder.addJavadoc("\n\n");
}
// query parameters
if (sqlParams.size() > 0) {
methodBuilder.addJavadoc("<h2>Query's parameters:</h2>\n");
methodBuilder.addJavadoc("<dl>\n");
for (String param : sqlParams) {
methodBuilder.addJavadoc("\t<dt>$L</dt><dd>is binded to method's parameter <strong>$L</strong></dd>\n", "${" + param + "}", method.findParameterNameByAlias(param));
}
methodBuilder.addJavadoc("</dl>");
methodBuilder.addJavadoc("\n\n");
}
// method params
ParameterSpec parameterSpec;
for (Pair<String, TypeName> item : method.getParameters()) {
parameterSpec = ParameterSpec.builder(item.value1, item.value0).build();
methodBuilder.addJavadoc("@param $L\n", parameterSpec.name);
if (beanTypeName.equals(item.value1)) {
methodBuilder.addJavadoc("\tis used as $L\n", "${" + method.findParameterAliasByName(item.value0) + "}");
} else if (TypeUtility.isTypeEquals(item.value1, ParameterizedTypeName.get(TypeUtility.className(OnReadBeanListener.class), beanTypeName))) {
methodBuilder.addJavadoc("\tis the $T listener\n", beanTypeName);
} else if (TypeUtility.isTypeEquals(item.value1, TypeUtility.className(OnReadCursorListener.class))) {
methodBuilder.addJavadoc("\tis the cursor listener\n", beanTypeName);
} else if (item.value0.equals(method.dynamicWhereParameterName)) {
methodBuilder.addJavadoc("\tis used as <strong>dynamic WHERE statement</strong> and it is formatted by ({@link $T#format})\n", StringUtils.class);
} else if (item.value0.equals(method.dynamicOrderByParameterName)) {
methodBuilder.addJavadoc("\tis used as <strong>dynamic ORDER BY statement</strong> and it is formatted by ({@link $T#format})\n", StringUtils.class);
} else if (item.value0.equals(method.dynamicPageSizeName)) {
methodBuilder.addJavadoc("\tis used as <strong>dynamic LIMIT statement</strong> and it is formatted by ({@link $T#format})\n", StringUtils.class);
} else {
methodBuilder.addJavadoc("\tis binded to <code>$L</code>\n", "${" + method.findParameterAliasByName(item.value0) + "}");
}
}
for (JavadocPart item : javadocParts) {
if (item.javadocPartType != JavadocPartType.ADD_PARAMETER)
continue;
methodBuilder.addJavadoc("@param $L\n", item.name);
methodBuilder.addJavadoc("\t$L\n", item.description);
}
for (JavadocPart item : javadocParts) {
if (item.javadocPartType != JavadocPartType.RETURN)
continue;
methodBuilder.addJavadoc("@return $L\n", item.description);
// override return
return;
}
// return type
switch(selectResultType) {
case BEAN:
methodBuilder.addJavadoc("@return selected bean or <code>null</code>.\n");
break;
case CURSOR:
methodBuilder.addJavadoc("@return cursor. Closing the cursor is delegated to the calling code.\n");
break;
case LIST_BEAN:
methodBuilder.addJavadoc("@return collection of bean or empty collection.\n");
break;
case LIST_SCALAR:
methodBuilder.addJavadoc("@return collection of single value extracted by query.\n");
break;
case SCALAR:
methodBuilder.addJavadoc("@return single value extracted by query.\n");
break;
case PAGED_RESULT:
methodBuilder.addJavadoc("@return paginated result.\n");
break;
default:
// case LISTENER_CURSOR:
break;
}
}
Aggregations