<p>
Generate insert used in content provider class.
</p>

@param classBuilder
the class builder
@param method
the method
@param insertResultType
the insert result type
976759
private static void generateInsertForContentProvider(TypeSpec.Builder classBuilder, final SQLiteModelMethod method,
			InsertType insertResultType) {
		final SQLiteDaoDefinition daoDefinition = method.getParent();
		final SQLiteEntity entity = method.getEntity();
		final Set<String> columns = new LinkedHashSet<>();

		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.contentProviderMethodName);
		if (!method.getParent().hasSamePackageOfSchema()) {
			methodBuilder.addModifiers(Modifier.PUBLIC);
		}

		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");

		String rxIdGetter = "result";

		// extract pathVariables
		// generate get uri variables in content values
		// 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);
				}
			}

			if (entityProperty.isPrimaryKey()) {
				rxIdGetter = PropertyUtility.getter(entityProperty);
			}
		}

		// 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, entity.getTableName(), conflictString2);
		if (method.getParent().getParent().generateRx) {
			SQLProperty primaryKey = entity.getPrimaryKey();
			if (primaryKey.columnType == ColumnType.PRIMARY_KEY) {
				// long autogenerated
				rxIdGetter = "result";
			} else {

				if (primaryKey.isType(String.class)) {
					rxIdGetter = String.format("contentValues.getAsString(\"%s\")", primaryKey.columnName);
				} else {
					rxIdGetter = String.format("contentValues.getAsLong(\"%s\")", primaryKey.columnName);
				}
			}

			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)");
		}

		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());
	}
1302730
public static void generateGenericExecSQL(MethodSpec.Builder methodBuilder, final SQLiteModelMethod method) {

		boolean nullable;
		final List<String> paramsList = new ArrayList<String>();
		final List<String> contentValueList = new ArrayList<String>();
		final One<Boolean> columnsToUpdate = new One<Boolean>(true);

		String sql = JQLChecker.getInstance().replace(method, method.jql, new JQLReplacerListenerImpl(method) {

			@Override
			public void onWhereStatementBegin(Where_stmtContext ctx) {
				super.onWhereStatementBegin(ctx);

				columnsToUpdate.value0 = false;
			}

			@Override
			public void onWhereStatementEnd(Where_stmtContext ctx) {
				super.onWhereStatementEnd(ctx);

				columnsToUpdate.value0 = true;
			}

			@Override
			public String onColumnName(String columnName) {
				String resolvedName = currentSchema.findColumnNameByPropertyName(method, columnName);
				AssertKripton.assertTrueOrUnknownPropertyInJQLException(resolvedName != null, method, columnName);

				return resolvedName;

			}

			@Override
			public String onBindParameter(String bindParameterName, boolean inStatement) {
				String propertyName = method.findParameterAliasByName(bindParameterName);

				if (columnsToUpdate.value0) {
					contentValueList.add(propertyName);
				} else {
					paramsList.add(propertyName);
				}
				return "?";
			}
		});

		// update/insert columns
		final SQLiteEntity entity = method.getEntity();
		for (String item : contentValueList) {
			// ASSERT: property is always in entity
			String propertyName = method.findParameterNameByAlias(item);
			TypeName paramType = method.findParameterTypeByAliasOrName(item);

			SQLProperty property = entity.get(item);

			if (propertyName == null)
				throw (new PropertyNotFoundException(method, propertyName, paramType));

			Pair<String, TypeName> methodParam = new Pair<String, TypeName>(propertyName, paramType);

			// check same type
			TypeUtility.checkTypeCompatibility(method, methodParam, property);
			// check nullabliity
			// nullable = TypeUtility.isNullable(method, methodParam, property);
			//
			// if (nullable) {
			// // it use raw method param's typeName
			// methodBuilder.beginControlFlow("if ($L!=null)", methodParam.value0);
			// }

			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, methodParam.value0, methodParam.value1,
					property);
			methodBuilder.addCode(");\n");
			// if (nullable) {
			// methodBuilder.nextControlFlow("else");
			//
			// if (method.isLogEnabled()) {
			// methodBuilder.addStatement("_contentValues.putNull($S)", property.columnName);
			// } else {
			// methodBuilder.addStatement("_contentValues.putNull()");
			// }
			//
			// methodBuilder.endControlFlow();
			// }

		}

		// where condition
		methodBuilder.addComment("build where condition");
		{
			// String separator = "";
			TypeName paramType;
			String realName;

			for (String item : paramsList) {
				methodBuilder.addCode("_contentValues.addWhereArgs(");

				paramType = method.findParameterTypeByAliasOrName(item);
				realName = method.findParameterNameByAlias(item);

				AssertKripton.assertTrueOrUnknownPropertyInJQLException(paramType != null, method, item);

				// code for query arguments
				nullable = TypeUtility.isNullable(paramType);
				if (nullable) {
					methodBuilder.addCode("($L==null?\"\":", realName);
				}

				// check for string conversion
				TypeUtility.beginStringConversion(methodBuilder, paramType);

				SQLTransformer.javaMethodParam2ContentValues(methodBuilder, method, realName, paramType, null);

				// check for string conversion
				TypeUtility.endStringConversion(methodBuilder, paramType);

				if (nullable) {
					methodBuilder.addCode(")");
				}

				methodBuilder.addCode(");\n");
			}
		}

		// log for where parames
		SqlBuilderHelper.generateLog(method, methodBuilder);

		// log
		methodBuilder.addCode("\n");
		methodBuilder.addStatement("database().execSQL($S, _contentValues.whereArgsAsArray())", sql);
	}
