diff --git a/core/server.go b/core/server.go index 71457bc..f79d601 100644 --- a/core/server.go +++ b/core/server.go @@ -1,48 +1,109 @@ package main import ( - "encoding/json" "fmt" "log" "net/http" - "os" "strconv" "github.com/openaccounting/oa-server/core/api" "github.com/openaccounting/oa-server/core/auth" "github.com/openaccounting/oa-server/core/model" - "github.com/openaccounting/oa-server/core/model/db" "github.com/openaccounting/oa-server/core/model/types" + "github.com/openaccounting/oa-server/core/repository" "github.com/openaccounting/oa-server/core/util" + "github.com/openaccounting/oa-server/database" + "github.com/spf13/viper" ) func main() { - //filename is the path to the json config file + // Initialize Viper configuration var config types.Config - file, err := os.Open("./config.json") - + + // Set config file properties + viper.SetConfigName("config") + viper.SetConfigType("json") + viper.AddConfigPath(".") + viper.AddConfigPath("/etc/openaccounting/") + viper.AddConfigPath("$HOME/.openaccounting") + + // Enable environment variables + viper.AutomaticEnv() + viper.SetEnvPrefix("OA") // will look for OA_DATABASE_PASSWORD, etc. + + // Set default values + viper.SetDefault("Address", "localhost") + viper.SetDefault("Port", 8080) + viper.SetDefault("DatabaseDriver", "sqlite") + viper.SetDefault("DatabaseFile", "./openaccounting.db") + viper.SetDefault("ApiPrefix", "/api/v1") + + // Read configuration + err := viper.ReadInConfig() if err != nil { - log.Fatal(fmt.Errorf("failed to open ./config.json with: %s", err.Error())) + log.Printf("Warning: Could not read config file: %v", err) + log.Println("Using environment variables and defaults") + } + + // Unmarshal config into struct + err = viper.Unmarshal(&config) + if err != nil { + log.Fatal(fmt.Errorf("failed to unmarshal config: %s", err.Error())) } - decoder := json.NewDecoder(file) - err = decoder.Decode(&config) - - if err != nil { - log.Fatal(fmt.Errorf("failed to decode ./config.json with: %s", err.Error())) + // Parse database address (assuming format host:port for MySQL) + host := config.DatabaseAddress + port := "3306" + if len(config.DatabaseAddress) > 0 { + // If there's a colon, split host and port + if colonIndex := len(config.DatabaseAddress); colonIndex > 0 { + host = config.DatabaseAddress + } } - connectionString := config.User + ":" + config.Password + "@" + config.DatabaseAddress + "/" + config.Database + // Default to SQLite if no driver specified + driver := config.DatabaseDriver + if driver == "" { + driver = "sqlite" + } - db, err := db.NewDB(connectionString) + // Initialize GORM database + dbConfig := &database.Config{ + Driver: driver, + Host: host, + Port: port, + User: config.User, + Password: config.Password, + DBName: config.Database, + File: config.DatabaseFile, + SSLMode: "disable", // Adjust as needed + } + + err = database.Connect(dbConfig) if err != nil { log.Fatal(fmt.Errorf("failed to connect to database with: %s", err.Error())) } + // Run migrations + err = database.AutoMigrate() + if err != nil { + log.Fatal(fmt.Errorf("failed to run migrations: %s", err.Error())) + } + + err = database.Migrate() + if err != nil { + log.Fatal(fmt.Errorf("failed to run custom migrations: %s", err.Error())) + } + bc := &util.StandardBcrypt{} - model.NewModel(db, bc, config) - auth.NewAuthService(db, bc) + // Create GORM repository and models + gormRepo := repository.NewGormRepository(database.DB) + gormModel := model.NewGormModel(database.DB, bc, config) + auth.NewGormAuthService(gormRepo, bc) + + // Set the global model instance + model.Instance = gormModel app, err := api.Init(config.ApiPrefix) if err != nil {