Paket data zu db umbenannt, den type Question zur SQL-Abfrage hinzugefügt, um Duplikate zu vermeiden und db.OpenDB() zu db.Open() umbenannt
This commit is contained in:
		
							
								
								
									
										313
									
								
								packages/db/db.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								packages/db/db.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,313 @@
 | 
			
		||||
package db
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"database/sql"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/go-sql-driver/mysql"
 | 
			
		||||
	"golang.org/x/term"
 | 
			
		||||
	"streifling.com/jason/sicherheitsunterweisung/packages/types"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
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 Open(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 {
 | 
			
		||||
	result, err := db.Exec(`
 | 
			
		||||
  INSERT INTO briefings
 | 
			
		||||
  	(date, time, location, document_name, as_of, instructor_id)
 | 
			
		||||
  VALUES
 | 
			
		||||
  	(?, ?, ?, ?, ?, ?)
 | 
			
		||||
  `, b.Date, b.Time, b.Location, b.DocumentName, b.AsOf, b.InstructorID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("*DB.writeBriefing: db.Exec(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	b.ID, err = result.LastInsertId()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("*DB.writeBriefing: result.LastInsertId(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (db *DB) WriteParticipant(p *types.Participant) error {
 | 
			
		||||
	result, err := db.Exec(`
 | 
			
		||||
  INSERT INTO participants
 | 
			
		||||
  	(first_name, last_name, company)
 | 
			
		||||
  VALUES
 | 
			
		||||
  	(?, ?, ?)
 | 
			
		||||
  `, p.FirstName, p.LastName, p.Company)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("*DB.writeParticipants: db.Exec(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	p.ID, err = result.LastInsertId()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("*DB.writeParticipants: result.LastInsertId(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (db *DB) WriteGivenAnswer(b *types.Briefing, p *types.Participant, q *types.Question, g *types.GivenAnswer) error {
 | 
			
		||||
	_, err := db.Exec(`
 | 
			
		||||
  INSERT INTO given_answers
 | 
			
		||||
  	(briefing_id, participant_id, question_id, given_answer)
 | 
			
		||||
  VALUES
 | 
			
		||||
  	(?, ?, ?, ?)
 | 
			
		||||
  `, b.ID, p.ID, q.ID, g)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("*DB.writeGivenAnswers: db.Exec(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (db *DB) WriteAllDataOfBriefing(b *types.Briefing, sp *[]*types.Participant, sq *[]*types.Question, sg *[]*types.GivenAnswer) error {
 | 
			
		||||
	if err := db.WriteBriefing(b); err != nil {
 | 
			
		||||
		return fmt.Errorf("*DB.WriteAllDataOfBriefing: db.writeBriefing(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, p := range *sp {
 | 
			
		||||
		if err := db.WriteParticipant(p); err != nil {
 | 
			
		||||
			return fmt.Errorf("*DB.WriteAllDataOfBriefing: db.writeParticipants(): %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, p := range *sp {
 | 
			
		||||
		for i, q := range *sq {
 | 
			
		||||
			db.WriteGivenAnswer(b, p, q, (*sg)[i])
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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 questions AS q
 | 
			
		||||
      ON q.id = g.question_id
 | 
			
		||||
    INNER JOIN instructors AS i
 | 
			
		||||
      ON i.id = b.instructor_id
 | 
			
		||||
  WHERE
 | 
			
		||||
    q.id = 1
 | 
			
		||||
  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) GetOverviewTableDataByName(n string) (*[]*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
 | 
			
		||||
  WHERE
 | 
			
		||||
    q.id = 1 AND
 | 
			
		||||
    i.first_name LIKE ? OR
 | 
			
		||||
    i.last_name LIKE ? OR
 | 
			
		||||
    p.first_name LIKE ? OR
 | 
			
		||||
    p.last_name LIKE ?
 | 
			
		||||
  ORDER BY
 | 
			
		||||
    b.id DESC,
 | 
			
		||||
    p.id
 | 
			
		||||
  `, "%"+n+"%", "%"+n+"%", "%"+n+"%", "%"+n+"%")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("*DB.GetOverviewTableDataByName: 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) GetLastID(table string) (int, error) {
 | 
			
		||||
	var id int
 | 
			
		||||
 | 
			
		||||
	row := db.QueryRow(`
 | 
			
		||||
  SELECT id
 | 
			
		||||
  FROM ?
 | 
			
		||||
  ORDER BY id DESC
 | 
			
		||||
    LIMIT 0, 1
 | 
			
		||||
  `, table)
 | 
			
		||||
 | 
			
		||||
	if err := row.Scan(&id); err != nil {
 | 
			
		||||
		return -1, fmt.Errorf("*DB.GetLastID: row.Scan(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return id, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (db *DB) GetInstructors() (*[]*types.Instructor, error) {
 | 
			
		||||
	rows, err := db.Query(`
 | 
			
		||||
  SELECT *
 | 
			
		||||
  FROM instructors
 | 
			
		||||
  `)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, fmt.Errorf("*DB.GetInstructors: db.Query(): %v\n", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	instructors := make([]*types.Instructor, 0)
 | 
			
		||||
	for rows.Next() {
 | 
			
		||||
		instructor := new(types.Instructor)
 | 
			
		||||
		if err = rows.Scan(instructor); err != nil {
 | 
			
		||||
			return nil, fmt.Errorf("*DB.GetInstructors: rows.Scan(): %v\n", err)
 | 
			
		||||
		}
 | 
			
		||||
		instructors = append(instructors, instructor)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return &instructors, nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user