go.charczuk.com@v0.0.0-20240327042549-bc490516bd1a/projects/chirp/pkg/model/migrations.go (about)

     1  /*
     2  
     3  Copyright (c) 2023 - Present. Will Charczuk. All rights reserved.
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file at the root of the repository.
     5  
     6  */
     7  
     8  package model
     9  
    10  import (
    11  	"context"
    12  	"database/sql"
    13  
    14  	"go.charczuk.com/sdk/apputil"
    15  	"go.charczuk.com/sdk/db"
    16  	"go.charczuk.com/sdk/db/dbgen"
    17  	"go.charczuk.com/sdk/db/migration"
    18  	"go.charczuk.com/sdk/uuid"
    19  )
    20  
    21  // Migrations returns the migration suite to bootstrap the database.
    22  func Migrations(opts ...migration.SuiteOption) *migration.Suite {
    23  	return migration.New(
    24  		append(opts,
    25  			migration.OptGroups(
    26  				append(
    27  					apputil.MigrationGroups(), // this includes e.g. `User` and `Session`
    28  					migration.NewGroupWithAction(
    29  						dbgen.TableFrom(UserInfo{},
    30  							dbgen.ForeignKey(UserInfo{}, "user_id", apputil.User{}, "id"),
    31  						),
    32  					),
    33  					migration.NewGroupWithAction(
    34  						dbgen.TableFrom(Chirp{},
    35  							dbgen.ForeignKey(Chirp{}, "user_id", apputil.User{}, "id"),
    36  							dbgen.ForeignKey(Chirp{}, "reply_id", Chirp{}, "id"),
    37  							dbgen.ForeignKey(Chirp{}, "quoted_id", Chirp{}, "id"),
    38  						),
    39  					),
    40  					migration.NewGroupWithAction(
    41  						dbgen.TableFrom(ChirpStats{},
    42  							dbgen.ForeignKey(ChirpStats{}, "chirp_id", Chirp{}, "id"),
    43  							dbgen.ForeignKey(ChirpStats{}, "user_id", apputil.User{}, "id"),
    44  						),
    45  					),
    46  					migration.NewGroupWithAction(
    47  						dbgen.TableFrom(ChirpLike{},
    48  							dbgen.ForeignKey(ChirpLike{}, "chirp_id", Chirp{}, "id"),
    49  							dbgen.ForeignKey(ChirpLike{}, "user_id", apputil.User{}, "id"),
    50  						),
    51  					),
    52  					migration.NewGroupWithAction(
    53  						dbgen.TableFrom(Graph{},
    54  							dbgen.ForeignKey(Graph{}, "user_id", apputil.User{}, "id"),
    55  							dbgen.ForeignKey(Graph{}, "target_id", apputil.User{}, "id"),
    56  						),
    57  					),
    58  					migration.NewGroupWithAction(
    59  						dbgen.TableFrom(Feed{},
    60  							dbgen.ForeignKey(Feed{}, "user_id", apputil.User{}, "id"),
    61  							dbgen.ForeignKey(Feed{}, "chirp_id", Chirp{}, "id"),
    62  						),
    63  					),
    64  					migration.NewGroupWithAction(
    65  						dbgen.TableFrom(Notification{},
    66  							dbgen.ForeignKey(Notification{}, "user_id", apputil.User{}, "id"),
    67  							dbgen.ForeignKey(Notification{}, "acting_user_id", apputil.User{}, "id"),
    68  							dbgen.ForeignKey(Notification{}, "chirp_id", Chirp{}, "id"),
    69  						),
    70  					),
    71  					migration.NewGroupWithAction(
    72  						dbgen.TableFrom(Audit{},
    73  							dbgen.ForeignKey(Audit{}, "user_id", apputil.User{}, "id"),
    74  						),
    75  					),
    76  					migration.NewGroupWithStep(
    77  						migration.IfNotExists(`select 1 from users where email = $1`, "will.charczuk@gmail.com"),
    78  						migration.ActionFunc(func(ctx context.Context, conn *db.Connection, tx *sql.Tx) error {
    79  							user := &apputil.User{
    80  								ID:         uuid.MustParse("476a78aa-8c46-45f6-aca4-dd52384d60bd"),
    81  								GivenName:  "Will",
    82  								FamilyName: "Charczuk",
    83  								Email:      "will.charczuk@gmail.com",
    84  								PictureURL: "https://lh3.googleusercontent.com/a/AAcHTte1Yp7G57Gs5c_BGXZGXVQVuXQBvvq-Uvyo573Awi9S5Q=s96-c",
    85  								Locale:     "en",
    86  							}
    87  							if err := conn.Invoke(db.OptContext(ctx), db.OptTx(tx)).Create(user); err != nil {
    88  								return err
    89  							}
    90  							if err := conn.Invoke(db.OptContext(ctx), db.OptTx(tx)).Create(&UserInfo{
    91  								UserID:  user.ID,
    92  								IsAdmin: true,
    93  							}); err != nil {
    94  								return err
    95  							}
    96  							return nil
    97  						}),
    98  					),
    99  					migration.NewGroupWithStep(
   100  						migration.ConstraintExists("chirp_like", "pk_chirp_like_chirp_id"),
   101  						migration.Statements(
   102  							`ALTER TABLE chirp_like DROP CONSTRAINT pk_chirp_like_chirp_id`,
   103  							`ALTER TABLE chirp_like ADD CONSTRAINT pk_chirp_like_chirp_id_user_id PRIMARY KEY (chirp_id, user_id)`,
   104  						),
   105  					),
   106  				)...,
   107  			),
   108  		)...,
   109  	)
   110  }