Starting auto-creation of database
This commit is contained in:
		
							parent
							
								
									e1baee2fd3
								
							
						
					
					
						commit
						b6104dfdbd
					
				@ -34,7 +34,7 @@ type columsDefinition struct {
 | 
				
			|||||||
	Type          string
 | 
						Type          string
 | 
				
			||||||
	Default       any
 | 
						Default       any
 | 
				
			||||||
	IsNullable    bool
 | 
						IsNullable    bool
 | 
				
			||||||
	Extra      string
 | 
						AutoIncrement bool
 | 
				
			||||||
	Charset       any
 | 
						Charset       any
 | 
				
			||||||
	Collation     any
 | 
						Collation     any
 | 
				
			||||||
	Table         string
 | 
						Table         string
 | 
				
			||||||
@ -63,69 +63,256 @@ type tableDefinition struct {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type databaseDefinition struct {
 | 
					type databaseDefinition struct {
 | 
				
			||||||
	Name        string
 | 
					 | 
				
			||||||
	Tables      []tableDefinition
 | 
						Tables      []tableDefinition
 | 
				
			||||||
	Indexes     []indexDefinition
 | 
						Indexes     []indexDefinition
 | 
				
			||||||
	ForeignKeys []foreignKeyDefinition
 | 
						ForeignKeys []foreignKeyDefinition
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var listTables = []tableDefinition{
 | 
					var databaseStructure databaseDefinition = databaseDefinition{
 | 
				
			||||||
 | 
						Tables: []tableDefinition{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		Name: "users",
 | 
								Name: "user",
 | 
				
			||||||
			Columns: []columsDefinition{
 | 
								Columns: []columsDefinition{
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Name:          "id",
 | 
										Name:          "id",
 | 
				
			||||||
					Type:          "int(11)",
 | 
										Type:          "int(11)",
 | 
				
			||||||
				Default:    nil,
 | 
					 | 
				
			||||||
					IsNullable:    false,
 | 
										IsNullable:    false,
 | 
				
			||||||
				Extra:      "AUTO_INCREMENT",
 | 
										AutoIncrement: true,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Name:       "name",
 | 
										Name:       "name",
 | 
				
			||||||
					Type:       "varchar(256)",
 | 
										Type:       "varchar(256)",
 | 
				
			||||||
				Default:    nil,
 | 
					 | 
				
			||||||
					IsNullable: false,
 | 
										IsNullable: false,
 | 
				
			||||||
				Extra:      "",
 | 
					 | 
				
			||||||
					Charset:    "utf8mb4",
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
					Collation:  "utf8mb4_unicode_ci",
 | 
										Collation:  "utf8mb4_unicode_ci",
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Name:       "password",
 | 
										Name:       "password",
 | 
				
			||||||
					Type:       "varchar(256)",
 | 
										Type:       "varchar(256)",
 | 
				
			||||||
				Default:    nil,
 | 
					 | 
				
			||||||
					IsNullable: false,
 | 
										IsNullable: false,
 | 
				
			||||||
				Extra:      "",
 | 
					 | 
				
			||||||
					Charset:    "utf8mb4",
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
				Collation:  "utf8mb4_unicode",
 | 
										Collation:  "utf8mb4_bin",
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
				Name:       "password-salt",
 | 
										Name:       "password_salt",
 | 
				
			||||||
					Type:       "varchar(256)",
 | 
										Type:       "varchar(256)",
 | 
				
			||||||
				Default:    nil,
 | 
					 | 
				
			||||||
					IsNullable: false,
 | 
										IsNullable: false,
 | 
				
			||||||
				Extra:      "",
 | 
					 | 
				
			||||||
					Charset:    "utf8mb4",
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
				Collation:  "utf8mb4_unicode",
 | 
										Collation:  "utf8mb4_bin",
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Name:       "permission_level",
 | 
										Name:       "permission_level",
 | 
				
			||||||
					Type:       "enum('ADMIN', 'MODERATOR', 'USER')",
 | 
										Type:       "enum('ADMIN', 'MODERATOR', 'USER')",
 | 
				
			||||||
				Default:    "USER",
 | 
										Default:    "'USER'",
 | 
				
			||||||
					IsNullable: false,
 | 
										IsNullable: false,
 | 
				
			||||||
				Extra:      "",
 | 
					 | 
				
			||||||
					Charset:    nil,
 | 
										Charset:    nil,
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Name:       "email",
 | 
										Name:       "email",
 | 
				
			||||||
					Type:       "varchar(256)",
 | 
										Type:       "varchar(256)",
 | 
				
			||||||
				Default:    nil,
 | 
					 | 
				
			||||||
					IsNullable: true,
 | 
										IsNullable: true,
 | 
				
			||||||
				Extra:      "",
 | 
										Default:    "NULL",
 | 
				
			||||||
					Charset:    "utf8mb4",
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
				Collation:  "utf8mb4_unicode",
 | 
										Collation:  "utf8mb4_bin",
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name: "folder",
 | 
				
			||||||
 | 
								Columns: []columsDefinition{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:          "id",
 | 
				
			||||||
 | 
										Type:          "int(11)",
 | 
				
			||||||
 | 
										IsNullable:    false,
 | 
				
			||||||
 | 
										AutoIncrement: true,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "name",
 | 
				
			||||||
 | 
										Type:       "varchar(64)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_unicode_ci",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name: "tag",
 | 
				
			||||||
 | 
								Columns: []columsDefinition{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:          "id",
 | 
				
			||||||
 | 
										Type:          "int(11)",
 | 
				
			||||||
 | 
										IsNullable:    false,
 | 
				
			||||||
 | 
										AutoIncrement: true,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "name",
 | 
				
			||||||
 | 
										Type:       "varchar(64)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_unicode_ci",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name: "website",
 | 
				
			||||||
 | 
								Columns: []columsDefinition{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:          "id",
 | 
				
			||||||
 | 
										Type:          "int(11)",
 | 
				
			||||||
 | 
										IsNullable:    false,
 | 
				
			||||||
 | 
										AutoIncrement: true,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "name",
 | 
				
			||||||
 | 
										Type:       "varchar(256)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_unicode_ci",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "content",
 | 
				
			||||||
 | 
										Type:       "longtext",
 | 
				
			||||||
 | 
										IsNullable: true,
 | 
				
			||||||
 | 
										Default:    "NULL",
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_bin",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "description",
 | 
				
			||||||
 | 
										Type:       "longtext",
 | 
				
			||||||
 | 
										IsNullable: true,
 | 
				
			||||||
 | 
										Default:    "NULL",
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_bin",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "folder_id",
 | 
				
			||||||
 | 
										Type:       "int(11)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "date",
 | 
				
			||||||
 | 
										Type:       "datetime",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
										Default:    "current_timestamp()",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "title",
 | 
				
			||||||
 | 
										Type:       "varchar(256)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_unicode_ci",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name: "tags_websites",
 | 
				
			||||||
 | 
								Columns: []columsDefinition{
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "tag_id",
 | 
				
			||||||
 | 
										Type:       "int(10)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "website_id",
 | 
				
			||||||
 | 
										Type:       "int(10)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										Name:       "value",
 | 
				
			||||||
 | 
										Type:       "varchar(64)",
 | 
				
			||||||
 | 
										IsNullable: false,
 | 
				
			||||||
 | 
										Charset:    "utf8mb4",
 | 
				
			||||||
 | 
										Collation:  "utf8mb4_unicode_ci",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						Indexes: []indexDefinition{
 | 
				
			||||||
 | 
							// PRIMARY KEYS
 | 
				
			||||||
 | 
							/*
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Name:  "",
 | 
				
			||||||
 | 
									Type:  database_ENUM_INDEX_PRIMARY,
 | 
				
			||||||
 | 
									Table: "user",
 | 
				
			||||||
 | 
									Columns: []string{
 | 
				
			||||||
 | 
										"id",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Name:  "",
 | 
				
			||||||
 | 
									Type:  database_ENUM_INDEX_PRIMARY,
 | 
				
			||||||
 | 
									Table: "folder",
 | 
				
			||||||
 | 
									Columns: []string{
 | 
				
			||||||
 | 
										"id",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Name:  "",
 | 
				
			||||||
 | 
									Type:  database_ENUM_INDEX_PRIMARY,
 | 
				
			||||||
 | 
									Table: "tag",
 | 
				
			||||||
 | 
									Columns: []string{
 | 
				
			||||||
 | 
										"id",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Name:  "",
 | 
				
			||||||
 | 
									Type:  database_ENUM_INDEX_PRIMARY,
 | 
				
			||||||
 | 
									Table: "website",
 | 
				
			||||||
 | 
									Columns: []string{
 | 
				
			||||||
 | 
										"id",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									Name:  "",
 | 
				
			||||||
 | 
									Type:  database_ENUM_INDEX_PRIMARY,
 | 
				
			||||||
 | 
									Table: "tags_websites",
 | 
				
			||||||
 | 
									Columns: []string{
 | 
				
			||||||
 | 
										"tag_id",
 | 
				
			||||||
 | 
										"website_id",
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							*/
 | 
				
			||||||
 | 
							// UNIQUE KEYS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:  "UNIQUE_user_name",
 | 
				
			||||||
 | 
								Type:  database_ENUM_INDEX_UNIQUE,
 | 
				
			||||||
 | 
								Table: "user",
 | 
				
			||||||
 | 
								Columns: []string{
 | 
				
			||||||
 | 
									"name",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:  "UNIQUE_website_name_folder",
 | 
				
			||||||
 | 
								Type:  database_ENUM_INDEX_UNIQUE,
 | 
				
			||||||
 | 
								Table: "website",
 | 
				
			||||||
 | 
								Columns: []string{
 | 
				
			||||||
 | 
									"name",
 | 
				
			||||||
 | 
									"folder_id",
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						ForeignKeys: []foreignKeyDefinition{
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:             "FK_tags_websites__tag_id",
 | 
				
			||||||
 | 
								Table:            "tags_websites",
 | 
				
			||||||
 | 
								ColumnName:       "tag_id",
 | 
				
			||||||
 | 
								PointingToTable:  "tag",
 | 
				
			||||||
 | 
								PointingToColumn: "id",
 | 
				
			||||||
 | 
								UpdateRule:       "CASCADE",
 | 
				
			||||||
 | 
								DeleteRule:       "CASCADE",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Name:             "FK_tags_websites__website_id",
 | 
				
			||||||
 | 
								Table:            "tags_websites",
 | 
				
			||||||
 | 
								ColumnName:       "website_id",
 | 
				
			||||||
 | 
								PointingToTable:  "website",
 | 
				
			||||||
 | 
								PointingToColumn: "id",
 | 
				
			||||||
 | 
								UpdateRule:       "CASCADE",
 | 
				
			||||||
 | 
								DeleteRule:       "CASCADE",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var dbPath string
 | 
					var dbPath string
 | 
				
			||||||
@ -146,6 +333,8 @@ func Init() {
 | 
				
			|||||||
	profiler.Register(profiler_DATABASE_QUERY, 4000, "µs")
 | 
						profiler.Register(profiler_DATABASE_QUERY, 4000, "µs")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	isInit = true
 | 
						isInit = true
 | 
				
			||||||
 | 
						destroyDatabase()
 | 
				
			||||||
 | 
						updateDatabaseStructure()
 | 
				
			||||||
	initDatabaseStructure()
 | 
						initDatabaseStructure()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -247,13 +436,47 @@ func executeQuery(query string, args ...any) *sql.Rows {
 | 
				
			|||||||
	profiler.Add(profiler_DATABASE_QUERY, time.Duration(time.Since(tStart).Microseconds()))
 | 
						profiler.Add(profiler_DATABASE_QUERY, time.Duration(time.Since(tStart).Microseconds()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Printf("Cannot query the database ! (Query : %s) with args ", query)
 | 
							log.Printf("Cannot query the database ! Query : %s", query)
 | 
				
			||||||
		log.Fatalln(args...)
 | 
							log.Fatalln("With args :", args)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return rows
 | 
						return rows
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func executeExec(query string, args ...any) sql.Result {
 | 
				
			||||||
 | 
						if !isInit {
 | 
				
			||||||
 | 
							return nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if db == nil {
 | 
				
			||||||
 | 
							connect()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						var result sql.Result
 | 
				
			||||||
 | 
						tStart := time.Now()
 | 
				
			||||||
 | 
						for i := range dbConfig.RetriesOnError {
 | 
				
			||||||
 | 
							result, err = db.Exec(query, args...)
 | 
				
			||||||
 | 
							if err == nil {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							log.Printf("Error while executing on the database [%d/%d] : %s\n", i+1, dbConfig.RetriesOnError, err)
 | 
				
			||||||
 | 
							if i+1 == dbConfig.RetriesOnError {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							time.Sleep((time.Duration)(dbConfig.TimeBetweenRetriesMs) * time.Millisecond)
 | 
				
			||||||
 | 
							ping()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						profiler.Add(profiler_DATABASE_QUERY, time.Duration(time.Since(tStart).Microseconds()))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							log.Printf("Cannot execute on the database ! Command : %s", query)
 | 
				
			||||||
 | 
							log.Fatalln("With args : ", args)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func fetchStoredRoutines() {
 | 
					func fetchStoredRoutines() {
 | 
				
			||||||
	storedRoutines = nil
 | 
						storedRoutines = nil
 | 
				
			||||||
	var rows *sql.Rows = executeQuery("SELECT ROUTINE_NAME, ROUTINE_TYPE FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA=?;", dbConfig.Database)
 | 
						var rows *sql.Rows = executeQuery("SELECT ROUTINE_NAME, ROUTINE_TYPE FROM information_schema.ROUTINES WHERE ROUTINE_SCHEMA=?;", dbConfig.Database)
 | 
				
			||||||
@ -318,7 +541,8 @@ func callStoredFunction(name string, args ...any) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func fetchTables() []string {
 | 
					func fetchTables() []string {
 | 
				
			||||||
	var rows *sql.Rows = executeQuery("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=?;", dbConfig.Database)
 | 
						var rows *sql.Rows = executeQuery("SHOW TABLES;")
 | 
				
			||||||
 | 
						//var rows *sql.Rows = executeQuery("SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA=?;", dbConfig.Database)
 | 
				
			||||||
	var tables []string = make([]string, 0)
 | 
						var tables []string = make([]string, 0)
 | 
				
			||||||
	if rows != nil {
 | 
						if rows != nil {
 | 
				
			||||||
		defer rows.Close()
 | 
							defer rows.Close()
 | 
				
			||||||
@ -332,19 +556,18 @@ func fetchTables() []string {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func fetchColumns(table string) []columsDefinition {
 | 
					func fetchColumns(table string) []columsDefinition {
 | 
				
			||||||
	var rows *sql.Rows = executeQuery("SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_DEFAULT, IS_NULLABLE, EXTRA, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=? AND TABLE_NAME=?;", dbConfig.Database, table)
 | 
						var rows *sql.Rows = executeQuery("SELECT COLUMN_NAME, COLUMN_TYPE, COLUMN_DEFAULT, IS_NULLABLE, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=? AND TABLE_NAME=?;", dbConfig.Database, table)
 | 
				
			||||||
	var columns []columsDefinition = make([]columsDefinition, 0)
 | 
						var columns []columsDefinition = make([]columsDefinition, 0)
 | 
				
			||||||
	if rows != nil {
 | 
						if rows != nil {
 | 
				
			||||||
		defer rows.Close()
 | 
							defer rows.Close()
 | 
				
			||||||
		for rows.Next() {
 | 
							for rows.Next() {
 | 
				
			||||||
			var resName, resType, resDefault, resNullable, resExtra, resCharset, resCollation string
 | 
								var resName, resType, resDefault, resNullable, resCharset, resCollation string
 | 
				
			||||||
			rows.Scan(&resName, &resType, &resDefault, &resNullable, &resExtra, &resCharset, &resCollation)
 | 
								rows.Scan(&resName, &resType, &resDefault, &resNullable, &resCharset, &resCollation)
 | 
				
			||||||
			columns = append(columns, columsDefinition{
 | 
								columns = append(columns, columsDefinition{
 | 
				
			||||||
				Name:       resName,
 | 
									Name:       resName,
 | 
				
			||||||
				Type:       resType,
 | 
									Type:       resType,
 | 
				
			||||||
				Default:    resDefault,
 | 
									Default:    resDefault,
 | 
				
			||||||
				IsNullable: resNullable == "YES",
 | 
									IsNullable: resNullable == "YES",
 | 
				
			||||||
				Extra:      resExtra,
 | 
					 | 
				
			||||||
				Charset:    resCharset,
 | 
									Charset:    resCharset,
 | 
				
			||||||
				Collation:  resCollation,
 | 
									Collation:  resCollation,
 | 
				
			||||||
				Table:      table,
 | 
									Table:      table,
 | 
				
			||||||
@ -421,8 +644,8 @@ func initDatabaseStructure() {
 | 
				
			|||||||
		var columns []columsDefinition = fetchColumns(tables[i])
 | 
							var columns []columsDefinition = fetchColumns(tables[i])
 | 
				
			||||||
		log.Printf(" - Table %s : \n", tables[i])
 | 
							log.Printf(" - Table %s : \n", tables[i])
 | 
				
			||||||
		for j := range columns {
 | 
							for j := range columns {
 | 
				
			||||||
			log.Printf("   - Column %s %s IsNullable:%t Default:%s Extra:%s Charset:%s/%s\n",
 | 
								log.Printf("   - Column %s %s IsNullable:%t Default:%s Charset:%s/%s\n",
 | 
				
			||||||
				columns[j].Name, columns[j].Type, columns[j].IsNullable, columns[j].Default, columns[j].Extra, columns[j].Charset, columns[j].Collation)
 | 
									columns[j].Name, columns[j].Type, columns[j].IsNullable, columns[j].Default, columns[j].Charset, columns[j].Collation)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -438,3 +661,119 @@ func initDatabaseStructure() {
 | 
				
			|||||||
		log.Printf(" - Foreign key %s\n", foreignKeys[i])
 | 
							log.Printf(" - Foreign key %s\n", foreignKeys[i])
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func updateDatabaseStructure() {
 | 
				
			||||||
 | 
						var tablesNeeded []tableDefinition = databaseStructure.Tables
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for t := range tablesNeeded {
 | 
				
			||||||
 | 
							var table tableDefinition = tablesNeeded[t]
 | 
				
			||||||
 | 
							var columnsNeeded []columsDefinition = table.Columns
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							executeExec(fmt.Sprintf("DROP TABLE IF EXISTS %s;", table.Name))
 | 
				
			||||||
 | 
							var query string = fmt.Sprintf("CREATE TABLE %s (\n", table.Name)
 | 
				
			||||||
 | 
							for c := range columnsNeeded {
 | 
				
			||||||
 | 
								if c != 0 {
 | 
				
			||||||
 | 
									query += ",\n"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var column columsDefinition = columnsNeeded[c]
 | 
				
			||||||
 | 
								query += fmt.Sprintf("%s %s", column.Name, column.Type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								str, ok := column.Charset.(string)
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									query += fmt.Sprintf(" CHARACTER SET %s", str)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								str, ok = column.Collation.(string)
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									query += fmt.Sprintf(" COLLATE %s", str)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if !column.IsNullable {
 | 
				
			||||||
 | 
									query += " NOT NULL"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								str, ok = column.Default.(string)
 | 
				
			||||||
 | 
								if ok {
 | 
				
			||||||
 | 
									query += fmt.Sprintf(" DEFAULT %s", str)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							query += "\n);"
 | 
				
			||||||
 | 
							fmt.Println(query)
 | 
				
			||||||
 | 
							executeExec(query)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var indexesNeeded []indexDefinition = databaseStructure.Indexes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for i := range indexesNeeded {
 | 
				
			||||||
 | 
							var index indexDefinition = indexesNeeded[i]
 | 
				
			||||||
 | 
							// ALTER TABLE <table> ADD CONSTRAINT PRIMARY KEY(<columns>);
 | 
				
			||||||
 | 
							// ALTER TABLE <table> ADD CONSTRAINT <constraint_name> UNIQUE(<columns>);
 | 
				
			||||||
 | 
							var command string = fmt.Sprintf("ALTER TABLE %s ADD CONSTRAINT ", index.Table)
 | 
				
			||||||
 | 
							switch index.Type {
 | 
				
			||||||
 | 
							case database_ENUM_INDEX_PRIMARY:
 | 
				
			||||||
 | 
								command += "PRIMARY KEY("
 | 
				
			||||||
 | 
							case database_ENUM_INDEX_UNIQUE:
 | 
				
			||||||
 | 
								command += fmt.Sprintf(" %s UNIQUE(", index.Name)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for c := range index.Columns {
 | 
				
			||||||
 | 
								if c != 0 {
 | 
				
			||||||
 | 
									command += ", "
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								var column string = index.Columns[c]
 | 
				
			||||||
 | 
								command += column
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							command += ");"
 | 
				
			||||||
 | 
							fmt.Println(command)
 | 
				
			||||||
 | 
							executeExec(command)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var foreignKeys []foreignKeyDefinition = databaseStructure.ForeignKeys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for fk := range foreignKeys {
 | 
				
			||||||
 | 
							var foreignKey foreignKeyDefinition = foreignKeys[fk]
 | 
				
			||||||
 | 
							// ALTER TABLE <table> ADD CONSTRAINT <constraint_name> FOREIGN KEY(<column>) REFERENCES <ref_table>(<ref_column>) ON DELETE <CASCADE / SET NULL> UPDATE <CASCADE / SET NULL>;
 | 
				
			||||||
 | 
							var command string = fmt.Sprintf("ALTER TABLE %s ADD INDEX %s(%s);", foreignKey.PointingToTable, foreignKey.Name, foreignKey.PointingToColumn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fmt.Println(command)
 | 
				
			||||||
 | 
							executeExec(command)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							command = fmt.Sprintf("ALTER TABLE %s ADD CONSTRAINT %s FOREIGN KEY (%s) REFERENCES %s (%s)", foreignKey.Table, foreignKey.Name, foreignKey.ColumnName, foreignKey.PointingToTable, foreignKey.PointingToColumn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if foreignKey.DeleteRule != "" {
 | 
				
			||||||
 | 
								command += fmt.Sprintf(" ON DELETE %s", foreignKey.DeleteRule)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if foreignKey.UpdateRule != "" {
 | 
				
			||||||
 | 
								command += fmt.Sprintf(" ON UPDATE %s", foreignKey.UpdateRule)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							command += ";"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fmt.Println(command)
 | 
				
			||||||
 | 
							executeExec(command)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func destroyDatabase() {
 | 
				
			||||||
 | 
						var tables []string = fetchTables()
 | 
				
			||||||
 | 
						var foreignKeys []foreignKeyDefinition = fetchForeignKeys()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for fk := range foreignKeys {
 | 
				
			||||||
 | 
							var foreignKey foreignKeyDefinition = foreignKeys[fk]
 | 
				
			||||||
 | 
							var command string = fmt.Sprintf("ALTER TABLE %s DROP FOREIGN KEY %s;", foreignKey.Table, foreignKey.Name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fmt.Println(command)
 | 
				
			||||||
 | 
							executeExec(command)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for t := range tables {
 | 
				
			||||||
 | 
							var table string = tables[t]
 | 
				
			||||||
 | 
							var command string = fmt.Sprintf("DROP TABLE %s;", table)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fmt.Println(command)
 | 
				
			||||||
 | 
							executeExec(command)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user