package main

import (
	"database/sql"

	"github.com/pingcap/errors"
)

var VarAutoCommit = SysVar{Name: "autocommit", Default: "ON"}

type TestAutoCommit struct {
	BaseTestCase
}

func (t *TestAutoCommit) Run() error {
	err := t.TestBasic("0")
	if err != nil {
		return err
	}
	db1, err := sql.Open("mysql", t.DSN)
	if err != nil {
		return errors.Annotate(err, "open database")
	}
	defer db1.Close()

	err = ExecAll(db1, []Step{
		{"CREATE DATABASE IF NOT EXISTS test_autocommit", "create test database"},
		{"USE test_autocommit", "use test database"},
		{"DROP TABLE IF EXISTS t", "drop test table"},
		{"CREATE TABLE t (c int)", "create test table"},
	})
	if err != nil {
		return err
	}

	db2, err := sql.Open("mysql", t.DSN)
	if err != nil {
		return errors.Annotate(err, "open database")
	}
	defer db2.Close()
	_, err = db2.Exec("USE test_autocommit")
	if err != nil {
		return errors.Annotate(err, "use test database")
	}

	err = t.Var.WithValue(db1, "0", func(db *sql.DB) error {
		_, err := db1.Exec("INSERT INTO t (c) VALUES (1)")
		if err != nil {
			return errors.Trace(err)
		}
		n := 0
		err = db2.QueryRow("SELECT COUNT(*) FROM t").Scan(&n)
		if err != nil {
			return errors.Trace(err)
		}
		if n != 0 {
			return errors.New("uncommitted stmt is visible")
		}
		_, err = db1.Exec("COMMIT")
		if err != nil {
			return errors.Trace(err)
		}
		err = db2.QueryRow("SELECT COUNT(*) FROM t").Scan(&n)
		if err != nil {
			return errors.Trace(err)
		}
		if n != 1 {
			return errors.New("committed stmt is invisible")
		}
		return nil
	})
	if err != nil {
		return err
	}

	return nil
}

func init() {
	RegisterTestCase("autocommit", &TestAutoCommit{BaseTestCase{Var: VarAutoCommit}})
}
