github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/ddl/ddl-mysql_test.go (about)

     1  package ddl
     2  
     3  import (
     4  	"database/sql"
     5  	"fmt"
     6  	"log"
     7  	"testing"
     8  
     9  	"github.com/ory/dockertest"
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	_ "github.com/go-sql-driver/mysql"
    13  )
    14  
    15  func doMySQLServerSetup() (*sql.DB, *dockertest.Pool, *dockertest.Resource) {
    16  
    17  	// uses a sensible default on windows (tcp/http) and linux/osx (socket)
    18  	pool, err := dockertest.NewPool("")
    19  	if err != nil {
    20  		log.Fatalf("Could not connect to docker: %v", err)
    21  	}
    22  
    23  	// pulls an image, creates a container based on it and runs it
    24  	resource, err := pool.Run("mysql", "5.7", []string{"MYSQL_ROOT_PASSWORD=secret"})
    25  	if err != nil {
    26  		log.Fatalf("Could not start resource: %v", err)
    27  	}
    28  
    29  	var db *sql.DB
    30  
    31  	// exponential backoff-retry, because the application in the container might not be ready to accept connections yet
    32  	if err := pool.Retry(func() error {
    33  		var err error
    34  		db, err = sql.Open("mysql", fmt.Sprintf("root:secret@(localhost:%s)/mysql", resource.GetPort("3306/tcp")))
    35  		if err != nil {
    36  			return err
    37  		}
    38  		return db.Ping()
    39  	}); err != nil {
    40  		log.Fatalf("Could not connect to docker: %v", err)
    41  	}
    42  
    43  	return db, pool, resource
    44  
    45  }
    46  
    47  // TestMysql tests each feature against a mysql database to ensure syntax is correct.
    48  func TestMysql(t *testing.T) {
    49  
    50  	assert := assert.New(t)
    51  
    52  	db, pool, resource := doMySQLServerSetup()
    53  	defer func() {
    54  		if err := pool.Purge(resource); err != nil {
    55  			log.Printf("Could not purge resource: %v", err)
    56  		}
    57  	}()
    58  
    59  	f := NewMySQLFormatter(false)
    60  
    61  	b := New()
    62  	b.SetCategory("test")
    63  
    64  	runSQL := func(up, _ []string, err error) {
    65  		if err != nil {
    66  			assert.NoError(err)
    67  			return
    68  		}
    69  		for _, s := range up {
    70  			t.Logf("Running SQL: %s", s)
    71  			_, err = db.Exec(s)
    72  			assert.NoError(err)
    73  		}
    74  	}
    75  
    76  	// -- create table
    77  
    78  	// one of each type on it (except the integer pk)
    79  	runSQL(b.Reset().
    80  		CreateTable("table_types").
    81  		Column("table_types_id", VarCharPK).PrimaryKey().
    82  		ColumnCustom("test_custom", "TEXT NOT NULL").
    83  		Column("test_varcharfk", VarCharFK).Length(255). // NOTE: lengths are ignored by SQLite, they don't get output
    84  		Column("test_bigintfk", BigIntFK).
    85  		Column("test_int", Int).
    86  		Column("test_intu", IntU).
    87  		Column("test_bigint", BigInt).
    88  		Column("test_bigintu", BigIntU).
    89  		Column("test_double", Double).
    90  		Column("test_datetime", DateTime).
    91  		Column("test_varchar", VarChar).Length(255).
    92  		Column("test_bool", Bool).
    93  		Column("test_text", Text).
    94  		Column("test_blob", Blob).
    95  		MakeSQL(f))
    96  
    97  	// integer autoinc pk
    98  	runSQL(b.Reset().
    99  		CreateTable("table_autoinc").
   100  		Column("table_autoinc_id", BigIntAutoPK).PrimaryKey().
   101  		Column("test_varchar", VarChar).
   102  		MakeSQL(f))
   103  
   104  	// mulitple pks
   105  	runSQL(b.Reset().
   106  		CreateTable("table_join").
   107  		Column("table_join_a_id", VarCharPK).PrimaryKey().
   108  		Column("table_join_b_id", VarCharPK).PrimaryKey().
   109  		MakeSQL(f))
   110  
   111  	// if not exists
   112  	runSQL(b.Reset().
   113  		CreateTable("table_existential").IfNotExists().
   114  		Column("table_existential_id", VarCharPK).PrimaryKey().
   115  		MakeSQL(f))
   116  
   117  	// null
   118  	runSQL(b.Reset().
   119  		CreateTable("table_null").
   120  		Column("table_null_id", VarCharPK).PrimaryKey().
   121  		Column("test_int", Int).Null().
   122  		Column("test_intu", IntU).Null().
   123  		Column("test_bigint", BigInt).Null().
   124  		Column("test_bigintu", BigIntU).Null().
   125  		Column("test_double", Double).Null().
   126  		Column("test_datetime", DateTime).Null().
   127  		Column("test_varchar", VarChar).Length(255).Null().
   128  		Column("test_bool", Bool).Null().
   129  		Column("test_text", Text).Null().
   130  		Column("test_blob", Blob).Null().
   131  		MakeSQL(f))
   132  
   133  	// case sensitive
   134  	runSQL(b.Reset().
   135  		CreateTable("table_cs").
   136  		Column("table_cs_id", VarCharPK).PrimaryKey().
   137  		Column("test_varchar_cs", VarChar).CaseSensitive().
   138  		Column("test_text_cs", Text).CaseSensitive().
   139  		MakeSQL(f))
   140  
   141  	// -- drop table
   142  	runSQL(b.Reset().
   143  		DropTable("table_cs").
   144  		MakeSQL(f))
   145  
   146  	// -- rename table
   147  	runSQL(b.Reset().
   148  		AlterTableRename("table_null", "table_null2").
   149  		MakeSQL(f))
   150  
   151  	// -- add column
   152  	runSQL(b.Reset().
   153  		AlterTableAdd("table_existential").
   154  		Column("other_cool_field", VarChar).Null().Default("mozdef").CaseSensitive().
   155  		MakeSQL(f))
   156  
   157  	// -- create index
   158  	runSQL(b.Reset().
   159  		CreateIndex("table_existential_other", "table_existential").Columns("other_cool_field").
   160  		MakeSQL(f))
   161  
   162  	// -- drop index
   163  	runSQL(b.Reset().
   164  		DropIndex("table_existential_other", "table_existential").
   165  		MakeSQL(f))
   166  
   167  	// -- more create index
   168  
   169  	// unique
   170  	runSQL(b.Reset().
   171  		CreateIndex("table_existential_other", "table_existential").
   172  		Unique().
   173  		Columns("other_cool_field").
   174  		MakeSQL(f))
   175  
   176  	// // if not exists - not supported
   177  	// runSQL(b.Reset().
   178  	// 	CreateIndex("table_existential_other", "table_existential").
   179  	// 	IfNotExists().
   180  	// 	Columns("other_cool_field").
   181  	// 	MakeSQL(f))
   182  
   183  }