678309
@Override
    public void postConstruct(Object instance, Object creationMetaData) throws InjectionProviderException
    {
        // TODO the servlet spec is not clear about searching in superclass??
        Class clazz = instance.getClass();
        Method[] methods = getDeclaredMethods(clazz);
        if (methods == null)
        {
            methods = clazz.getDeclaredMethods();
            Map<Class,Method[]> declaredMethodBeansMap = getDeclaredMethodBeansMap();
            synchronized(declaredMethodBeansMap)
            {
                declaredMethodBeansMap.put(clazz, methods);
            }
        }
        Method postConstruct = null;
        for (int i = 0; i < methods.length; i++)
        {
            Method method = methods[i];
            if (method.isAnnotationPresent(PostConstruct.class))
            {
                // a method that does not take any arguments
                // the method must not be static
                // must not throw any checked expections
                // the return value must be void
                // the method may be public, protected, package private or private

                if ((postConstruct != null)
                        || (method.getParameterTypes().length != 0)
                        || (Modifier.isStatic(method.getModifiers()))
                        || (method.getExceptionTypes().length > 0)
                        || (!method.getReturnType().getName().equals("void")))
                {
                    throw new IllegalArgumentException("Invalid PostConstruct annotation");
                }
                postConstruct = method;
            }
        }
        try
        {
            invokeAnnotatedMethod(postConstruct, instance);
        }
        catch (IllegalAccessException ex)
        {
            throw new InjectionProviderException(ex);
        }
        catch (InvocationTargetException ex)
        {
            throw new InjectionProviderException(ex);
        }
    }
