package com.getbase.android.db.fluentsqlite;
import static android.os.Build.VERSION_CODES.HONEYCOMB;
import static com.google.common.base.Preconditions.checkNotNull;
import com.getbase.android.db.fluentsqlite.Expressions.Expression;
import com.getbase.android.db.provider.Utils;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Collections2;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import android.annotation.TargetApi;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
public class Update implements UpdateTableSelector {
private String mTable;
private List<String> mSelections = Lists.newArrayList();
private List<Object> mSelectionArgs = Lists.newArrayList();
private ContentValues mValues = new ContentValues();
private LinkedListMultimap<String, Object> mCustomExpressionsArgs = LinkedListMultimap.create();
private LinkedHashMap<String, String> mCustomExpressions = Maps.newLinkedHashMap();
private Update() {
}
public static UpdateTableSelector update() {
return new Update();
}
public int perform(SQLiteDatabase db) {
String mSelection = Joiner.on(" AND ").join(mSelections);
if (mCustomExpressions.isEmpty()) {
return db.update(mTable, mValues, mSelection, FluentIterable.from(mSelectionArgs).transform(Functions.toStringFunction()).toArray(String.class));
} else {
return performUpdateWithCustomExpressions(db, mSelection);
}
}
@SuppressWarnings("NewApi")
private int performUpdateWithCustomExpressions(SQLiteDatabase db, String selection) {
List<Object> args = Lists.newArrayList();
StringBuilder builder = new StringBuilder();
builder
.append("UPDATE ")
.append(mTable)
.append(" SET ")
.append(Joiner.on(", ").join(Collections2.transform(mCustomExpressions.entrySet(), new Function<Entry<String, String>, String>() {
@Override
public String apply(Entry<String, String> entry) {
return entry.getKey() + "=" + entry.getValue();
}
})));
if (mValues.size() != 0) {
builder.append(", ");
}
Set<Entry<String, Object>> values = mValues.valueSet();
builder.append(Joiner.on(", ").join(Collections2.transform(values, new Function<Entry<String, Object>, Object>() {
@Override
public Object apply(Entry<String, Object> value) {
return value.getKey() + "=?";
}
})));
args.addAll(Collections2.transform(values, new Function<Entry<String, Object>, Object>() {
@Override
public Object apply(Entry<String, Object> value) {
return value.getValue();
}
}));
args.addAll(mSelectionArgs);
if (!Strings.isNullOrEmpty(selection)) {
builder
.append(" WHERE ")
.append(selection);
}
SQLiteStatement statement = db.compileStatement(builder.toString());
try {
int argIndex = 1;
for (String customColumn : mCustomExpressions.keySet()) {
for (Object arg : mCustomExpressionsArgs.get(customColumn)) {
Utils.bindContentValueArg(statement, argIndex++, arg);
}
}
for (Object arg : args) {
Utils.bindContentValueArg(statement, argIndex++, arg);
}
return statement.executeUpdateDelete();
} finally {
statement.close();
}
}
@Override
public Update table(String table) {
mTable = checkNotNull(table);
return this;
}
public Update values(ContentValues values) {
for (Entry<String, Object> value : values.valueSet()) {
mCustomExpressions.remove(value.getKey());
}
mValues.putAll(values);
return this;
}
public Update value(String column, Object value) {
mCustomExpressions.remove(column);
mCustomExpressionsArgs.removeAll(column);
Utils.addToContentValues(column, value, mValues);
return this;
}
@TargetApi(HONEYCOMB)
public Update setColumn(String column, String expression) {
mValues.remove(column);
mCustomExpressionsArgs.removeAll(column);
mCustomExpressions.put(column, "(" + expression + ")");
return this;
}
@TargetApi(HONEYCOMB)
public Update setColumn(String column, Expression expression) {
setColumn(column, expression.getSql());
mCustomExpressionsArgs.putAll(column, Arrays.asList(expression.getMergedArgs()));
return this;
}
@SafeVarargs
public final <T> Update where(String selection, T... selectionArgs) {
if (selection != null) {
mSelections.add("(" + selection + ")");
if (selectionArgs != null) {
Collections.addAll(mSelectionArgs, selectionArgs);
}
} else {
Preconditions.checkArgument(selectionArgs == null || selectionArgs.length == 0, "Cannot use not null arguments with null selection");
}
return this;
}
@SafeVarargs
public final <T> Update where(Expression expression, T... selectionArgs) {
return where(expression.getSql(), expression.getMergedArgs(selectionArgs));
}
}