
/*
 * Copyright (C) 2015 Archie L. Cobbs. All rights reserved.
 */

package org.jsimpledb.kv.spanner;

import com.google.cloud.spanner.SpannerOptions;

import org.jsimpledb.kv.KVDatabase;
import org.jsimpledb.kv.KVTransaction;
import org.jsimpledb.kv.test.KVTestSupport;
import org.jsimpledb.util.ByteUtil;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class DeleteTest extends KVTestSupport {

    private SpannerKVDatabase db;

    @BeforeClass(groups = "configure")
    @Parameters({ "spannerProject", "spannerInstance" })
    public void setSpannerConfig(@Optional String project, @Optional String instance) throws Exception {
        if (instance != null) {
            this.db = new SpannerKVDatabase();
            final SpannerOptions.Builder builder = SpannerOptions.newBuilder();
            if (project != null)
                builder.setProjectId(project);
            this.db.setSpannerOptions(builder.build());
            this.db.setInstanceId(instance);
        }
    }

    @Test
    protected void testDeleteToInfinity() throws Exception {
        if (this.db == null)
            return;
        this.db.start();
        try {

            final byte[] key1 = new byte[] { (byte)0x11 };
            final byte[] val1 = new byte[] { (byte)0xaa };
            final byte[] key2 = new byte[] { (byte)0x22 };
            final byte[] val2 = new byte[] { (byte)0xbb };

            // Populate DB
            KVTransaction tx = this.db.createTransaction();
            try {
                tx.removeRange(new byte[0], null);
                tx.put(key1, val1);
                tx.put(key2, val2);
                tx.commit();
            } finally {
                tx.rollback();
            }

            // Display db
            this.show("initial content");

            // Delete to infinity
            tx = this.db.createTransaction();
            try {
                tx.removeRange(ByteUtil.getNextKey(key1), null);
                tx.commit();
            } finally {
                tx.rollback();
            }

            // Verify second key is gone
            tx = this.db.createTransaction();
            try {
                this.show("after remove");
                Assert.assertNull(tx.get(key2));
                tx.commit();
            } finally {
                tx.rollback();
            }

        } finally {
            this.db.stop();
        }
    }

    private void show(String label) throws Exception {
        this.log.info("Spanner content (" + label + "):");
        KVTransaction tx = this.db.createTransaction();
        try {
            this.show(tx, label);
            tx.commit();
        } finally {
            tx.rollback();
        }
    }

    private void show(KVTransaction tx, String label) throws Exception {
        final Exception e = this.showKV(tx, label);
        if (e != null)
            throw e;
    }
}


@@ -1571,71 +1571,37 @@
     
-KVTransaction tx = this.db.createTransaction();%0A            try
+this.tryNtimes(this.db, tx -%3E
  %7B%0A 
@@ -1738,93 +1738,11 @@
     
-    tx.commit();%0A            %7D finally %7B%0A                tx.rollback();%0A            %7D
+%7D);
 %0A%0A  
@@ -1859,221 +1859,86 @@
    t
-x = this.db.createTransaction();%0A            try %7B%0A                tx.removeRange(ByteUtil.getNextKey(key1), null);%0A                tx.commit();%0A            %7D finally %7B%0A                tx.rollback();%0A            %7D
+his.tryNtimes(this.db, tx -%3E tx.removeRange(ByteUtil.getNextKey(key1), null));
 %0A%0A  
@@ -1993,56 +1993,36 @@
    t
-x = this.db.createTransaction();%0A            try
+his.tryNtimes(this.db, tx -%3E
  %7B%0A 
@@ -2128,93 +2128,11 @@
     
-    tx.commit();%0A            %7D finally %7B%0A                tx.rollback();%0A            %7D
+%7D);
 %0A%0A  
@@ -2234,401 +2234,139 @@
 el) 
-throws Exception %7B%0A        this.log.info(%22Spanner content (%22 + label + %22):%22);%0A        KVTransaction tx = this.db.createTransaction();%0A        try %7B%0A            this.show(tx, label);%0A            tx.commit();%0A        %7D finally %7B%0A            tx.rollback();%0A        %7D%0A    %7D%0A%0A    private void show(KVTransaction tx, String label) throws Exception %7B%0A        final Exception e = this.showKV(tx, label
+%7B%0A        this.tryNtimes(this.db, tx -%3E %7B%0A            final RuntimeException e = this.showKV(tx, %22Spanner content (%22 + label + %22):%22
 );%0A 
@@ -2368,24 +2368,28 @@
 %22);%0A        
+    
 if (e != nul
@@ -2403,16 +2403,20 @@
         
+    
 throw e;
@@ -2416,16 +2416,28 @@
 hrow e;%0A
+        %7D);%0A
     %7D%0A%7D%0A

Update unit test to properly handle retry exceptions.