github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/table_editor_test.go (about)

     1  // Copyright 2019 Dolthub, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package sqle
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/dolthub/go-mysql-server/sql"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/stretchr/testify/require"
    24  
    25  	"github.com/dolthub/dolt/go/libraries/doltcore/dtestutils"
    26  	"github.com/dolthub/dolt/go/libraries/doltcore/row"
    27  	"github.com/dolthub/dolt/go/libraries/doltcore/schema"
    28  	. "github.com/dolthub/dolt/go/libraries/doltcore/sql/sqltestutil"
    29  	"github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil"
    30  )
    31  
    32  type tableEditorTest struct {
    33  	// The name of this test. Names should be unique and descriptive.
    34  	name string
    35  	// Test setup to run
    36  	setup func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor)
    37  	// The select query to run to verify the results
    38  	selectQuery string
    39  	// The rows this query should return, nil if an error is expected
    40  	expectedRows []sql.Row
    41  	// Expected error string, if any
    42  	expectedErr string
    43  }
    44  
    45  func TestTableEditor(t *testing.T) {
    46  	edna := NewPeopleRow(10, "Edna", "Krabapple", false, 38, 8.0)
    47  	krusty := NewPeopleRow(11, "Krusty", "Klown", false, 48, 9.5)
    48  	smithers := NewPeopleRow(12, "Waylon", "Smithers", false, 44, 7.1)
    49  	ralph := NewPeopleRow(13, "Ralph", "Wiggum", false, 9, 9.1)
    50  	martin := NewPeopleRow(14, "Martin", "Prince", false, 11, 6.3)
    51  	skinner := NewPeopleRow(15, "Seymore", "Skinner", false, 50, 8.3)
    52  	fatTony := NewPeopleRow(16, "Fat", "Tony", false, 53, 5.0)
    53  	troyMclure := NewPeopleRow(17, "Troy", "McClure", false, 58, 7.0)
    54  
    55  	var expectedErr error
    56  	// Some of these are pretty exotic use cases, but since we support all these operations it's nice to know they work
    57  	// in tandem.
    58  	testCases := []tableEditorTest{
    59  		{
    60  			name: "all inserts",
    61  			setup: func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor) {
    62  				require.NoError(t, ed.Insert(ctx, r(edna, PeopleTestSchema)))
    63  				require.NoError(t, ed.Insert(ctx, r(krusty, PeopleTestSchema)))
    64  				require.NoError(t, ed.Insert(ctx, r(smithers, PeopleTestSchema)))
    65  				require.NoError(t, ed.Insert(ctx, r(ralph, PeopleTestSchema)))
    66  				require.NoError(t, ed.Insert(ctx, r(martin, PeopleTestSchema)))
    67  				require.NoError(t, ed.Insert(ctx, r(skinner, PeopleTestSchema)))
    68  				require.NoError(t, ed.Insert(ctx, r(fatTony, PeopleTestSchema)))
    69  				require.NoError(t, ed.Insert(ctx, r(troyMclure, PeopleTestSchema)))
    70  			},
    71  			selectQuery: "select * from people where id >= 10 ORDER BY id",
    72  			expectedRows: ToSqlRows(PeopleTestSchema,
    73  				edna, krusty, smithers, ralph, martin, skinner, fatTony, troyMclure,
    74  			),
    75  		},
    76  		{
    77  			name: "inserts and deletes",
    78  			setup: func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor) {
    79  				require.NoError(t, ed.Insert(ctx, r(edna, PeopleTestSchema)))
    80  				require.NoError(t, ed.Insert(ctx, r(krusty, PeopleTestSchema)))
    81  				require.NoError(t, ed.Delete(ctx, r(edna, PeopleTestSchema)))
    82  			},
    83  			selectQuery: "select * from people where id >= 10 ORDER BY id",
    84  			expectedRows: ToSqlRows(PeopleTestSchema,
    85  				krusty,
    86  			),
    87  		},
    88  		{
    89  			name: "inserts and deletes 2",
    90  			setup: func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor) {
    91  				require.NoError(t, ed.Insert(ctx, r(edna, PeopleTestSchema)))
    92  				require.NoError(t, ed.Insert(ctx, r(krusty, PeopleTestSchema)))
    93  				require.NoError(t, ed.Delete(ctx, r(edna, PeopleTestSchema)))
    94  				require.NoError(t, ed.Insert(ctx, r(fatTony, PeopleTestSchema)))
    95  				require.NoError(t, ed.Delete(ctx, r(Homer, PeopleTestSchema)))
    96  			},
    97  			selectQuery: "select * from people where id >= 10 or id = 0 ORDER BY id",
    98  			expectedRows: ToSqlRows(PeopleTestSchema,
    99  				krusty, fatTony,
   100  			),
   101  		},
   102  		{
   103  			name: "inserts and updates",
   104  			setup: func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor) {
   105  				require.NoError(t, ed.Insert(ctx, r(edna, PeopleTestSchema)))
   106  				require.NoError(t, ed.Insert(ctx, r(krusty, PeopleTestSchema)))
   107  				require.NoError(t, ed.Update(ctx, r(edna, PeopleTestSchema), r(MutateRow(PeopleTestSchema, edna, AgeTag, 1), PeopleTestSchema)))
   108  			},
   109  			selectQuery: "select * from people where id >= 10 ORDER BY id",
   110  			expectedRows: ToSqlRows(PeopleTestSchema,
   111  				MutateRow(PeopleTestSchema, edna, AgeTag, 1),
   112  				krusty,
   113  			),
   114  		},
   115  		{
   116  			name: "inserts updates and deletes",
   117  			setup: func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor) {
   118  				require.NoError(t, ed.Insert(ctx, r(edna, PeopleTestSchema)))
   119  				require.NoError(t, ed.Insert(ctx, r(krusty, PeopleTestSchema)))
   120  				require.NoError(t, ed.Update(ctx, r(edna, PeopleTestSchema), r(MutateRow(PeopleTestSchema, edna, AgeTag, 1), PeopleTestSchema)))
   121  				require.NoError(t, ed.Insert(ctx, r(smithers, PeopleTestSchema)))
   122  				require.NoError(t, ed.Insert(ctx, r(ralph, PeopleTestSchema)))
   123  				require.NoError(t, ed.Update(ctx, r(smithers, PeopleTestSchema), r(MutateRow(PeopleTestSchema, smithers, AgeTag, 1), PeopleTestSchema)))
   124  				require.NoError(t, ed.Delete(ctx, r(smithers, PeopleTestSchema)))
   125  				require.NoError(t, ed.Insert(ctx, r(skinner, PeopleTestSchema)))
   126  				require.NoError(t, ed.Delete(ctx, r(ralph, PeopleTestSchema)))
   127  				require.NoError(t, ed.Insert(ctx, r(ralph, PeopleTestSchema)))
   128  			},
   129  			selectQuery: "select * from people where id >= 10 ORDER BY id",
   130  			expectedRows: ToSqlRows(PeopleTestSchema,
   131  				MutateRow(PeopleTestSchema, edna, AgeTag, 1),
   132  				krusty,
   133  				ralph,
   134  				skinner,
   135  			),
   136  		},
   137  		{
   138  			name: "inserts and updates to primary key",
   139  			setup: func(ctx *sql.Context, t *testing.T, ed *sqlTableEditor) {
   140  				require.NoError(t, ed.Insert(ctx, r(edna, PeopleTestSchema)))
   141  				require.NoError(t, ed.Insert(ctx, r(krusty, PeopleTestSchema)))
   142  				require.NoError(t, ed.Update(ctx, r(edna, PeopleTestSchema), r(MutateRow(PeopleTestSchema, edna, IdTag, 30), PeopleTestSchema)))
   143  			},
   144  			selectQuery: "select * from people where id >= 10 ORDER BY id",
   145  			expectedRows: ToSqlRows(PeopleTestSchema,
   146  				krusty,
   147  				MutateRow(PeopleTestSchema, edna, IdTag, 30),
   148  			),
   149  		},
   150  	}
   151  
   152  	for _, test := range testCases {
   153  		t.Run(test.name, func(t *testing.T) {
   154  			expectedErr = nil
   155  
   156  			dEnv := dtestutils.CreateTestEnv()
   157  			CreateTestDatabase(dEnv, t)
   158  
   159  			ctx := NewTestSQLCtx(context.Background())
   160  			root, _ := dEnv.WorkingRoot(context.Background())
   161  			db := NewDatabase("dolt", dEnv.DbData())
   162  			_ = DSessFromSess(ctx.Session).AddDB(ctx, db, db.DbData())
   163  			ctx.SetCurrentDatabase(db.Name())
   164  			err := db.SetRoot(ctx, root)
   165  			require.NoError(t, err)
   166  			peopleTable, _, err := db.GetTableInsensitive(ctx, "people")
   167  			require.NoError(t, err)
   168  
   169  			dt := peopleTable.(sql.UpdatableTable)
   170  			ed := dt.Updater(ctx).(*sqlTableEditor)
   171  
   172  			test.setup(ctx, t, ed)
   173  			if len(test.expectedErr) > 0 {
   174  				require.Error(t, expectedErr)
   175  				assert.Contains(t, expectedErr.Error(), test.expectedErr)
   176  				return
   177  			} else {
   178  				require.NoError(t, ed.Close(ctx))
   179  			}
   180  
   181  			root, err = db.GetRoot(ctx)
   182  			require.NoError(t, err)
   183  
   184  			actualRows, _, err := executeSelect(context.Background(), dEnv, root, test.selectQuery)
   185  			require.NoError(t, err)
   186  
   187  			assert.Equal(t, test.expectedRows, actualRows)
   188  		})
   189  	}
   190  }
   191  
   192  func r(r row.Row, sch schema.Schema) sql.Row {
   193  	sqlRow, err := sqlutil.DoltRowToSqlRow(r, sch)
   194  	if err != nil {
   195  		panic(err)
   196  	}
   197  	return sqlRow
   198  }