github.com/dolthub/go-mysql-server@v0.18.0/_example/main.go (about)

     1  // Copyright 2020-2022 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 main
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"time"
    21  
    22  	"github.com/dolthub/vitess/go/mysql"
    23  	"github.com/dolthub/vitess/go/vt/proto/query"
    24  
    25  	sqle "github.com/dolthub/go-mysql-server"
    26  	"github.com/dolthub/go-mysql-server/memory"
    27  	"github.com/dolthub/go-mysql-server/server"
    28  	"github.com/dolthub/go-mysql-server/sql"
    29  	"github.com/dolthub/go-mysql-server/sql/mysql_db"
    30  	"github.com/dolthub/go-mysql-server/sql/types"
    31  )
    32  
    33  // This is an example of how to implement a MySQL server.
    34  // After running the example, you may connect to it using the following:
    35  //
    36  // > mysql --host=localhost --port=3306 --user=root mydb --execute="SELECT * FROM mytable;"
    37  // +----------+-------------------+-------------------------------+----------------------------+
    38  // | name     | email             | phone_numbers                 | created_at                 |
    39  // +----------+-------------------+-------------------------------+----------------------------+
    40  // | Jane Deo | janedeo@gmail.com | ["556-565-566","777-777-777"] | 2022-11-01 12:00:00.000001 |
    41  // | Jane Doe | jane@doe.com      | []                            | 2022-11-01 12:00:00.000001 |
    42  // | John Doe | john@doe.com      | ["555-555-555"]               | 2022-11-01 12:00:00.000001 |
    43  // | John Doe | johnalt@doe.com   | []                            | 2022-11-01 12:00:00.000001 |
    44  // +----------+-------------------+-------------------------------+----------------------------+
    45  //
    46  // The included MySQL client is used in this example, however any MySQL-compatible client will work.
    47  
    48  var (
    49  	dbName    = "mydb"
    50  	tableName = "mytable"
    51  	address   = "localhost"
    52  	port      = 3306
    53  )
    54  
    55  // For go-mysql-server developers: Remember to update the snippet in the README when this file changes.
    56  
    57  func main() {
    58  	pro := createTestDatabase()
    59  	engine := sqle.NewDefault(pro)
    60  
    61  	session := memory.NewSession(sql.NewBaseSession(), pro)
    62  	ctx := sql.NewContext(context.Background(), sql.WithSession(session))
    63  	ctx.SetCurrentDatabase("test")
    64  
    65  	// This variable may be found in the "users_example.go" file. Please refer to that file for a walkthrough on how to
    66  	// set up the "mysql" database to allow user creation and user checking when establishing connections. This is set
    67  	// to false for this example, but feel free to play around with it and see how it works.
    68  	if enableUsers {
    69  		if err := enableUserAccounts(ctx, engine); err != nil {
    70  			panic(err)
    71  		}
    72  	}
    73  
    74  	config := server.Config{
    75  		Protocol: "tcp",
    76  		Address:  fmt.Sprintf("%s:%d", address, port),
    77  	}
    78  	s, err := server.NewServer(config, engine, sessionBuilder(pro), nil)
    79  	if err != nil {
    80  		panic(err)
    81  	}
    82  	if err = s.Start(); err != nil {
    83  		panic(err)
    84  	}
    85  }
    86  
    87  func sessionBuilder(pro *memory.DbProvider) server.SessionBuilder {
    88  	return func(ctx context.Context, conn *mysql.Conn, addr string) (sql.Session, error) {
    89  		host := ""
    90  		user := ""
    91  		mysqlConnectionUser, ok := conn.UserData.(mysql_db.MysqlConnectionUser)
    92  		if ok {
    93  			host = mysqlConnectionUser.Host
    94  			user = mysqlConnectionUser.User
    95  		}
    96  
    97  		client := sql.Client{Address: host, User: user, Capabilities: conn.Capabilities}
    98  		baseSession := sql.NewBaseSessionWithClientServer(addr, client, conn.ConnectionID)
    99  		return memory.NewSession(baseSession, pro), nil
   100  	}
   101  }
   102  
   103  func createTestDatabase() *memory.DbProvider {
   104  	db := memory.NewDatabase("mydb")
   105  	db.BaseDatabase.EnablePrimaryKeyIndexes()
   106  
   107  	pro := memory.NewDBProvider(db)
   108  	session := memory.NewSession(sql.NewBaseSession(), pro)
   109  	ctx := sql.NewContext(context.Background(), sql.WithSession(session))
   110  
   111  	table := memory.NewTable(db, tableName, sql.NewPrimaryKeySchema(sql.Schema{
   112  		{Name: "name", Type: types.Text, Nullable: false, Source: tableName, PrimaryKey: true},
   113  		{Name: "email", Type: types.Text, Nullable: false, Source: tableName, PrimaryKey: true},
   114  		{Name: "phone_numbers", Type: types.JSON, Nullable: false, Source: tableName},
   115  		{Name: "created_at", Type: types.MustCreateDatetimeType(query.Type_DATETIME, 6), Nullable: false, Source: tableName},
   116  	}), db.GetForeignKeyCollection())
   117  	db.AddTable(tableName, table)
   118  
   119  	creationTime := time.Unix(0, 1667304000000001000).UTC()
   120  	_ = table.Insert(ctx, sql.NewRow("Jane Deo", "janedeo@gmail.com", types.MustJSON(`["556-565-566", "777-777-777"]`), creationTime))
   121  	_ = table.Insert(ctx, sql.NewRow("Jane Doe", "jane@doe.com", types.MustJSON(`[]`), creationTime))
   122  	_ = table.Insert(ctx, sql.NewRow("John Doe", "john@doe.com", types.MustJSON(`["555-555-555"]`), creationTime))
   123  	_ = table.Insert(ctx, sql.NewRow("John Doe", "johnalt@doe.com", types.MustJSON(`[]`), creationTime))
   124  
   125  	return pro
   126  }