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