/*
 * Copyright 2015, Yahoo Inc.
 * Copyrights licensed under the Apache 2.0 License.
 * See the accompanying LICENSE file for terms.
 */
package com.yahoo.squidb.sql;

import com.yahoo.squidb.utility.VersionCode;

/**
 * A statement that operates on a {@link SqlTable}
 */
public abstract class TableStatement extends CompilableWithArguments implements SqlStatement {

    /**
     * Algorithms used by SQLite when a constraint violation occurs during an insert or update operation
     *
     * @see <a href="http://www.sqlite.org/lang_conflict.html">http://www.sqlite.org/lang_conflict.html</a>
     */
    public enum ConflictAlgorithm {
        /**
         * No conflict algorithm specified.
         */
        NONE,
        /**
         * Aborts the command and reverts any changes made within the same transaction up to this point.
         */
        ROLLBACK,
        /**
         * Aborts the command and reverts any changes made by this command up to this point. Changes made by other
         * commands in the same transaction as this command and which have already completed are preserved.
         */
        ABORT,
        /**
         * Aborts the command, but any changes to the database that the command made prior to encountering the
         * constraint violation are preserved.
         */
        FAIL,
        /**
         * When a constraint violation occurs, the one row that contains the constraint violation is not inserted or
         * changed. Other rows before and after the row that contained the constraint violation continue to be inserted
         * or updated normally.
         */
        IGNORE,
        /**
         * When a UNIQUE constraint violation occurs, the pre-existing row that caused the constraint violation is
         * removed prior to inserting or updating the current row.
         */
        REPLACE
    }

    private CompiledArgumentResolver compiledArgumentResolver = null;

    @Override
    @Deprecated
    public final synchronized CompiledStatement compile(VersionCode sqliteVersion) {
        return compile(CompileContext.defaultContextForVersionCode(sqliteVersion));
    }

    @Override
    public final synchronized CompiledStatement compile(CompileContext compileContext) {
        if (compiledArgumentResolver == null) {
            SqlBuilder builder = buildSql(compileContext, true, false);
            compiledArgumentResolver = new CompiledArgumentResolver(builder);
        }
        return compiledArgumentResolver.resolveToCompiledStatement();
    }

    /**
     * Deprecated, use {@link #sqlForValidation(CompileContext)} instead
     */
    @Deprecated
    public final String sqlForValidation(VersionCode sqliteVersion) {
        return sqlForValidation(CompileContext.defaultContextForVersionCode(sqliteVersion));
    }

    public final String sqlForValidation(CompileContext compileContext) {
        SqlBuilder builder = buildSql(compileContext, true, true);
        return new CompiledArgumentResolver(builder).resolveToCompiledStatement().sql;
    }

    public abstract SqlTable<?> getTable();

    /**
     * Invalidate the compile cache for this statement
     */
    protected final synchronized void invalidateCompileCache() {
        compiledArgumentResolver = null;
    }
}

@@ -1930,16 +1930,146 @@
 = null;%0A
+    private CompileContext compileContext = null;%0A%0A    /**%0A     * Deprecated, use %7B@link #compile(CompileContext)%7D instead%0A     */
 %0A    @Ov
@@ -2362,32 +2362,138 @@
 mpileContext) %7B%0A
+        CompileContext contextToUse = this.compileContext != null ? this.compileContext : compileContext;%0A
         if (comp
@@ -2564,36 +2564,34 @@
  buildSql(co
-mpileCo
 ntext
+ToUse
 , true, fals
@@ -3261,32 +3261,382 @@
 t().sql;%0A    %7D%0A%0A
+    /**%0A     * Sets the %7B@link CompileContext%7D to be used when compiling this statement. If set, this value supersedes that%0A     * provided by the %7B@link #compile(CompileContext)%7D method.%0A     */%0A    public void setCompileContext(CompileContext compileContext) %7B%0A        this.compileContext = compileContext;%0A        invalidateCompileCache();%0A    %7D%0A%0A
     public abstr

Add the ability to supply a CompileContext at the TableStatement level