package data import ( "bufio" "database/sql" "fmt" "os" "strings" "syscall" "streifling.com/jason/sicherheitsunterweisung/packages/types" "github.com/go-sql-driver/mysql" "golang.org/x/term" ) type DB struct { *sql.DB Name string } func getUsername() (string, error) { user := os.Getenv("DB_USER") if user == "" { var err error fmt.Printf("DB Benutzer: ") user, err = bufio.NewReader(os.Stdin).ReadString('\n') if err != nil { return "", fmt.Errorf("getUsername: bufio.NewReader(os.Stdin).ReadString('\n'): %v", err) } } return strings.TrimSpace(user), nil } func getPassword() (string, error) { pass := os.Getenv("DB_PASS") if pass == "" { fmt.Printf("DB Passwort: ") bytePass, err := term.ReadPassword(int(syscall.Stdin)) if err != nil { return "", fmt.Errorf("getCredentials: term.ReadPassword(int(syscall.Stdin)): %v", err) } fmt.Println() pass = strings.TrimSpace(string(bytePass)) } return pass, nil } func getCredentials() (string, string, error) { user, err := getUsername() if err != nil { return "", "", fmt.Errorf("getCredentials: getUsername(): %v", err) } pass, err := getPassword() if err != nil { return "", "", fmt.Errorf("getCredentials: getPassword(): %v", err) } return user, pass, nil } func reverseOrder(bs []*types.Briefing) { for i, j := 0, len(bs)-1; i < j; i, j = i+1, j-1 { bs[i], bs[j] = bs[j], bs[i] } } func OpenDB(dbName string) (*DB, error) { var err error db := new(DB) cfg := mysql.NewConfig() cfg.DBName = dbName cfg.User, cfg.Passwd, err = getCredentials() if err != nil { return nil, fmt.Errorf("Open: getCredentials(): %v\n", err) } db.Name = dbName db.DB, err = sql.Open("mysql", cfg.FormatDSN()) if err != nil { return nil, fmt.Errorf("Open: sql.Open(\"mysql\", cfg.FormatDSN()): %v\n", err) } if err := db.Ping(); err != nil { return nil, fmt.Errorf("Open: db.Ping(): %v\n", err) } return db, nil } func (db *DB) WriteBriefing(b *types.Briefing) error { for i := 0; i < len(b.Participants); i++ { result, err := db.Exec("INSERT INTO "+db.Name+" (instructor_first,"+ " instructor_last, date, time, state, location, participant_first,"+ " participant_last, company) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", b.FirstName, b.LastName, b.Date, b.Time, b.State, b.Location, b.Participants[i].FirstName, b.Participants[i].LastName, b.Participants[i].Company) if err != nil { return fmt.Errorf("*DB.WriteBriefing: db.Exec(\"INSERT INTO"+ " \"+db.Name+\" (instructor_first, instructor_last, date, time, state,"+ " location, participant_first, participant_last, company) VALUES (?, ?,"+ " ?, ?, ?, ?, ?, ?, ?)\", b.FirstName, b.LastName, b.Date, b.Time,"+ " b.State, b.Location, b.Participants[i].FirstName,"+ " b.Participants[i].LastName, b.Participants[i].Company): %v\n", err) } _, err = result.LastInsertId() if err != nil { return fmt.Errorf("*DB.WriteBriefing: result.LastInsertId(): %v\n", err) } } return nil } func (db *DB) GetAllOverviewTableData() (*[]*types.OverviewTableData, error) { rows, err := db.Query(` SELECT i.first_name, i.last_name, b.date, b.time, b.location, b.document_name, b.as_of, p.first_name, p.last_name, p.company FROM given_answers AS g INNER JOIN briefings AS b ON b.id = g.briefing_id INNER JOIN participants AS p ON p.id = g.participant_id INNER JOIN instructors AS i ON i.id = b.instructor_id ORDER BY b.id DESC, p.id`) if err != nil { return nil, fmt.Errorf("*DB.ReadAllBriefings: db.Query(): %v\n", err) } defer rows.Close() data := make([]*types.OverviewTableData, 0) for rows.Next() { otd := new(types.OverviewTableData) err := rows.Scan( &otd.InstructorFirstName, &otd.InstructorLastName, &otd.BriefingDate, &otd.BriefingTime, &otd.BriefingLocation, &otd.BriefingDocumentName, &otd.BriefingAsOf, &otd.ParticipantFirstName, &otd.ParticipantLastName, &otd.ParticipantCompany, ) if err != nil { return nil, fmt.Errorf("*DB.ReadAllBriefings: rows.Scan(): %v\n", err) } data = append(data, otd) } return &data, nil } func (db *DB) ReadByName(name string) ([]*types.Briefing, error) { bs := make([]*types.Briefing, 0) rows, err := db.Query("SELECT *"+ " FROM "+db.Name+ " WHERE instructor_first LIKE ?"+ " OR instructor_last LIKE ?"+ " OR participant_first LIKE ?"+ " OR participant_last LIKE ?", "%"+name+"%", "%"+name+"%", "%"+name+"%", "%"+name+"%") if err != nil { return nil, fmt.Errorf("*DB.ReadByName: db.Query(\"SELECT *"+ " FROM \"+db.Name+"+ " WHERE instructor_first LIKE ?"+ " OR instructor_last LIKE ?"+ " OR participant_first LIKE ?"+ " OR participant_last LIKE ?\"): %v\n", err) } defer rows.Close() for rows.Next() { b := new(types.Briefing) p := new(types.Participant) if err := rows.Scan(&p.ID, &b.FirstName, &b.LastName, &b.Date, &b.Time, &b.State, &b.Location, &p.FirstName, &p.LastName, &p.Company); err != nil { return nil, fmt.Errorf("*DB.ReadByName: rows.Scan(&p.ID, &b.FirstName,"+ " &b.LastName, &b.Date, &b.Time, &b.State, &b.Location, &p.FirstName,"+ " &p.LastName, &p.Company): %v\n", err) } b.Participants = append(b.Participants, p) bs = append(bs, b) } reverseOrder(bs) return bs, nil } func (db *DB) GetLastID(i *int64) error { row := db.QueryRow("SELECT id" + " FROM " + db.Name + " ORDER BY id DESC LIMIT 0, 1") if err := row.Scan(i); err != nil { return fmt.Errorf("*DB.GetLastID: row.Scan(&i): %v\n", err) } return nil }