1082513
private void generateInsert(SQLiteDatabaseSchema schema) {
		// method sign
		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder("insert").addModifiers(Modifier.PUBLIC).addAnnotation(Override.class).returns(Uri.class);
		methodBuilder.addParameter(Uri.class, "uri");
		methodBuilder.addParameter(ContentValues.class, "contentValues");

		boolean hasOperation = hasOperationOfType(schema, methodBuilder, JQLType.INSERT);

		if (!hasOperation) {
			methodBuilder.addStatement("throw new $T(\"Unknown URI for $L operation: \" + uri)", IllegalArgumentException.class, JQLType.DELETE);
			classBuilder.addMethod(methodBuilder.build());
			return;
		}

		defineJavadocHeaderForContentOperation(methodBuilder, "insert");

		// method code
		methodBuilder.addStatement("long _id=-1");
		methodBuilder.addStatement("$T _returnURL=null", Uri.class);
		methodBuilder.beginControlFlow("switch (sURIMatcher.match(uri))");
		for (Entry<String, ContentEntry> item : uriSet.entrySet()) {
			if (item.getValue().insert == null)
				continue;

			defineJavadocForContentUri(methodBuilder, item.getValue().insert);

			methodBuilder.beginControlFlow("case $L:", item.getValue().pathIndex);
			methodBuilder.addStatement("_id=dataSource.get$L().$L(uri, contentValues)", item.getValue().insert.getParent().getName(), item.getValue().insert.contentProviderMethodName);
			methodBuilder.addStatement("_returnURL=Uri.withAppendedPath(uri, String.valueOf(_id))");

			methodBuilder.addStatement("break");
			methodBuilder.endControlFlow();
		}

		defineJavadocFooterForContentOperation(methodBuilder);

		methodBuilder.beginControlFlow("default:");
		methodBuilder.addStatement("throw new $T(\"Unknown URI for $L operation: \" + uri)", IllegalArgumentException.class, JQLType.INSERT);
		methodBuilder.endControlFlow();

		methodBuilder.endControlFlow();

		if (hasOperation) {

			if (schema.generateLog) {
				// generate log section - BEGIN
				methodBuilder.addComment("log section for content provider insert BEGIN");
				methodBuilder.beginControlFlow("if (dataSource.isLogEnabled())");

				methodBuilder.addStatement("$T.info(\"Element is created with URI '%s'\", _returnURL)", Logger.class);
				methodBuilder.addStatement("$T.info(\"Changes are notified for URI '%s'\", uri)", Logger.class);

				// generate log section - END
				methodBuilder.endControlFlow();
				methodBuilder.addComment("log section for content provider insert END");
			}
			methodBuilder.addStatement("getContext().getContentResolver().notifyChange(uri, null)");
			methodBuilder.addStatement("return _returnURL");
		}

		classBuilder.addMethod(methodBuilder.build());

	}
1104376
@Override
    public <T> Query<T> createSqlQueryMappingColumns(Class<T> entityType,
                                                     String sql,
                                                     Map<String, String> columnMapping) {
        Assert.notNull(entityType, "entityType must not null");
        Assert.hasText(sql, "sql must has text");
        Assert.notEmpty(columnMapping, "columnMapping must not empty");
        RawSqlBuilder rawSqlBuilder = RawSqlBuilder.parse(sql);
        columnMapping.entrySet().forEach(entry -> {
            rawSqlBuilder.columnMapping(entry.getKey(), entry.getValue());
        });
        return ebeanServer.find(entityType).setRawSql(rawSqlBuilder.create());
    }
995174
public void buildReturnCode(MethodSpec.Builder methodBuilder, boolean updateMode, SQLiteModelMethod method, TypeName returnType) {
		if (returnType == TypeName.VOID) {

		} else if (isTypeIncludedIn(returnType, Boolean.TYPE, Boolean.class)) {
			methodBuilder.addJavadoc("\n");
			if (updateMode)
				methodBuilder.addJavadoc("@return <code>true</code> if record is updated, <code>false</code> otherwise");
			else
				methodBuilder.addJavadoc("@return <code>true</code> if record is deleted, <code>false</code> otherwise");
			methodBuilder.addJavadoc("\n");

			methodBuilder.addCode("return result!=0;\n");
		} else if (isTypeIncludedIn(returnType, Long.TYPE, Long.class, Integer.TYPE, Integer.class, Short.TYPE, Short.class)) {
			methodBuilder.addJavadoc("\n");
			if (updateMode) {
				methodBuilder.addJavadoc("@return number of updated records");
			} else {
				methodBuilder.addJavadoc("@return number of deleted records");
			}
			methodBuilder.addJavadoc("\n");

			methodBuilder.addCode("return result;\n");
		} else {
			// more than one listener found
			throw (new InvalidMethodSignException(method, "invalid return type"));
		}
	}
