// Package kurzd contains the Kurz daemon command. package main import ( "fmt" "gopkg.in/yaml.v2" "os" "time" "database/sql" _ "github.com/go-sql-driver/mysql" ) /** kurzd -v Verbose (default: false). help Display help. server Serve kurz (default option). -p|--port Serve on this IP port (default: 80). -m|--monitoring Serve monitoring on this IP port (default: none) install Install kurzd completely. config Install the configuration define by command line to ~. schema Install the kurz database schema. export Export kurzd data. -o Specify a destination file. config Export kurz configuration. content Export kurz content. uninstall Uninstall kurzd completely. config Uninstall the curz configuration file from ~. schema Uninstall the curz database schema. status Report on kurzd status stop Stop all instances of kurzd on the current server (restricted) */ func main() { command, subCommand, options, err := parseCommand() if err != nil { panic(err.Error()) } switch command { case "export": switch subCommand { case "content": dbDriver, dbDsn := parseDbCred(options) db, err := dbDial(dbDriver, dbDsn) if err != nil { panic("Could not open database") } defer db.Close() entries, err := exportContent(db) if err != nil { panic(err.Error()) } y, err := yaml.Marshal(&entries) if err != nil { panic(err.Error()) } fmt.Println(string(y)) } } } type stringMap map[string]string type MapEntry struct { Hash uint64 Url string Date1, Date2, Date3 time.Time RefCount uint32 } func dbDial(dbDriver, dbDsn string) (*sql.DB, error) { db, err := sql.Open(dbDriver, dbDsn) if err != nil { return nil, err } return db, nil } func parseDbCred(_ stringMap) (driver, dsn string) { const DefaultDriver = "mysql" const DefaultDsn = "root:root@tcp(localhost:3306)/kurz" envDriver := os.Getenv("DB_DRIVER") if envDriver == "" { envDriver = DefaultDriver } envDsn := os.Getenv("DB_DSN") if envDsn == "" { envDsn = DefaultDsn } envDsn += "?parseTime=true" return envDriver, envDsn } /* parseCommand returns a valid command/subCommand/options triplet and nil, or an error, in which case the values for the other results are not defined. */ func parseCommand() (command, subCommand string, options stringMap, err error) { return "export", "content", stringMap{}, nil } func exportContent(db *sql.DB) ([]MapEntry, error) { stmt, err := db.Prepare(` SELECT Hash, url, Date1, Date2, Date3, RefCount FROM map ORDER BY url`) if err != nil { panic(err.Error()) } defer stmt.Close() rows, err := stmt.Query() if err != nil { return nil, err } defer rows.Close() entry := MapEntry{} var entries []MapEntry for rows.Next() { err = rows.Scan(&entry.Hash, &entry.Url, &entry.Date1, &entry.Date2, &entry.Date3, &entry.RefCount) if err != nil { return nil, err } entries = append(entries, entry) } return entries, nil }