github.com/sharovik/devbot@v1.0.1-0.20240308094637-4a0387c40516/scripts/install/main.go (about)

     1  package main
     2  
     3  import (
     4  	"flag"
     5  	"os"
     6  
     7  	"github.com/sharovik/devbot/internal/dto/databasedto"
     8  	"github.com/sharovik/devbot/internal/service/definedevents"
     9  	"github.com/sharovik/orm/clients"
    10  	"github.com/sharovik/orm/dto"
    11  
    12  	"github.com/sharovik/devbot/internal/config"
    13  	"github.com/sharovik/devbot/internal/container"
    14  	"github.com/sharovik/devbot/internal/database"
    15  	"github.com/sharovik/devbot/internal/log"
    16  	im "github.com/sharovik/devbot/scripts/install/database"
    17  )
    18  
    19  const descriptionEventAlias = "The event alias for which Install method will be called"
    20  const envFilePath = "./.env"
    21  
    22  var (
    23  	cfg = config.Config{}
    24  	m   = []database.BaseMigrationInterface{
    25  		im.InstallMigration{},
    26  	}
    27  )
    28  
    29  func init() {
    30  	configuration, err := config.Init()
    31  	if err != nil {
    32  		panic(err)
    33  	}
    34  
    35  	cfg = configuration
    36  	_ = log.Init(cfg.LogConfig)
    37  }
    38  
    39  func main() {
    40  	if err := run(); err != nil {
    41  		if err := container.C.Dictionary.CloseDatabaseConnection(); err != nil {
    42  			log.Logger().AddError(err).Msg("Failed to close connection")
    43  		}
    44  	}
    45  }
    46  
    47  func triggerMigrations() error {
    48  	//Create migrations table
    49  	q := new(clients.Query).
    50  		Create(databasedto.MigrationModel).
    51  		IfNotExists().
    52  		AddIndex(dto.Index{
    53  			Name:   "migration_version_uindex",
    54  			Target: databasedto.MigrationModel.GetTableName(),
    55  			Key:    "version",
    56  			Unique: true,
    57  		})
    58  	if _, err := container.C.Dictionary.GetDBClient().Execute(q); err != nil {
    59  		log.Logger().AddError(err).Msg("Failed to create migration table. Already exists?")
    60  	}
    61  
    62  	for _, migration := range m {
    63  		container.C.MigrationService.SetMigration(migration)
    64  	}
    65  
    66  	if err := container.C.MigrationService.RunMigrations(); err != nil {
    67  		return err
    68  	}
    69  
    70  	return nil
    71  }
    72  
    73  func run() error {
    74  	if err := checkIfEnvFilesExists(); err != nil {
    75  		log.Logger().AddError(err).Msg("Failed check the .env file step")
    76  		return err
    77  	}
    78  
    79  	if err := checkIfDatabaseExists(); err != nil {
    80  		log.Logger().AddError(err).Msg("Database check error")
    81  		return err
    82  	}
    83  
    84  	eventAlias := parseEventAlias()
    85  	cnt, err := container.Init()
    86  	if err != nil {
    87  		log.Logger().AddError(err).Msg("Failed to init container")
    88  		return err
    89  	}
    90  
    91  	container.C = cnt
    92  
    93  	definedevents.InitializeDefinedEvents()
    94  
    95  	if err = triggerMigrations(); err != nil {
    96  		log.Logger().AddError(err).Msg("Database check error")
    97  		return err
    98  	}
    99  
   100  	if eventAlias != "" {
   101  		log.Logger().Info().Msg("Event alias cannot be empty")
   102  
   103  		if container.C.DefinedEvents[eventAlias] == nil {
   104  			log.Logger().Info().Msg("Event is not defined in the defined-events")
   105  			return nil
   106  		}
   107  
   108  		eventID, err := container.C.Dictionary.FindEventByAlias(eventAlias)
   109  		if err != nil {
   110  			log.Logger().AddError(err).Msg("Failed to check if event exists")
   111  			return err
   112  		}
   113  
   114  		if eventID != int64(0) {
   115  			log.Logger().Info().Msg("Event is already installed")
   116  			return nil
   117  		}
   118  
   119  		if err := container.C.DefinedEvents[eventAlias].Install(); err != nil {
   120  			log.Logger().AddError(err).Str("event_name", eventAlias).Msg("Failed to install the event.")
   121  		}
   122  
   123  		if err := container.C.Dictionary.CloseDatabaseConnection(); err != nil {
   124  			log.Logger().AddError(err).Msg("Failed to close connection")
   125  		}
   126  
   127  		log.Logger().Info().Msg("Done")
   128  		return nil
   129  	}
   130  
   131  	log.Logger().Debug().Msg("Trying to install all defined events if it's possible")
   132  	for eventAlias, event := range container.C.DefinedEvents {
   133  
   134  		eventID, err := container.C.Dictionary.FindEventByAlias(eventAlias)
   135  		if err != nil {
   136  			log.Logger().AddError(err).Msg("Failed to check if event exists")
   137  			return err
   138  		}
   139  
   140  		if eventID != int64(0) {
   141  			log.Logger().Info().Int64("event_id", eventID).Str("event_alias", eventAlias).Msg("Event is already installed")
   142  			continue
   143  		}
   144  
   145  		if err := event.Install(); err != nil {
   146  			log.Logger().AddError(err).Str("event_alias", eventAlias).Msg("Failed to install the event.")
   147  		}
   148  	}
   149  
   150  	log.Logger().Info().Msg("Done")
   151  	return nil
   152  }
   153  
   154  func checkIfDatabaseExists() error {
   155  	log.Logger().AppendGlobalContext(map[string]interface{}{
   156  		"database_connection": cfg.Database.Type,
   157  		"database_host":       cfg.Database.Host,
   158  	})
   159  	log.Logger().Info().Msg("Check if the database exists")
   160  	switch cfg.Database.Type {
   161  	case clients.DatabaseTypeSqlite:
   162  		_, err := os.Stat(cfg.Database.Host)
   163  		if err == nil {
   164  			log.Logger().Info().Msg("Database file already exists")
   165  			return nil
   166  		}
   167  
   168  		log.Logger().Info().Msg("Creating the database file")
   169  
   170  		_, err = os.Create(cfg.Database.Host)
   171  		if err != nil {
   172  			log.Logger().AddError(err).Msg("Failed to create database file")
   173  			return err
   174  		}
   175  	default:
   176  		log.Logger().Info().Msg("No action for selected type of database")
   177  	}
   178  
   179  	return nil
   180  }
   181  
   182  func checkIfEnvFilesExists() error {
   183  	if _, err := os.Stat(envFilePath); err != nil {
   184  		log.Logger().AddError(err).
   185  			Str("path", envFilePath).
   186  			Msg("The .env file does not exists in selected path")
   187  
   188  		return err
   189  	}
   190  
   191  	return nil
   192  }
   193  
   194  func parseEventAlias() string {
   195  	eventAlias := flag.String("event_alias", "", descriptionEventAlias)
   196  	flag.Parse()
   197  
   198  	return *eventAlias
   199  }