529144
public static void generateLog(final SQLiteModelMethod method, MethodSpec.Builder methodBuilder) {
		SQLiteDaoDefinition daoDefinition = method.getParent();

		// log is enabled
		if (daoDefinition.isLogEnabled()) {
			// generate log section - BEGIN
			methodBuilder.addComment("log section BEGIN");
			methodBuilder.beginControlFlow("if (_context.isLogEnabled())");

			methodBuilder.addCode("// log for insert -- BEGIN \n");

			JQLChecker checker = JQLChecker.getInstance();
			final One<Boolean> inWhere = new One<Boolean>(false);

			String sql = checker.replace(method, method.jql, new JQLReplacerListenerImpl(method) {

				@Override
				public String onBindParameter(String bindParameterName, boolean inStatement) {
					if (inWhere.value0) {
						return "?";
					}

					return null;
				}

				@Override
				public void onWhereStatementBegin(Where_stmtContext ctx) {
					super.onWhereStatementBegin(ctx);

					inWhere.value0 = true;
				}

				@Override
				public void onWhereStatementEnd(Where_stmtContext ctx) {
					super.onWhereStatementEnd(ctx);

					inWhere.value0 = false;
				}
			});

			if (method.jql.containsSelectOperation) {
				// log
				// manage log
				methodBuilder.addCode("\n");
				methodBuilder.addStatement("$T.info($S)", Logger.class, sql);
			} else {
				sql = checker.replaceVariableStatements(method, sql, new JQLReplaceVariableStatementListenerImpl() {

					@Override
					public String onColumnNameSet(String statement) {
						return "%s";
					}

					@Override
					public String onColumnValueSet(String statement) {
						return "%s";
					}
				});

				methodBuilder.addStatement("$T _columnNameBuffer=new $T()", StringBuffer.class, StringBuffer.class);
				methodBuilder.addStatement("$T _columnValueBuffer=new $T()", StringBuffer.class, StringBuffer.class);
				methodBuilder.addStatement("String _columnSeparator=$S", "");

				SqlBuilderHelper.forEachColumnInContentValue(methodBuilder, method, "_contentValues.keys()", false, new OnColumnListener() {

					@Override
					public void onColumnCheck(MethodSpec.Builder methodBuilder, String columNameVariable) {
						methodBuilder.addStatement("_columnNameBuffer.append(_columnSeparator+$L)", columNameVariable);
						methodBuilder.addStatement("_columnValueBuffer.append(_columnSeparator+$S+$L)", ":", columNameVariable);
						methodBuilder.addStatement("_columnSeparator=$S", ", ");

					}
				});

				methodBuilder.addStatement("$T.info($S, _columnNameBuffer.toString(), _columnValueBuffer.toString())", Logger.class, sql);
			}
			generateLogForContentValues(method, methodBuilder);

			methodBuilder.addCode("// log for insert -- END \n\n");
			SqlBuilderHelper.generateLogForWhereParameters(method, methodBuilder);

			// generate log section - END
			methodBuilder.endControlFlow();
			methodBuilder.addComment("log section END");
		}
	}
880785
@InterfaceStability.Committed
    public AsyncMutateInBuilder insertDocument(boolean insertDocument) {
        if (this.upsertDocument && insertDocument) {
            throw new IllegalArgumentException("Cannot set both upsertDocument and insertDocument to true");
        }
        this.insertDocument = insertDocument;
        return this;
    }
