Ivan Chavero
2019-11-06 633b30798b3ac7af096f1d1d38e00a910b83d180
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
package main
 
import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
    "github.com/gorilla/mux"
    "html/template"
    "log"
    "net/http"
    "os"
)
 
// Global variables
 
var username, password, database, host string
var DB *sql.DB
 
type Quote struct {
    ID      int
    Message string
}
 
func main() {
    username, _ = os.LookupEnv("MYSQL_USER")
    password, _ = os.LookupEnv("MYSQL_PASSWORD")
    database, _ = os.LookupEnv("MYSQL_DATABASE")
    host, _ = os.LookupEnv("MYSQL_HOST")
    DB = db_connect(username, password, database, host)
    if DB == nil {
        log.Printf("Could not connect to the databse: %s", database)
    }
    defer DB.Close()
    setup()
 
    r := mux.NewRouter()
    r.HandleFunc("/", HomeHandler)
    r.HandleFunc("/random", RandHandler)
    r.HandleFunc("/env", EnvHandler)
    r.HandleFunc("/status", StatusHandler)
    http.Handle("/", r)
    log.Printf("Starting Application\nServices:\n/\n/random\n/env\n/status")
    log.Fatal(http.ListenAndServe(":8000", r))
}
 
// Handlers
 
func HomeHandler(w http.ResponseWriter, r *http.Request) {
    tmpl := template.Must(template.ParseFiles("layout.html"))
    quotes := get_all_quotes()
    data := struct {
        Quotes []Quote
    }{
        quotes,
    }
    err := tmpl.Execute(w, data)
    if err != nil {
        log.Printf("Error while executing template: %s", err)
    }
}
 
func RandHandler(w http.ResponseWriter, r *http.Request) {
    quote := get_random_quote()
    fmt.Fprintf(w, "%d: %s", quote.ID, quote.Message)
}
 
func StatusHandler(w http.ResponseWriter, r *http.Request) {
    err := DB.Ping()
    if err != nil {
        fmt.Fprintf(w, "Database connection error: %s", err)
    } else {
        fmt.Fprintf(w, "Database connection OK\n")
    }
}
 
func EnvHandler(w http.ResponseWriter, r *http.Request) {
    tmpl := template.Must(template.ParseFiles("layout.html"))
    data := struct {
        MYSQL_USER     string
        MYSQL_PASSWORD string
        MYSQL_DATABASE string
        MYSQL_HOST     string
        Quotes         []Quote
    }{
        username,
        password,
        database,
        host,
        nil,
    }
    err := tmpl.Execute(w, data)
    if err != nil {
        log.Printf("Error while executing template: %s", err)
    }
    log.Printf("Database Setup Variables:\nMYSQL_USER: %s\nMYSQL_PASSWORD: %s\nMYSQL_DATABASE: %s\nMYSQL_HOST: %s\n", username, password, database, host)
 
}
 
func Setup() {
    var messages = []string{
        "When words fail, music speaks.\n- William Shakespeare\n",
        "Happines depends upon ourselves.\n- Aristotle\n",
        "The secret of change is to focus all your energy not on fighting the old but on building the new.\n- Socrates\n",
        "Nothing that glitters is gold.\n- Mark Twain",
        "Imagination is more important than knowledge.\n- Albert Einstein\n",
        "Hell, if I could explain it to the average person, it wouldn't have been worth the Nobel prize.\n- Richard Feynman\n",
        "Young man, in mathematics you don't understand things. You just get used to them.\n- John von Neumann\n",
        "Those who can imagine anything, can create the impossible.\n- Alan Turing\n",
    }
    log.Print("Creating schema")
    db_create_schema()
    log.Printf("Database Setup Completed\n")
    for _, s := range messages {
        insert_data(s)
    }
}
 
// Data functions
 
func setup() {
    var rows string
 
    // Check if the databse connection is active
    err := DB.Ping()
    if err != nil {
        log.Fatalf("Database connection error: %s", err)
    } else {
        log.Printf("Database connection OK\n")
    }
 
    // Get table rows to check if there's data already
    err = DB.QueryRow("SELECT count(*) FROM quotes").Scan(&rows)
    if err == nil && rows != "0" {
        log.Printf("Database already setup, ignoring")
        return
    }
 
    log.Print("Creating schema")
    db_create_schema()
    log.Print("Adding quotes")
    for _, s := range messages {
        insert_data(s)
    }
    log.Printf("Database Setup Completed\n")
}
 
func db_create_schema() {
    crt, err := DB.Prepare("CREATE TABLE quotes (id int NOT NULL AUTO_INCREMENT, message text, CONSTRAINT id_pk PRIMARY KEY (id))")
    if err != nil {
        log.Printf("Error preparing the database creation: %s", err)
    }
    _, err = crt.Exec()
    if err != nil {
        log.Printf("Error creating the database: %s", err)
    }
    crt.Close()
}
 
func db_connect(username string, password string, database string, host string) *sql.DB {
    connstring := username + ":" + password + "@tcp(" + host + ":3306)/" + database
    log.Print("Connecting to the database: " + connstring)
    db, err := sql.Open("mysql", connstring)
    if err != nil {
        log.Printf("Error preparing database connection:%s", err.Error())
        return nil
    }
 
    return db
}
 
func insert_data(message string) {
    stmtIns, err := DB.Prepare("INSERT INTO quotes (message) VALUES( ? )")
    log.Printf("Adding quote: %s", message)
    if err != nil {
        panic(err.Error())
    }
 
    _, err = stmtIns.Exec(message)
    if err != nil {
        panic(err.Error())
    }
    stmtIns.Close()
 
}
 
func get_all_quotes() []Quote {
    var id int
    var message string
    var quotes []Quote
    rows, err := DB.Query("SELECT id, message FROM quotes order by id asc")
    defer rows.Close()
    for rows.Next() {
        err = rows.Scan(&id, &message)
        if err != nil {
            log.Printf("Error: %v", err.Error())
        }
        quotes = append(quotes, Quote{ID: id, Message: message})
    }
    return quotes
}
 
func get_random_quote() Quote {
    var id int
    var message string
    err := DB.QueryRow("SELECT id, message FROM quotes order by RAND() LIMIT 1").Scan(&id, &message)
    if err != nil {
        log.Printf("Error: %v", err.Error())
    }
 
    log.Printf("Quote: %s", message)
    return Quote{ID: id, Message: message}
}