use of com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition in project kripton by xcesco.
the class JQLBuilder method buildJQLInsert.
/**
* <pre>
*
* INSERT INTO person (name, surname, birth_city, birth_day) VALUES (${name}, ${surname}, ${birthCity}, ${birthDay})
* </pre>
*
* @param method
* @param preparedJql
* @return
*/
private static JQL buildJQLInsert(SQLiteModelMethod method, final JQL result, String preparedJql) {
if (StringUtils.hasText(preparedJql)) {
result.value = preparedJql;
// INSERT can contains bind parameter in column values and select
// statement
final One<Boolean> inColumnValueSet = new One<Boolean>(false);
final One<Boolean> inWhereStatement = new One<Boolean>(false);
JQLChecker.getInstance().analyze(method, result, new JqlBaseListener() {
@Override
public void enterConflict_algorithm(Conflict_algorithmContext ctx) {
result.conflictAlgorithmType = ConflictAlgorithmType.valueOf(ctx.getText().toUpperCase());
}
@Override
public void enterProjected_columns(Projected_columnsContext ctx) {
result.containsSelectOperation = true;
}
@Override
public void enterWhere_stmt(Where_stmtContext ctx) {
inWhereStatement.value0 = true;
}
@Override
public void exitWhere_stmt(Where_stmtContext ctx) {
inWhereStatement.value0 = false;
}
@Override
public void enterColumn_value_set(Column_value_setContext ctx) {
inColumnValueSet.value0 = true;
}
@Override
public void exitColumn_value_set(Column_value_setContext ctx) {
inColumnValueSet.value0 = false;
}
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
if (inWhereStatement.value0) {
result.bindParameterOnWhereStatementCounter++;
} else if (inColumnValueSet.value0) {
result.bindParameterAsColumnValueCounter++;
}
AssertKripton.assertTrue(inWhereStatement.value0 || inColumnValueSet.value0, "unknown situation!");
}
});
if (result.containsSelectOperation) {
AssertKripton.assertTrueOrInvalidMethodSignException(method.getReturnClass().equals(TypeName.VOID), method, "defined JQL requires that method's return type is void");
}
// ASSERT: a INSERT-SELECT SQL can not contains parameters on values
// section.
} else {
// use annotation's attribute value and exclude and bean definition
// to
final Class<? extends Annotation> annotation = BindSqlInsert.class;
final SQLiteDaoDefinition dao = method.getParent();
final boolean includePrimaryKey = AnnotationUtility.extractAsBoolean(method.getElement(), annotation, AnnotationAttributeType.INCLUDE_PRIMARY_KEY);
// define field list
// every method parameter can be used only as insert field
InsertType insertResultType = SqlInsertBuilder.detectInsertType(method);
Set<String> fields;
if (insertResultType == InsertType.INSERT_BEAN) {
fields = extractFieldsFromAnnotation(method, annotation, includePrimaryKey);
} else {
fields = extractFieldsFromMethodParameters(method, annotation);
}
result.conflictAlgorithmType = ConflictAlgorithmType.valueOf(AnnotationUtility.extractAsEnumerationValue(method.getElement(), annotation, AnnotationAttributeType.CONFLICT_ALGORITHM_TYPE));
StringBuilder builder = new StringBuilder();
builder.append(INSERT_KEYWORD);
builder.append(" " + result.conflictAlgorithmType.getSqlForInsert());
builder.append(INTO_KEYWORD);
builder.append(" " + dao.getEntitySimplyClassName());
builder.append(" (");
builder.append(forEachFields(fields, new OnFieldListener() {
@Override
public String onField(String item) {
return item;
}
}));
builder.append(") ");
builder.append(VALUES_KEYWORD);
final One<String> prefix = new One<>("");
if (result.hasParamBean()) {
prefix.value0 = result.paramBean + ".";
}
builder.append(" (");
builder.append(forEachFields(fields, new OnFieldListener() {
@Override
public String onField(String item) {
return "${" + prefix.value0 + item + "}";
}
}));
builder.append(")");
result.value = builder.toString();
}
result.operationType = JQLType.INSERT;
result.dynamicReplace = new HashMap<>();
return result;
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition in project kripton by xcesco.
the class JQLBuilder method buildJQLDelete.
/**
* <pre>
* DELETE person WHERE id = ${bean.id} AND #{where}
* </pre>
*
* @param method
* @param preparedJql
* @return
*/
private static JQL buildJQLDelete(SQLiteModelMethod method, final JQL result, Map<JQLDynamicStatementType, String> dynamicReplace, String preparedJql) {
final SQLiteDaoDefinition dao = method.getParent();
if (StringUtils.hasText(preparedJql)) {
// in DELETE SQL only where statement can contains bind parameter
result.value = preparedJql;
JQLChecker.getInstance().analyze(method, result, new JqlBaseListener() {
@Override
public void enterBind_parameter(Bind_parameterContext ctx) {
result.bindParameterOnWhereStatementCounter++;
}
});
// where management
JQLChecker.getInstance().replaceVariableStatements(method, preparedJql, new JQLReplaceVariableStatementListenerImpl() {
@Override
public String onWhere(String statement) {
result.annotatedWhere = true;
result.staticWhereConditions = true;
return null;
}
});
// if (result.containsSelectOperation) {
// AssertKripton.failWithInvalidMethodSignException(!TypeUtility.typeName(Void.TYPE).equals(method.getReturnClass()),
// method,
// "method that contains SQL with inner SELECT can return only
// void");
// }
} else {
StringBuilder builder = new StringBuilder();
builder.append(DELETE_KEYWORD + " " + FROM_KEYWORD);
// entity name
builder.append(" " + dao.getEntitySimplyClassName());
builder.append(defineWhereStatement(method, result, BindSqlDelete.class, dynamicReplace));
result.value = builder.toString();
}
result.operationType = JQLType.DELETE;
result.dynamicReplace = dynamicReplace;
return result;
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition in project kripton by xcesco.
the class SqlInsertBuilder method generateInsertForContentProvider.
/**
* <p>
* Generate insert used in content provider class.
* </p>
*
* @param methodBuilder
* @param method
* @param insertResultType
*/
private static void generateInsertForContentProvider(TypeSpec.Builder classBuilder, final SQLiteModelMethod method, InsertType insertResultType) {
final SQLiteDaoDefinition daoDefinition = method.getParent();
final SQLiteEntity entity = daoDefinition.getEntity();
final Set<String> columns = new LinkedHashSet<>();
MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.contentProviderMethodName);
ParameterSpec parameterSpec;
parameterSpec = ParameterSpec.builder(Uri.class, "uri").build();
methodBuilder.addParameter(parameterSpec);
parameterSpec = ParameterSpec.builder(ContentValues.class, "contentValues").build();
methodBuilder.addParameter(parameterSpec);
methodBuilder.returns(Long.TYPE);
SqlBuilderHelper.generateLogForContentProviderBeginning(method, methodBuilder);
// just detect which columns are admitted
JQLChecker.getInstance().replace(method, method.jql, new JQLReplacerListenerImpl(method) {
@Override
public String onColumnName(String columnName) {
SQLProperty tempProperty = entity.get(columnName);
AssertKripton.assertTrueOrUnknownPropertyInJQLException(tempProperty != null, method, columnName);
columns.add(tempProperty.columnName);
return tempProperty.columnName;
}
@Override
public String onColumnFullyQualifiedName(String tableName, String columnName) {
AssertKripton.fail("Inconsistent state");
return null;
}
});
// generate columnCheckSet
SqlBuilderHelper.generateColumnCheckSet(classBuilder, method, columns);
// retrieve content values
methodBuilder.addStatement("$T _contentValues=contentValuesForContentProvider(contentValues)", KriptonContentValues.class);
// generate column check
SqlBuilderHelper.forEachColumnInContentValue(methodBuilder, method, "_contentValues.values().keySet()", true, null);
methodBuilder.addCode("\n");
// every controls was done in constructor of SQLiteModelMethod
for (ContentUriPlaceHolder variable : method.contentProviderUriVariables) {
SQLProperty entityProperty = entity.get(variable.value);
if (entityProperty != null) {
methodBuilder.addCode("// Add parameter $L at path segment $L\n", variable.value, variable.pathSegmentIndex);
TypeName entityPropertyType = entityProperty.getPropertyType().getTypeName();
if (TypeUtility.isString(entityPropertyType)) {
methodBuilder.addStatement("contentValues.put($S, uri.getPathSegments().get($L))", entityProperty.columnName, variable.pathSegmentIndex);
} else {
methodBuilder.addStatement("contentValues.put($S, Long.valueOf(uri.getPathSegments().get($L)))", entityProperty.columnName, variable.pathSegmentIndex);
}
}
}
// generate log for inser operation
SqlBuilderHelper.generateLogForContentValuesContentProvider(method, methodBuilder);
ConflictAlgorithmType conflictAlgorithmType = InsertBeanHelper.getConflictAlgorithmType(method);
String conflictString1 = "";
String conflictString2 = "";
if (conflictAlgorithmType != ConflictAlgorithmType.NONE) {
conflictString1 = "WithOnConflict";
conflictString2 = ", " + conflictAlgorithmType.getConflictAlgorithm();
methodBuilder.addCode("// conflict algorithm $L\n", method.jql.conflictAlgorithmType);
}
methodBuilder.addComment("insert operation");
methodBuilder.addStatement("long result = database().insert$L($S, null, _contentValues.values()$L)", conflictString1, daoDefinition.getEntity().getTableName(), conflictString2);
if (method.getParent().getParent().generateRx) {
GenericSQLHelper.generateSubjectNext(methodBuilder, SubjectType.INSERT);
}
// support for livedata
if (daoDefinition.hasLiveData()) {
methodBuilder.addComment("support for livedata");
methodBuilder.addStatement(BindDaoBuilder.METHOD_NAME_REGISTRY_EVENT + "(result>0?1:0)");
}
methodBuilder.addStatement("return result");
// javadoc
// 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 contentValues content values\n");
methodBuilder.addJavadoc("@return new row's id\n");
classBuilder.addMethod(methodBuilder.build());
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition in project kripton by xcesco.
the class SqlInsertBuilder method detectInsertType.
public static InsertType detectInsertType(SQLiteModelMethod method) {
SQLiteDaoDefinition daoDefinition = method.getParent();
SQLiteEntity entity = daoDefinition.getEntity();
InsertType insertResultType = null;
// check type of arguments
int count = 0;
for (Pair<String, TypeName> param : method.getParameters()) {
if (TypeUtility.isEquals(param.value1, typeName(entity.getElement()))) {
count++;
}
}
AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() == 0, method, " INSERT operations require at least one parameter");
if (count == 0) {
// method to insert raw data: no bean is used
insertResultType = InsertType.INSERT_RAW;
ModelAnnotation annotation = method.getAnnotation(BindSqlInsert.class);
// check value attribute
AssertKripton.failWithInvalidMethodSignException(AnnotationUtility.extractAsStringArray(method, annotation, AnnotationAttributeType.FIELDS).size() > 0, method, " can not use attribute %s in this kind of query definition", AnnotationAttributeType.FIELDS.getValue());
// check excludeFields attribute
AssertKripton.failWithInvalidMethodSignException(AnnotationUtility.extractAsStringArray(method, annotation, AnnotationAttributeType.EXCLUDED_FIELDS).size() > 0, method, " can not use attribute %s in this kind of query definition", AnnotationAttributeType.EXCLUDED_FIELDS.getValue());
// check if there is only one parameter
AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() != 1 && TypeUtility.isEquals(method.getParameters().get(0).value1, daoDefinition.getEntityClassName()), method);
// check no
AssertKripton.failWithInvalidMethodSignException(annotation.getAttributeAsBoolean(AnnotationAttributeType.INCLUDE_PRIMARY_KEY), method, "attribute '%s' can not be used here", AnnotationAttributeType.INCLUDE_PRIMARY_KEY.getValue());
} else if (count == 1) {
insertResultType = InsertType.INSERT_BEAN;
AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() > 1, method, " aspected only one parameter of %s type", daoDefinition.getEntityClassName());
} else {
throw (new InvalidMethodSignException(method, "only one parameter of type " + typeName(entity.getElement()) + " can be used"));
}
return insertResultType;
}
use of com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition in project kripton by xcesco.
the class SqlSelectBuilder method generateSelect.
/**
* @param elementUtils
* @param builder
* @param method
* @throws ClassNotFoundException
*/
public static void generateSelect(Builder builder, SQLiteModelMethod method) throws ClassNotFoundException {
SQLiteDaoDefinition daoDefinition = method.getParent();
SQLiteEntity entity = daoDefinition.getEntity();
SelectBuilderUtility.SelectType selectResultType = null;
// if true, field must be associate to ben attributes
TypeName returnTypeName = method.getReturnClass();
ParameterizedTypeName readBeanListener = ParameterizedTypeName.get(ClassName.get(OnReadBeanListener.class), ClassName.get(entity.getElement()));
ClassName readCursorListener = ClassName.get(OnReadCursorListener.class);
ModelAnnotation annotation = method.getAnnotation(BindSqlSelect.class);
int pageSize = annotation.getAttributeAsInt(AnnotationAttributeType.PAGE_SIZE);
AssertKripton.failWithInvalidMethodSignException(pageSize < 0, method, "in @%s(pageSize) must be set with positive number", BindSqlSelect.class.getSimpleName());
AssertKripton.failWithInvalidMethodSignException(pageSize > 0 && method.hasDynamicPageSizeConditions(), method, "can not define @%s(pageSize) and mark a method parameter with @%s ", BindSqlSelect.class.getSimpleName(), BindSqlPageSize.class.getSimpleName());
if (TypeUtility.isTypeIncludedIn(returnTypeName, Void.class, Void.TYPE)) {
// return VOID (in the parameters must be a listener)
if (SqlBuilderHelper.hasParameterOfType(method, readCursorListener)) {
selectResultType = SelectBuilderUtility.SelectType.LISTENER_CURSOR;
} else if (SqlBuilderHelper.hasParameterOfType(method, readBeanListener)) {
selectResultType = SelectBuilderUtility.SelectType.LISTENER_BEAN;
}
} else if (TypeUtility.isTypeIncludedIn(returnTypeName, Cursor.class)) {
// return Cursor (no listener)
selectResultType = SelectBuilderUtility.SelectType.CURSOR;
} else if (returnTypeName instanceof ParameterizedTypeName) {
ParameterizedTypeName returnParameterizedTypeName = (ParameterizedTypeName) returnTypeName;
ClassName returnParameterizedClassName = returnParameterizedTypeName.rawType;
// return List (no listener)
AssertKripton.assertTrueOrInvalidMethodSignException(returnParameterizedTypeName.typeArguments.size() == 1, method, "return type %s is not supported", returnTypeName);
TypeName elementName = returnParameterizedTypeName.typeArguments.get(0);
Class<?> wrapperClazz = Class.forName(returnParameterizedClassName.toString());
if (PaginatedResult.class.isAssignableFrom(wrapperClazz)) {
// method must have pageSize, statically or dynamically
// defined
AssertKripton.assertTrueOrInvalidMethodSignException(method.hasDynamicPageSizeConditions() || pageSize > 0, method, "use of PaginatedResult requires 'pageSize' attribute or a @%s annotated parameter", returnTypeName, BindSqlPageSize.class.getSimpleName());
// paged result
AssertKripton.assertTrueOrInvalidMethodSignException(TypeUtility.isEquals(elementName, entity.getName().toString()), method, "return type %s is not supported", returnTypeName);
selectResultType = SelectBuilderUtility.SelectType.PAGED_RESULT;
// set typeName of paginatedResult
method.paginatedResultName = "paginatedResult";
} else if (Collection.class.isAssignableFrom(wrapperClazz)) {
if (TypeUtility.isEquals(elementName, entity.getName().toString())) {
// entity list
selectResultType = SelectBuilderUtility.SelectType.LIST_BEAN;
} else if (SQLTransformer.isSupportedJDKType(elementName) || TypeUtility.isByteArray(elementName)) {
// scalar list
selectResultType = SelectBuilderUtility.SelectType.LIST_SCALAR;
} else {
AssertKripton.failWithInvalidMethodSignException(true, method, "%s is invalid return type", method.getReturnClass());
}
}
} else if (TypeUtility.isEquals(returnTypeName, entity)) {
// return one element (no listener)
selectResultType = SelectBuilderUtility.SelectType.BEAN;
} else if (SQLTransformer.isSupportedJDKType(returnTypeName) || TypeUtility.isByteArray(returnTypeName)) {
// return single value string, int, long, short, double, float,
// String (no listener)
selectResultType = SelectBuilderUtility.SelectType.SCALAR;
}
AssertKripton.assertTrueOrInvalidMethodSignException(selectResultType != null, method, "'%s' as return type is not supported", returnTypeName);
// generate select method
selectResultType.generate(builder, method);
if (method.hasLiveData()) {
// generate
selectResultType.generateLiveData(builder, method);
}
if (method.contentProviderEntryPathEnabled) {
// we need to generate UPDATE or DELETE for content provider to
generateSelectForContentProvider(builder, method, selectResultType);
}
}
Aggregations