337976
public static InsertType detectInsertType(SQLiteModelMethod method) {
		SQLiteDaoDefinition daoDefinition = method.getParent();
		SQLiteEntity entity = method.getEntity();
		TypeName beanTypeName = typeName(entity.getElement());

		InsertType insertResultType = null;

		// check type of arguments
		int beanCounter = 0;
		int beanCollectionCounter = 0;
		for (Pair<String, TypeName> param : method.getParameters()) {
			if (TypeUtility.isEquals(param.value1, beanTypeName)) {
				beanCounter++;
			} else if (TypeUtility.isCollectionOfType(param.value1, beanTypeName)) {
				beanCollectionCounter++;
			}
		}

		AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() == 0, method,
				" INSERT operations require at least one parameter");

		if (beanCounter == 0 && beanCollectionCounter == 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 (beanCounter == 1) {
			insertResultType = InsertType.INSERT_BEAN;

			AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() > 1, method,
					" aspected only one parameter of %s type", daoDefinition.getEntityClassName());
		} else if (beanCollectionCounter == 1) {
			insertResultType = InsertType.INSERT_LIST_BEAN;
			AssertKripton.failWithInvalidMethodSignException(method.getParameters().size() > 1, method,
					" aspected only one collection of %s type as parameter", daoDefinition.getEntityClassName());

			AssertKripton.assertTrueOrInvalidMethodSignException(
					TypeUtility.isCollectionOfType(method.getReturnClass(), beanTypeName)
							|| TypeUtility.isEquals(method.getReturnClass(), typeName(Void.TYPE)),
					method, " invalid return type for multiple insert method",
					daoDefinition.getEntityClassName());
		} else {
			throw (new InvalidMethodSignException(method,
					"only one parameter of type " + typeName(entity.getElement()) + " can be used"));
		}

		return insertResultType;
	}
1331629
public AnnotatedTypeBuilder<X> addToMethod(AnnotatedMethod<? super X> method, Annotation annotation) {
       return addToMethod(method.getJavaMember(), annotation);
   }
390726
private static void generateSelectForContentProvider(Builder builder, final SQLiteModelMethod method, SelectType selectResultType) {
		final SQLiteDaoDefinition daoDefinition = method.getParent();
		final SQLiteEntity entity = method.getEntity();
		final Set<String> columns = new LinkedHashSet<>();

		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.contentProviderMethodName);
		if (!method.getParent().hasSamePackageOfSchema()) {
			methodBuilder.addModifiers(Modifier.PUBLIC);
		}

		// 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) {
				if (item.alias != null) {
					columns.add(entity.get(item.alias.trim()).columnName);
				} else {
					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, false);

		// 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;
			// extract pathVariables
			// 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());
	}
222187
@Override
	public void generateSpecializedPart(SQLiteModelMethod method, TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, Set<JQLProjection> fieldList, boolean mapFields) {
		methodBuilder.addCode("return _cursor;\n");
		// methodBuilder.endControlFlow();
	}
232818
@Override
  public <T> void insert(Collection<? extends T> batchToSave, Class<T> entityClass) {
    insert(batchToSave, Util.determineCollectionName(entityClass));
  }
305415
@Override
	public void generateSpecializedPart(SQLiteModelMethod method, TypeSpec.Builder classBuilder, MethodSpec.Builder methodBuilder, Set<JQLProjection> fieldList, boolean mapFields) {
		//LiteralType listenerType=LiteralType.of(OnReadCursorListener.class);
		ClassName listenerType=ClassName.get(OnReadCursorListener.class);
		
		int counter = SqlBuilderHelper.countParameterOfType(method, listenerType);
		if (counter == 0) {
			// non listener found
			throw (new InvalidMethodSignException(method, "there is no parameter of type \"ReadCursorListener\""));
		}
		if (counter > 1) {
			// more than one listener found
			throw (new InvalidMethodSignException(method, "there are more than one parameter of type \"ReadCursorListener\""));
		}

		String listenerName = SqlSelectBuilder.getNameParameterOfType(method, listenerType);

		methodBuilder.addCode("\n");
		methodBuilder.beginControlFlow("if (_cursor.moveToFirst())");

		// generate index from columns
		methodBuilder.addCode("\n");

		methodBuilder.beginControlFlow("do\n");
		methodBuilder.addCode("$L.onRead(_cursor);\n", listenerName);
		methodBuilder.endControlFlow("while (_cursor.moveToNext())");

		// close cursor
		methodBuilder.endControlFlow();
		methodBuilder.endControlFlow();

	}
