Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.abubusoft.kripton.processor.sqlite.InsertRawHelper Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2015, 2017 Francesco Benincasa ([email protected] ).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.abubusoft.kripton.processor.sqlite;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.lang.model.element.Modifier;
import com.abubusoft.kripton.android.ColumnType;
import com.abubusoft.kripton.android.sqlite.KriptonContentValues;
import com.abubusoft.kripton.android.sqlite.KriptonDatabaseWrapper;
import com.abubusoft.kripton.common.One;
import com.abubusoft.kripton.common.Pair;
import com.abubusoft.kripton.processor.core.AssertKripton;
import com.abubusoft.kripton.processor.core.reflect.TypeUtility;
import com.abubusoft.kripton.processor.exceptions.InvalidMethodSignException;
import com.abubusoft.kripton.processor.exceptions.PropertyNotFoundException;
import com.abubusoft.kripton.processor.sqlite.GenericSQLHelper.SubjectType;
import com.abubusoft.kripton.processor.sqlite.SqlInsertBuilder.InsertCodeGenerator;
import com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLChecker;
import com.abubusoft.kripton.processor.sqlite.grammars.jql.JQLReplacerListenerImpl;
import com.abubusoft.kripton.processor.sqlite.grammars.jsql.JqlParser.Column_value_setContext;
import com.abubusoft.kripton.processor.sqlite.model.SQLProperty;
import com.abubusoft.kripton.processor.sqlite.model.SQLiteDaoDefinition;
import com.abubusoft.kripton.processor.sqlite.model.SQLiteEntity;
import com.abubusoft.kripton.processor.sqlite.model.SQLiteModelMethod;
import com.abubusoft.kripton.processor.sqlite.transform.SQLTransformer;
import com.squareup.javapoet.FieldSpec;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeName;
import com.squareup.javapoet.TypeSpec;
import android.database.sqlite.SQLiteStatement;
/**
* The Class InsertRawHelper.
*/
public class InsertRawHelper implements InsertCodeGenerator {
/* (non-Javadoc)
* @see com.abubusoft.kripton.processor.sqlite.SqlInsertBuilder.InsertCodeGenerator#generate(com.squareup.javapoet.TypeSpec.Builder, com.squareup.javapoet.MethodSpec.Builder, boolean, com.abubusoft.kripton.processor.sqlite.model.SQLiteModelMethod, com.squareup.javapoet.TypeName)
*/
@Override
public void generate(TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, boolean mapFields, final SQLiteModelMethod method, TypeName returnType) {
final SQLiteDaoDefinition daoDefinition = method.getParent();
final SQLiteEntity entity = method.getEntity();
//boolean nullable;
// generate javadoc
generateJavaDoc(methodBuilder, method, returnType);
// standard INSERT
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);
}
if (method.jql.containsSelectOperation) {
// INSERT-SELECT
GenericSQLHelper.generateGenericExecSQL(methodBuilder, method);
} else {
methodBuilder.addCode("\n");
List> fieldsToUpdate = method.getParameters();
fieldsToUpdate=SqlBuilderHelper.orderContentValues(method, fieldsToUpdate);
for (Pair item : fieldsToUpdate) {
String propertyName = method.findParameterAliasByName(item.value0);
SQLProperty property = entity.get(propertyName);
if (property == null)
throw (new PropertyNotFoundException(method, propertyName, item.value1));
// check same type
TypeUtility.checkTypeCompatibility(method, item, property);
if (method.isLogEnabled()) {
methodBuilder.addCode("_contentValues.put($S, ", property.columnName);
} else {
methodBuilder.addCode("_contentValues.put(");
}
// it does not need to be converted in string
SQLTransformer.javaMethodParam2ContentValues(methodBuilder, method, item.value0, item.value1, property);
methodBuilder.addCode(");\n");
}
methodBuilder.addCode("\n");
SqlBuilderHelper.generateLog(method, methodBuilder);
methodBuilder.addComment("insert operation");
if (method.jql.hasDynamicParts() || method.jql.containsSelectOperation) {
// does not memorize compiled statement, it can vary every time generate SQL for insert
SqlBuilderHelper.generateSQLForInsertDynamic(method, methodBuilder);
methodBuilder.addStatement("long result = $T.insert(_context, _sql, _contentValues)", KriptonDatabaseWrapper.class);
} else {
String psName=method.buildPreparedStatementName();
methodBuilder.addStatement("long result = $T.insert($L, _contentValues)", KriptonDatabaseWrapper.class, psName);
}
if (daoDefinition.getParent().generateRx) {
// rx management
String rxIdGetter=null;
if (entity.getPrimaryKey().columnType==ColumnType.PRIMARY_KEY) {
rxIdGetter="result";
} else {
// unmanaged pk
for (Pair item : fieldsToUpdate) {
String propertyName = method.findParameterAliasByName(item.value0);
SQLProperty property = entity.get(propertyName);
if (property.isPrimaryKey()) {
rxIdGetter=item.value0;
}
}
}
GenericSQLHelper.generateSubjectNext(entity, methodBuilder, SubjectType.INSERT, rxIdGetter);
}
// support for livedata
if (daoDefinition.hasLiveData()) {
methodBuilder.addComment("support for livedata");
methodBuilder.addStatement(BindDaoBuilder.METHOD_NAME_REGISTRY_EVENT+"(result>0?1:0)");
}
// define return value
if (returnType == TypeName.VOID) {
} else if (TypeUtility.isTypeIncludedIn(returnType, Boolean.TYPE, Boolean.class)) {
methodBuilder.addStatement("return result!=-1");
} else if (TypeUtility.isTypeIncludedIn(returnType, Long.TYPE, Long.class)) {
methodBuilder.addStatement("return result");
} else if (TypeUtility.isTypeIncludedIn(returnType, Integer.TYPE, Integer.class)) {
methodBuilder.addStatement("return (int)result");
} else if (TypeUtility.isTypeIncludedIn(returnType, String.class)) {
methodBuilder.addStatement("return String.valueOf(result)");
} else {
// more than one listener found
throw (new InvalidMethodSignException(method, "invalid return type"));
}
}
}
/**
* Generate java doc.
*
* @param methodBuilder the method builder
* @param method the method
* @param returnType the return type
* @return string sql
*/
public String generateJavaDoc(MethodSpec.Builder methodBuilder, final SQLiteModelMethod method, TypeName returnType) {
final SQLiteEntity entity = method.getEntity();
final One inColumnValues = new One(false);
final List> methodParamsUsedAsColumnValue = new ArrayList<>();
final List> methodParamsUsedAsParameter = new ArrayList<>();
// transform JQL to SQL
String sqlInsert = JQLChecker.getInstance().replace(method, method.jql, new JQLReplacerListenerImpl(method) {
@Override
public void onColumnValueSetBegin(Column_value_setContext ctx) {
inColumnValues.value0 = true;
}
@Override
public void onColumnValueSetEnd(Column_value_setContext ctx) {
inColumnValues.value0 = false;
}
@Override
public String onColumnName(String columnName) {
Set property = currentSchema.getPropertyBySimpleName(columnName);
AssertKripton.assertTrueOrUnknownPropertyInJQLException(property != null, method, columnName);
SQLProperty tempProperty = property.iterator().next();
AssertKripton.assertTrueOrUnknownPropertyInJQLException(tempProperty != null, method, columnName);
return tempProperty.columnName;
}
@Override
public String onBindParameter(String bindParameterName, boolean inStatement) {
String resolvedParamName = method.findParameterNameByAlias(bindParameterName);
if (inColumnValues.value0) {
methodParamsUsedAsColumnValue.add(new Pair<>(resolvedParamName, method.findParameterType(resolvedParamName)));
} else {
methodParamsUsedAsParameter.add(new Pair<>(resolvedParamName, method.findParameterType(resolvedParamName)));
}
return SqlAnalyzer.PARAM_PREFIX + resolvedParamName + SqlAnalyzer.PARAM_SUFFIX;
}
});
methodBuilder.addJavadoc("SQL insert \n");
methodBuilder.addJavadoc("$L \n", sqlInsert);
methodBuilder.addJavadoc("\n");
if (methodParamsUsedAsColumnValue.size() > 0) {
// list of inserted fields
methodBuilder.addJavadoc("Inserted columns: \n");
methodBuilder.addJavadoc("\n");
for (Pair property : methodParamsUsedAsColumnValue) {
//String resolvedName = method.findParameterAliasByName(property.value0);
String resolvedName=method.findParameterNameByAlias(property.value0);
/*SQLProperty prop = entity.get(resolvedName);
if (prop == null)
throw (new PropertyNotFoundException(method, property.value0, property.value1));*/
methodBuilder.addJavadoc("\t$L ", property.value0);
methodBuilder.addJavadoc("is binded to query's parameter $L and method's parameter $L \n", SqlAnalyzer.PARAM_PREFIX + property.value0 + SqlAnalyzer.PARAM_SUFFIX, resolvedName);
}
methodBuilder.addJavadoc(" \n\n");
}
// list of parameters
if (methodParamsUsedAsParameter.size() > 0) {
methodBuilder.addJavadoc("Method parameters used as sql parameters \n");
methodBuilder.addJavadoc("\n");
for (Pair property : methodParamsUsedAsParameter) {
String resolvedName = method.findParameterNameByAlias(property.value0);
methodBuilder.addJavadoc("\t$L ", resolvedName);
methodBuilder.addJavadoc("is binded to query's parameter "+SqlAnalyzer.PARAM_PREFIX+"$L"+SqlAnalyzer.PARAM_SUFFIX+" \n", property.value0);
}
methodBuilder.addJavadoc(" \n\n");
}
for (Pair param : method.getParameters()) {
if (methodParamsUsedAsColumnValue.contains(param)) {
methodBuilder.addJavadoc("@param $L\n", param.value0);
if (entity.get(method.findParameterAliasByName(param.value0))!=null) {
methodBuilder.addJavadoc("\tis binded to column value $L \n", entity.get(method.findParameterAliasByName(param.value0)).columnName);
} else {
// in case of JQL explicit, you can declare name of parameter
methodBuilder.addJavadoc("\tis binded to query parameter $L \n", param.value0); }
}
if (methodParamsUsedAsParameter.contains(param)) {
methodBuilder.addJavadoc("@param $L\n", param.value0);
methodBuilder.addJavadoc("\tis used as parameter\n");
}
}
generateJavaDocReturnType(methodBuilder, returnType);
return sqlInsert;
}
/**
* Generate javadoc about return type of method.
*
* @param methodBuilder the method builder
* @param returnType the return type
*/
public static void generateJavaDocReturnType(MethodSpec.Builder methodBuilder, TypeName returnType) {
if (returnType == TypeName.VOID) {
} else if (TypeUtility.isTypeIncludedIn(returnType, Boolean.TYPE, Boolean.class)) {
methodBuilder.addJavadoc("\n");
methodBuilder.addJavadoc("@return true
if record is inserted, false
otherwise");
} else if (TypeUtility.isTypeIncludedIn(returnType, Long.TYPE, Long.class)) {
methodBuilder.addJavadoc("\n");
methodBuilder.addJavadoc("@return id of inserted record");
} else if (TypeUtility.isTypeIncludedIn(returnType, Integer.TYPE, Integer.class)) {
methodBuilder.addJavadoc("\n");
methodBuilder.addJavadoc("@return id of inserted record");
}
methodBuilder.addJavadoc("\n");
}
}