github.com/blend/go-sdk@v1.20220411.3/examples/db/multiple/main.go (about)

     1  /*
     2  
     3  Copyright (c) 2022 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package main
     9  
    10  import (
    11  	"context"
    12  	"fmt"
    13  
    14  	"github.com/blend/go-sdk/db"
    15  	"github.com/blend/go-sdk/db/migration"
    16  	"github.com/blend/go-sdk/logger"
    17  )
    18  
    19  type book struct {
    20  	ID   int    `db:"id,pk,auto"`
    21  	Name string `db:"name"`
    22  }
    23  
    24  type person struct {
    25  	ID   int    `db:"id,pk,auto"`
    26  	Name string `db:"name"`
    27  }
    28  
    29  type ledger struct {
    30  	BookID   int `db:"book_id,pk"`
    31  	PersonID int `db:"person_id,pk"`
    32  }
    33  
    34  func createSchema(log logger.Log, conn *db.Connection) error {
    35  	books := migration.NewStep(
    36  		migration.TableNotExists("book"),
    37  		migration.Statements(
    38  			"CREATE TABLE book (id serial not null primary key, name varchar(255))",
    39  		),
    40  	)
    41  	people := migration.NewStep(
    42  		migration.TableNotExists("person"),
    43  		migration.Statements(
    44  			"CREATE TABLE person(id serial not null primary key, name varchar(255))",
    45  		),
    46  	)
    47  	ledger := migration.NewStep(
    48  		migration.TableNotExists("ledger"),
    49  		migration.Statements(
    50  			`CREATE TABLE ledger(
    51  				book_id int not null references book(id),
    52  				person_id int not null references person(id)
    53  			)`,
    54  			`ALTER TABLE ledger ADD PRIMARY KEY (book_id, person_id)`,
    55  		),
    56  	)
    57  
    58  	suite := migration.New(
    59  		migration.OptGroups(
    60  			migration.NewGroup(
    61  				migration.OptGroupActions(
    62  					books,
    63  					people,
    64  					ledger,
    65  				),
    66  			),
    67  		),
    68  	)
    69  	suite.Log = log
    70  	return suite.Apply(context.TODO(), conn)
    71  }
    72  
    73  func seedData(log logger.Log, conn *db.Connection) error {
    74  	// seed books
    75  	if err := conn.Invoke().CreateMany([]book{
    76  		{Name: "Old Man and the Sea"},
    77  		{Name: "Romeo & Juliet"},
    78  		{Name: "The Prince"},
    79  		{Name: "1984"},
    80  		{Name: "A Brave New World"},
    81  	}); err != nil {
    82  		return err
    83  	}
    84  
    85  	// seed books
    86  	if err := conn.Invoke().CreateMany([]person{
    87  		{Name: "Will"},
    88  		{Name: "example-string"},
    89  		{Name: "Mike"},
    90  		{Name: "Ayman"},
    91  		{Name: "Madhu"},
    92  	}); err != nil {
    93  		return err
    94  	}
    95  
    96  	return conn.Invoke().CreateMany([]ledger{
    97  		{BookID: 1, PersonID: 1},
    98  		{BookID: 2, PersonID: 1},
    99  		{BookID: 3, PersonID: 1},
   100  		{BookID: 1, PersonID: 2},
   101  		{BookID: 4, PersonID: 2},
   102  		{BookID: 1, PersonID: 3},
   103  		{BookID: 5, PersonID: 3},
   104  		{BookID: 1, PersonID: 4},
   105  		{BookID: 2, PersonID: 4},
   106  		{BookID: 3, PersonID: 4},
   107  		{BookID: 4, PersonID: 4},
   108  		{BookID: 5, PersonID: 4},
   109  	})
   110  }
   111  
   112  func dropSchema(log logger.Log, conn *db.Connection) error {
   113  	ledger := migration.NewStep(
   114  		migration.TableExists("ledger"),
   115  		migration.Statements(
   116  			"DROP TABLE ledger",
   117  		),
   118  	)
   119  	people := migration.NewStep(
   120  		migration.TableExists("person"),
   121  		migration.Statements(
   122  			"DROP TABLE person",
   123  		),
   124  	)
   125  	books := migration.NewStep(
   126  		migration.TableExists("book"),
   127  		migration.Statements(
   128  			"DROP TABLE book",
   129  		),
   130  	)
   131  
   132  	suite := migration.New(
   133  		migration.OptGroups(
   134  			migration.NewGroup(
   135  				migration.OptGroupActions(
   136  					ledger,
   137  					people,
   138  					books,
   139  				),
   140  			),
   141  		),
   142  	)
   143  
   144  	suite.Log = log
   145  	return suite.Apply(context.TODO(), conn)
   146  }
   147  
   148  func main() {
   149  	cfg := db.Config{
   150  		Database: "postgres",
   151  		SSLMode:  db.SSLModeDisable,
   152  	}
   153  	conn, err := db.New(db.OptConfig(cfg))
   154  	if err != nil {
   155  		logger.FatalExit(err)
   156  	}
   157  	if err := conn.Open(); err != nil {
   158  		logger.FatalExit(err)
   159  	}
   160  
   161  	log := logger.Prod()
   162  	if err := createSchema(log, conn); err != nil {
   163  		logger.FatalExit(err)
   164  	}
   165  	defer dropSchema(log, conn)
   166  
   167  	if err := seedData(log, conn); err != nil {
   168  		log.Fatal(err)
   169  		return
   170  	}
   171  
   172  	results, err := conn.Query("select * from book; select * from person; select * from ledger").Do()
   173  	if err != nil {
   174  		log.Fatal(err)
   175  		return
   176  	}
   177  
   178  	var b []book
   179  	if err = db.OutMany(results, &b); err != nil {
   180  		log.Fatal(err)
   181  		return
   182  	}
   183  	if !results.NextResultSet() {
   184  		log.Fatalf("no person result set, cannot continue")
   185  		return
   186  	}
   187  
   188  	var p []person
   189  	if err = db.OutMany(results, &p); err != nil {
   190  		log.Fatal(err)
   191  		return
   192  	}
   193  	if !results.NextResultSet() {
   194  		log.Fatalf("no ledger result set, cannot continue")
   195  		return
   196  	}
   197  
   198  	var l []ledger
   199  	if err = db.OutMany(results, &l); err != nil {
   200  		log.Fatal(err)
   201  		return
   202  	}
   203  	for _, book := range b {
   204  		fmt.Printf("%#v\n", book)
   205  	}
   206  	for _, person := range p {
   207  		fmt.Printf("%#v\n", person)
   208  	}
   209  	for _, ledger := range l {
   210  		fmt.Printf("%#v\n", ledger)
   211  	}
   212  }