613653
@Override
	public void generate(TypeSpec.Builder classBuilder, boolean mapFields, SQLiteModelMethod method) {
		Set<JQLProjection> fieldList = JQLChecker.getInstance().extractProjections(method, method.jql.value, method.getEntity());

		// generate method code
		MethodSpec.Builder methodBuilder = generateMethodBuilder(method);

		generateCommonPart(method, classBuilder, methodBuilder, fieldList, true);
		methodBuilder.addComment("Specialized part - $L - BEGIN", this.getClass().getSimpleName());
		generateSpecializedPart(method, classBuilder, methodBuilder, fieldList, selectType.isMapFields());
		methodBuilder.addComment("Specialized part - $L - END", this.getClass().getSimpleName());

		if (!method.isPagedLiveData()) {
			// method ForLiveData do not have to be generated for paged live
			// data
			classBuilder.addMethod(methodBuilder.build());
		}

	}
1052400
@SuppressWarnings("unchecked")
	@Override
	public <E> int batchInsert(final Class<E> entityType, final Stream<E> entities,
			final InsertsCondition<? super E> condition) {
		@SuppressWarnings("rawtypes")
		EntityHandler handler = this.getEntityHandler();
		if (!handler.getEntityType().isAssignableFrom(entityType)) {
			throw new IllegalArgumentException("Entity type not supported");
		}

		try {
			TableMetadata metadata = handler.getMetadata(this.transactionManager, entityType);
			SqlContext context = handler.createBatchInsertContext(this, metadata, entityType);
			context.setSqlKind(SqlKind.BATCH_INSERT);

			// IDアノテーションが付与されたカラム情報を取得する
			MappingColumn[] idColumns = MappingUtils.getIdMappingColumns(entityType);

			setGeneratedKeyColumns(context, idColumns, metadata);

			int count = 0;
			List<E> entityList = new ArrayList<>();
			for (Iterator<E> iterator = entities.iterator(); iterator.hasNext();) {
				E entity = iterator.next();

				if (!entityType.isInstance(entity)) {
					throw new IllegalArgumentException("Entity types do not match");
				}

				entityList.add(entity);

				handler.setInsertParams(context, entity);
				context.addBatch();

				if (condition.test(context, context.batchCount(), entity)) {
					count += Arrays.stream(doBatchInsert(context, handler, entityList, idColumns)).sum();
					entityList.clear();
				}
			}
			return count + (context.batchCount() != 0
					? Arrays.stream(doBatchInsert(context, handler, entityList, idColumns)).sum()
					: 0);
		} catch (SQLException e) {
			throw new EntitySqlRuntimeException(SqlKind.BATCH_INSERT, e);
		}
	}
