commit 43c5ef6548fb08a89c4e4205d554231f311b4844 Author: Julian Daube Date: Wed Mar 8 20:15:10 2017 +0100 initial commit diff --git a/cmd/importPunkte/main.go b/cmd/importPunkte/main.go new file mode 100644 index 0000000..a6fbe41 --- /dev/null +++ b/cmd/importPunkte/main.go @@ -0,0 +1,141 @@ +package main + +import ( + "bufio" + "database/sql" + "encoding/csv" + "flag" + "fmt" + "log" + "os" + "strconv" + "strings" + + _ "github.com/go-sql-driver/mysql" +) + +var ( + dbURL = flag.String("db", "julian:hi@/test", "The Database") +) + +const ( + queryInsert = "INSERT INTO Punkte (Matrnr, Aufgabe, Punkte) VALUES(?,?,?)" +) + +// This function assumes it input to be only one float +func convertFloat(input string) string { + // replace all , with . + return strings.Replace(input, ",", ".", -1) +} + +func YesNo() bool { + reader := bufio.NewReader(os.Stdin) + for { + line, _, err := reader.ReadLine() + if err != nil { + return false + } + + // default case + if len(line) == 0 { + return true + } + + switch line[0] { + case 'Y': + fallthrough + case 'y': + return true + case 'N': + fallthrough + case 'n': + return false + } + } +} + +func main() { + flag.Parse() + + files := flag.Args() + if len(files) == 0 { + log.Fatal("no files given!") + } + + db, err := sql.Open("mysql", *dbURL) + if err != nil { + log.Fatal("error connecting to Database:", err) + } + defer db.Close() + + for _, f := range files { + log.Println("importing", f) + file, err := os.Open(f) + if err != nil { + log.Println("could not open file:", f+":", err) + continue + } + + reader := csv.NewReader(file) + transaction, err := db.Begin() + if err != nil { + log.Fatal("cannot prepare statement:", err) + } + + stmt, err := transaction.Prepare(queryInsert) + if err != nil { + log.Fatal("could not prepare insert statement:", err) + } + defer stmt.Close() + + var ( + line []string + count = 0 + linecount = 0 + + ID int + Aufgabe = 1 + points float64 + ) + + for { + linecount++ + line, err = reader.Read() + if err != nil || line == nil { + break + } + + if len(line) < 2 { + log.Println(linecount, ": malformed line") + continue + } + + if ID, err = strconv.Atoi(line[0]); err != nil { + log.Println(linecount, ": no ID given, could not convert:", err) + continue + } + + fmt.Print(ID, " ") + + Aufgabe = 1 + for _, p := range line[1:] { + if points, err = strconv.ParseFloat(convertFloat(p), 32); err != nil { + log.Println(linecount, "A", Aufgabe, ": could not parse points:", err) + } + fmt.Print(points, " ") + + if _, err = stmt.Exec(ID, Aufgabe, points); err != nil { + log.Println(linecount, ": error inserting:", err) + } + Aufgabe++ + } + fmt.Println() + count++ + } + fmt.Println("read", count, "Students") + fmt.Println("commit changes? (Y/n)") + if YesNo() { + transaction.Commit() + } + } +} diff --git a/cmd/importTeilnehmer/main.go b/cmd/importTeilnehmer/main.go new file mode 100644 index 0000000..ec14115 --- /dev/null +++ b/cmd/importTeilnehmer/main.go @@ -0,0 +1,111 @@ +package main + +import ( + "database/sql" + "encoding/csv" + "flag" + "log" + "os" + "strconv" + + _ "github.com/go-sql-driver/mysql" +) + +// Student from Database +type Student struct { + Vorname, Nachname string + Matrikelnummer int + StudiengangID int +} + +var ( + databaseURL = flag.String("db", "julian:hi@/test", "The Database url") +) + +const ( + insertQuery = "INSERT INTO Teilnehmer (Nachname, Vorname, Matrnr, Studiengang) VALUES(?,?,?,?)" +) + +// Main Function +func main() { + flag.Parse() + + if flag.NArg() == 0 { + log.Fatal("no file(s) given!") + } + + // try to open file + file, err := os.Open(flag.Arg(0)) + if err != nil { + log.Fatal("could not open file:", err) + } + defer file.Close() + + reader := csv.NewReader(file) + + defer log.Println("shutdown completed") + // list all Database providers + log.Println("Database providers:", sql.Drivers()) + + // connect to database + db, err := sql.Open("mysql", *databaseURL) + + if err != nil { + log.Fatal(err) + } + defer db.Close() + log.Println("mysql connection established") + // prepare Queries + newStudent, err := db.Prepare(insertQuery) + if err != nil { + log.Fatal("Error preparing statement:", insertQuery+":", err) + } + + defer newStudent.Close() + + // init completed + defer log.Println("shutting down") + + var ( + line []string + linenumber = 0 + count = 0 + ) + + for ; err == nil; line, err = reader.Read() { + linenumber++ + if len(line) < 4 { + log.Println("line", linenumber, "malformed") + continue + } + + number, err := strconv.Atoi(line[2]) + if err != nil { + log.Println("line", linenumber, ":could not convert ID:"+line[2]+":", err) + continue + } + if number < 0 { + log.Println("line", linenumber, ":ID invalid:", number) + continue + } + + studiengang, err := strconv.Atoi(line[3]) + if err != nil { + log.Println("line", linenumber, ":studiengang could not be converted:", err) + continue + } + if studiengang < 0 || studiengang > 2 { + log.Println("line", linenumber, ":Studiengang does not exist:", studiengang) + continue + } + + if _, err := newStudent.Exec(line[0], line[1], number, studiengang); err != nil { + log.Println("line", linenumber, ":could not execute INSERT:", err) + continue + } + + count++ + } + + log.Println("done, inserted", count, "records") +} diff --git a/cmd/list/main.go b/cmd/list/main.go new file mode 100644 index 0000000..052b62c --- /dev/null +++ b/cmd/list/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "database/sql" + "flag" + "fmt" + "log" + + "encoding/json" + + _ "github.com/go-sql-driver/mysql" +) + +var ( + dbURL = flag.String("db", "julian:hi@/test", "The Database") +) + +func main() { + flag.Parse() + + db, err := sql.Open("mysql", *dbURL) + if err != nil { + log.Fatal(err) + } + if err = readStudiengaenge(db); err != nil { + log.Fatal("readStudiengaenge:", err) + } + + result, err := db.Query("SELECT Vorname, Nachname, Matrnr, Studiengang FROM Teilnehmer") + if err != nil { + log.Fatal("error fetching students:", err) + } + + var ( + stud Student + ID int + ) + + for result.Next() { + if err = result.Scan(&stud.Vorname, &stud.Nachname, &stud.Matrnr, &ID); err != nil { + log.Println("could not retrieve Student:", err) + continue + } + + name, ok := studiengaenge[ID] + if !ok { + log.Println("illegal Studiengang:", ID) + continue + } + + stud.Studiengang = name + + out, err := json.Marshal(stud) + if err != nil { + log.Fatal("could not marshal to json:", err) + } + fmt.Println(string(out)) + } +} diff --git a/cmd/list/studenten.go b/cmd/list/studenten.go new file mode 100644 index 0000000..9cbfc22 --- /dev/null +++ b/cmd/list/studenten.go @@ -0,0 +1,17 @@ +package main + +import ( + "strconv" +) + +// Ein Student +type Student struct { + Vorname, Nachname string + Matrnr int + Studiengang Studiengang +} + +// Gibt den Studenten als String zurück +func (s Student) String() string { + return "{" + strconv.Itoa(s.Matrnr) + " " + s.Nachname + ", " + s.Vorname + " \"" + *s.Studiengang + "\"}" +} diff --git a/cmd/list/studiengang.go b/cmd/list/studiengang.go new file mode 100644 index 0000000..d81635c --- /dev/null +++ b/cmd/list/studiengang.go @@ -0,0 +1,32 @@ +package main + +import "database/sql" + +// Ein Studiengang +type Studiengang *string + +// globale Tabelle aller Studiengänge +var studiengaenge map[int]Studiengang + +// lese alle Studiengänge aus der mysql Tabelle +func readStudiengaenge(db *sql.DB) error { + studiengaenge = make(map[int]Studiengang) + result, err := db.Query("SELECT ID, Studiengaenge.Name FROM Studiengaenge") + if err != nil { + return err + } + + var ( + ID int + stud string + ) + + for result.Next() { + if err = result.Scan(&ID, &stud); err != nil { + return err + } + studiengaenge[ID] = Studiengang(&stud) + } + + return nil +} diff --git a/cmd/stripColumns/main.go b/cmd/stripColumns/main.go new file mode 100644 index 0000000..a950d1a --- /dev/null +++ b/cmd/stripColumns/main.go @@ -0,0 +1,83 @@ +package main + +import ( + "database/sql" + "flag" + "log" + + _ "github.com/go-sql-driver/mysql" +) + +var ( + dbURL = flag.String("db", "julian:hi@/test", "Die URL zur Datenbank") + table = flag.String("table", "Teilnehmer", "Die Tabelle") + key = flag.String("key", "Matrnr", "Der Tabellenschlüsselname") + attr = flag.String("attr", "Nachname", "Die Spalte zum Cleanen") +) + +const ( + querySelect = "SELECT ?,? FROM ?" + queryUpdate = "UPDATE ? SET ?=? WHERE ?=?" +) + +func main() { + flag.Parse() + + db, err := sql.Open("mysql", *dbURL) + if err != nil { + log.Fatal("error connecting to database:", err) + } + defer db.Close() + + statement, err := db.Prepare("SELECT " + *key + "," + *attr + " FROM " + *table) + + if err != nil { + log.Fatal("error in precompiled statement:", querySelect+":", err) + } + defer statement.Close() + + rows, err := statement.Query() + + if err != nil { + log.Fatal("error executing query:", err) + } + + context, err := db.Begin() + if err != nil { + log.Fatal("error creating context:", err) + } + + update, err := context.Prepare("UPDATE " + *table + " SET " + *attr + "=? WHERE " + *key + "=?") + if err != nil { + log.Fatal("error in precompiled statement:", queryUpdate+":", err) + } + + var ( + keyBuffer int + dirty, clean string + + count int + ) + + for rows.Next() { + if err = rows.Scan(&keyBuffer, &dirty); err != nil { + log.Println("error while reading:", err) + } + + clean = strip(dirty) + if clean != dirty { + if result, err := update.Exec(clean, keyBuffer); err != nil { + log.Fatal("error on update, change canceled:", err) + } else if i, err := result.RowsAffected(); err == nil && i != 1 { + log.Fatal("changed to many rows... aborting") + } else { + count++ + } + } + } + + log.Println("committing change,", count, "rows affected") + if err := context.Commit(); err != nil { + log.Println("could not commit changed:", err) + } +} diff --git a/cmd/stripColumns/strip.go b/cmd/stripColumns/strip.go new file mode 100644 index 0000000..6e778ca --- /dev/null +++ b/cmd/stripColumns/strip.go @@ -0,0 +1,15 @@ +package main + +func strip(str string) (output string) { + var ( + start = 0 + end = len(str) + ) + for ; start < len(str) && str[start] == ' '; start++ { + } + + for ; end > 0 && str[end-1] == ' '; end-- { + } + + return str[start:end] +}