package main import ( "database/sql" "log" "time" ) // Device : holds information about a specific Device type Device struct { ID int `json:"id"` Name string `json:"name"` DeviceTypeID int `json:"deviceTypeId"` DeviceType DeviceType `json:"deviceType"` Address string `json:"address"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } // Devices : a list of Device items type Devices []Device const deviceTableCreationQuery = `CREATE TABLE IF NOT EXISTS devices ( id int(10) unsigned NOT NULL AUTO_INCREMENT, name varchar(255), deviceTypeId int(10) unsigned NOT NULL, address varchar(255), createdAt datetime, updatedAt datetime, PRIMARY KEY (id), CONSTRAINT fk_devicetype FOREIGN KEY (deviceTypeId) REFERENCES deviceTypes(id) );` func ensureDeviceTableExists(db *sql.DB) { if _, err := db.Exec(deviceTableCreationQuery); err != nil { log.Fatal(err) } } func seedDeviceData(db *sql.DB) { sqlQuery := `INSERT INTO devices VALUES (1,'Default PLC',1,'192.168.1.10','2016-10-13 15:05:32','2016-10-13 15:05:32');` insStmt, insErr := db.Prepare(sqlQuery) if insErr != nil { panic(insErr.Error()) // proper error handling instead of panic in your app } defer insStmt.Close() // Close the statement when we leave main() / the program terminates insStmt.Exec() } // getDevice : used during GET command func (d *Device) getDevice(db *sql.DB) error { sqlQuery := `SELECT devices.name, devices.deviceTypeId, deviceTypes.id, deviceTypes.name, deviceTypes.createdAt, deviceTypes.updatedAt, devices.address, devices.createdAt, devices.updatedAt FROM devices LEFT JOIN deviceTypes ON devices.deviceTypeId = deviceTypes.id WHERE devices.id=?` return db.QueryRow(sqlQuery, d.ID).Scan(&d.Name, &d.DeviceTypeID, &d.DeviceType.ID, &d.DeviceType.Name, &d.DeviceType.CreatedAt, &d.DeviceType.UpdatedAt, &d.Address, &d.CreatedAt, &d.UpdatedAt) } // updateDevice : used during PUT command func (d *Device) updateDevice(db *sql.DB) error { updStmt, updErr := db.Prepare("UPDATE devices SET name=?, deviceTypeId=?, address=?, updatedAt=? WHERE id=?") if updErr != nil { panic(updErr.Error()) // proper error handling instead of panic in your app } defer updStmt.Close() // Close the statement when we leave main() / the program terminates _, err := updStmt.Exec(d.Name, d.DeviceTypeID, d.Address, time.Now(), d.ID) return err } // deleteDevice : used during DELETE command func (d *Device) deleteDevice(db *sql.DB) error { _, err := db.Exec("DELETE FROM devices WHERE id=?", d.ID) return err } // createDevice : used during PUSH command func (d *Device) createDevice(db *sql.DB) error { stmtIns, insErr := db.Prepare("INSERT INTO devices (name, deviceTypeId, address, createdAt, updatedAt) VALUES (?, ?, ?, ?, ?);") if insErr != nil { panic(insErr.Error()) // proper error handling instead of panic in your app } defer stmtIns.Close() // Close the statement when we leave main() / the program terminates _, err := stmtIns.Exec(d.Name, d.DeviceTypeID, d.Address, time.Now(), time.Now()) return err } // getDevices : used during GET command for all func getDevices(db *sql.DB, start, count int) (Devices, error) { sqlQuery := `SELECT devices.id, devices.name, devices.deviceTypeId, deviceTypes.id, deviceTypes.name, deviceTypes.createdAt, deviceTypes.updatedAt, devices.address, devices.createdAt, devices.updatedAt FROM devices LEFT JOIN deviceTypes ON devices.deviceTypeId = deviceTypes.id LIMIT ? OFFSET ?;` getStmt, prepErr := db.Prepare(sqlQuery) if prepErr != nil { panic(prepErr.Error()) // proper error handling instead of panic in your app } defer getStmt.Close() // Close the statement when we leave main() / the program terminates rows, err := getStmt.Query(count, start) if err != nil { return nil, err } defer rows.Close() devices := Devices{} for rows.Next() { var d Device if err := rows.Scan(&d.ID, &d.Name, &d.DeviceTypeID, &d.DeviceType.ID, &d.DeviceType.Name, &d.DeviceType.CreatedAt, &d.DeviceType.UpdatedAt, &d.Address, &d.CreatedAt, &d.UpdatedAt); err != nil { return nil, err } devices = append(devices, d) } return devices, nil }