510160
@Override
	public void generateLiveData(TypeSpec.Builder classBuilder, SQLiteModelMethod method) {
		SQLiteDaoDefinition daoDefinition = method.getParent();
		Set<JQLProjection> fieldList = JQLChecker.getInstance().extractProjections(method, method.jql.value, method.getEntity());

		// generate method code
		MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(method.getName().replaceAll(LIVE_DATA_PREFIX, "")).addAnnotation(Override.class).addModifiers(Modifier.PUBLIC);

		methodBuilder.addJavadoc("<h2>Live data</h2>\n");
		methodBuilder.addJavadoc("<p>This method open a connection internally.</p>\n\n");

		generateCommonPart(method, classBuilder, methodBuilder, fieldList, GenerationType.NO_CONTENT, method.liveDataReturnClass, true, false);

		boolean pagedLiveData = method.isPagedLiveData();

		if (pagedLiveData) {
			SelectType.PAGED_RESULT.generate(classBuilder, method);

			String pageResultName = SelectPaginatedResultHelper.getCurrentPagedResultClass();
			SelectPaginatedResultHelper.createPagedResult(method, pageResultName, methodBuilder);
		}

		ClassName dataSourceClazz = BindDataSourceBuilder.generateDataSourceName(daoDefinition.getParent());
		ClassName daoFactoryClazz = TypeUtility.className(BindDaoFactoryBuilder.generateDaoFactoryName(daoDefinition.getParent()));
		ClassName batchClazz = TypeUtility.mergeTypeNameWithSuffix(dataSourceClazz, ".Batch");

		List<Pair<String, TypeName>> methodParameters = method.getParameters();
		StringBuilder buffer = new StringBuilder();
		String separator = "";

		for (Pair<String, TypeName> item : methodParameters) {
			buffer.append(separator + item.value0);
			separator = ", ";
		}

		ClassName handlerClass = KriptonLiveDataManager.getInstance().getLiveDataHandlerClazz();
		if (pagedLiveData) {
			handlerClass = KriptonLiveDataManager.getInstance().getPagedLiveDataHandlerClazz();

			TypeSpec batchBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(ParameterizedTypeName.get(batchClazz, method.getReturnClass()))
					.addMethod(
							MethodSpec.methodBuilder("onExecute").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC).addParameter(ParameterSpec.builder(daoFactoryClazz, "daoFactory").build())
									.returns(method.getReturnClass()).addStatement("return paginatedResult.execute(daoFactory)").build())
					.build();

			// return
			TypeSpec.Builder liveDataBuilderBuilder = TypeSpec.anonymousClassBuilder("paginatedResult")
					.addSuperinterface(ParameterizedTypeName.get(handlerClass, method.getReturnClass())).addMethod(MethodSpec.methodBuilder("compute").addAnnotation(Override.class)
							.addModifiers(Modifier.PROTECTED).returns(method.getReturnClass()).addStatement("return $T.getInstance().executeBatch($L)", dataSourceClazz, batchBuilder).build());
			TypeSpec liveDataBuilder = liveDataBuilderBuilder.build();

			methodBuilder.addStatement("final $T builder=$L", ParameterizedTypeName.get(handlerClass, method.getReturnClass()), liveDataBuilder);
		} else {
			TypeSpec batchBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(ParameterizedTypeName.get(batchClazz, method.getReturnClass()))
					.addMethod(MethodSpec.methodBuilder("onExecute").addAnnotation(Override.class).addModifiers(Modifier.PUBLIC)
							.addParameter(ParameterSpec.builder(daoFactoryClazz, "daoFactory").build()).returns(method.getReturnClass())
							.addStatement("return daoFactory.get$L().$L($L)", daoDefinition.getName(), method.getName() + LIVE_DATA_PREFIX, buffer.toString()).build())
					.build();

			TypeSpec.Builder liveDataBuilderBuilder = TypeSpec.anonymousClassBuilder("").addSuperinterface(ParameterizedTypeName.get(handlerClass, method.getReturnClass()))
					.addMethod(MethodSpec.methodBuilder("compute").addAnnotation(Override.class).addModifiers(Modifier.PROTECTED).returns(method.getReturnClass())
							.addStatement("return $T.getInstance().executeBatch($L)", dataSourceClazz, batchBuilder).build());
			TypeSpec liveDataBuilder = liveDataBuilderBuilder.build();

			methodBuilder.addStatement("final $T builder=$L", ParameterizedTypeName.get(handlerClass, method.getReturnClass()), liveDataBuilder);
		}

		methodBuilder.addStatement("registryLiveData(builder)");
		methodBuilder.addStatement("return builder.getLiveData()");

		classBuilder.addMethod(methodBuilder.build());
	}