You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: db_test.go
    path of file: ./repos/beego/client/orm
    
    the code of the file until where you have to start completion: // Copyright 2020 beego
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package orm

import (
	"errors"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"

	"github.com/beego/beego/v2/client/orm/clauses/order_clause"
	"github.com/beego/beego/v2/client/orm/internal/buffers"

	"github.com/beego/beego/v2/client/orm/internal/models"
)

func TestDbBase_InsertValueSQL(t *testing.T) {

	mi := &models.ModelInfo{
		Table: "test_table",
	}

	testCases := []struct {
		name    string
		db      *dbBase
		isMulti bool
		names   []string
		values  []interface{}

		wantRes string
	}{
		{
			name: "single insert by dbBase",
			db: &dbBase{
				ins: &dbBase{},
			},
			isMulti: false,
			names:   []string{"name", "age"},
			values:  []interface{}{"test", 18},
			wantRes: "INSERT INTO `test_table` (`name`, `age`) VALUES (?, ?)",
		},
		{
			name: "single insert by dbBasePostgres",
			db: &dbBase{
				ins: newdbBasePostgres(),
			},
			isMulti: false,
			names:   []string{"name", "age"},
			values:  []interface{}{"test", 18},
			wantRes: "INSERT INTO \"test_table\" (\"name\", \"age\") VALUES ($1, $2)",
		},
		{
			name: "multi insert by dbBas
    
func TestDbBase_readValuesSQL(t *testing.T) {

	mc := models.NewModelCacheHandler()

	err := mc.Register("", false, new(testTab), new(testTab1), new(testTab2))

	assert.Nil(t, err)

	mc.Bootstrap()

	mi, ok := mc.GetByMd(new(testTab))

	assert.True(t, ok)

	cond := NewCondition().And("name", "test_name").
		OrCond(NewCondition().And("age__gt", 18).And("score__lt", 60))

	tz := time.Local

	testCases := []struct {
		name string
		db   *dbBase

		cols []string
		qs   querySet

		wantRes  string
		wantArgs []interface{}
	}{
		{
			name: "read values with MySQL",
			db: &dbBase{
				ins: newdbBaseMysql(),
			},
			cols: []string{"T0.`name` name", "T0.`age` age", "T0.`score` score"},
			qs: querySet{
				mi:     mi,
				cond:   cond,
				limit:  10,
				offset: 100,
				groups: []string{"name", "age"},
				orders: []*order_clause.Order{
					order_clause.Clause(order_clause.Column("score"),
						order_clause.SortDescending()),
					order_clause.Clause(order_clause.Column("age"),
						order_clause.SortAscending()),
				},
				useIndex: 1,
				indexes:  []string{"name", "score"},
			},
			wantRes:  "SELECT T0.`name` name, T0.`age` age, T0.`score` score FROM `test_tab` T0  USE INDEX(`name`,`score`) WHERE T0.`name` = ? OR ( T0.`age` > ? AND T0.`score` < ? ) GROUP BY T0.`name`, T0.`age` ORDER BY T0.`score` DESC, T0.`age` ASC LIMIT 10 OFFSET 100",
			wantArgs: []interface{}{"test_name", int64(18), int64(60)},
		},
		{
			name: "read values with MySQL and distinct",
			db: &dbBase{
				ins: newdbBaseMysql(),
			},
			cols: []string{"T0.`name` name", "T0.`age` age", "T0.`score` score"},
			qs: querySet{
				mi:     mi,
				cond:   cond,
				limit:  10,
				offset: 100,
				groups: []string{"name", "age"},
				orders: []*order_clause.Order{
					order_clause.Clause(order_clause.Column("score"),
						order_clause.SortDescending()),
					order_clause.Clause(order_clause.Column("age"),
						order_clause.SortAscending()),
				},
				useIndex: 1,
				indexes:  []string{"name", "score"},
				distinct: true,
			},
			wantRes:  "SELECT DISTINCT T0.`name` name, T0.`age` age, T0.`score` score FROM `test_tab` T0  USE INDEX(`name`,`score`) WHERE T0.`name` = ? OR ( T0.`age` > ? AND T0.`score` < ? ) GROUP BY T0.`name`, T0.`age` ORDER BY T0.`score` DESC, T0.`age` ASC LIMIT 10 OFFSET 100",
			wantArgs: []interface{}{"test_name", int64(18), int64(60)},
		},
		{
			name: "read values with PostgreSQL",
			db: &dbBase{
				ins: newdbBasePostgres(),
			},
			cols: []string{`T0."name" name`, `T0."age" age`, `T0."score" score`},
			qs: querySet{
				mi:     mi,
				cond:   cond,
				limit:  10,
				offset: 100,
				groups: []string{"name", "age"},
				orders: []*order_clause.Order{
					order_clause.Clause(order_clause.Column("score"),
						order_clause.SortDescending()),
					order_clause.Clause(order_clause.Column("age"),
						order_clause.SortAscending()),
				},
			},
			wantRes:  `SELECT T0."name" name, T0."age" age, T0."score" score FROM "test_tab" T0 WHERE T0."name" = $1 OR ( T0."age" > $2 AND T0."score" < $3 ) GROUP BY T0."name", T0."age" ORDER BY T0."score" DESC, T0."age" ASC LIMIT 10 OFFSET 100`,
			wantArgs: []interface{}{"test_name", int64(18), int64(60)},
		},
		{
			name: "read values with PostgreSQL and distinct",
			db: &dbBase{
				ins: newdbBasePostgres(),
			},
			cols: []string{`T0."name" name`, `T0."age" age`, `T0."score" score`},
			qs: querySet{
				mi:     mi,
				cond:   cond,
				limit:  10,
				offset: 100,
				groups: []string{"name", "age"},
				orders: []*order_clause.Order{
					order_clause.Clause(order_clause.Column("score"),
						order_clause.SortDescending()),
					order_clause.Clause(order_clause.Column("age"),
						order_clause.SortAscending()),
				},
				distinct: true,
			},
			wantRes:  `SELECT DISTINCT T0."name" name, T0."age" age, T0."score" score FROM "test_tab" T0 WHERE T0."name" = $1 OR ( T0."age" > $2 AND T0."score" < $3 ) GROUP BY T0."name", T0."age" ORDER BY T0."score" DESC, T0."age" ASC LIMIT 10 OFFSET 100`,
			wantArgs: []interface{}{"test_name", int64(18), int64(60)},
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			tables := newDbTables(mi, tc.db.ins)

			res, args := tc.db.readValuesSQL(tables, tc.cols, tc.qs, mi, cond, tz)

			assert.Equal(t, tc.wantRes, res)
			assert.Equal(t, tc.wantArgs, args)
		})
	}

}