123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- package kyoketsu
- import (
- "database/sql"
- "errors"
- "github.com/mattn/go-sqlite3"
- )
- type TopologyDatabaseIO interface {
-
- Migrate() error
- Create(host Host) (*Host, error)
- All() ([]Host, error)
- GetByFqdn(dn string) (*Host, error)
- Update(id int64, updated Host) (*Host, error)
- Delete(id int64) error
- }
- var (
- ErrDuplicate = errors.New("record already exists")
- ErrNotExists = errors.New("row not exists")
- ErrUpdateFailed = errors.New("update failed")
- ErrDeleteFailed = errors.New("delete failed")
- )
- type SQLiteRepo struct {
- db *sql.DB
- }
- func NewSQLiteRepo(db *sql.DB) *SQLiteRepo {
- return &SQLiteRepo{
- db: db,
- }
- }
- func (r *SQLiteRepo) Migrate() error {
- query := `
- CREATE TABLE IF NOT EXISTS hosts(
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- fqdn TEXT NOT NULL,
- ipv4_address TEXT NOT NULL UNIQUE,
- listening_port TEXT NOT NULL
- );
- `
- _, err := r.db.Exec(query)
- return err
- }
- func (r *SQLiteRepo) Create(host Host) (*Host, error) {
- res, err := r.db.Exec("INSERT INTO hosts(fqdn, ipv4_address, listening_port) values(?,?,?)", host.Fqdn, host.IpAddress, host.PortString)
- if err != nil {
- var sqliteErr sqlite3.Error
- if errors.As(err, &sqliteErr) {
- if errors.Is(sqliteErr.ExtendedCode, sqlite3.ErrConstraintUnique) {
- return nil, ErrDuplicate
- }
- }
- return nil, err
- }
- id, err := res.LastInsertId()
- if err != nil {
- return nil, err
- }
- host.Id = id
- return &host, nil
- }
- func (r *SQLiteRepo) All() ([]Host, error) {
- rows, err := r.db.Query("SELECT * FROM hosts")
- if err != nil {
- return nil, err
- }
- defer rows.Close()
- var all []Host
- for rows.Next() {
- var host Host
- if err := rows.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString); err != nil {
- return nil, err
- }
- all = append(all, host)
- }
- return all, nil
- }
- func (r *SQLiteRepo) GetByFqdn(dn string) (*Host, error) {
- row := r.db.QueryRow("SELECT * FROM hosts WHERE fqdn = ?", dn)
- var host Host
- if err := row.Scan(&host.Id, &host.Fqdn, &host.IpAddress, &host.PortString); err != nil {
- if errors.Is(err, sql.ErrNoRows) {
- return nil, ErrNotExists
- }
- return nil, err
- }
- return &host, nil
- }
- func (r *SQLiteRepo) Update(id int64, updated Host) (*Host, error) {
- if id == 0 {
- return nil, errors.New("invalid updated ID")
- }
- res, err := r.db.Exec("UPDATE hosts SET name = ?, url = ?, rank = ? WHERE id = ?", updated.Fqdn, updated.IpAddress, updated.PortString, id)
- if err != nil {
- return nil, err
- }
- rowsAffected, err := res.RowsAffected()
- if err != nil {
- return nil, err
- }
- if rowsAffected == 0 {
- return nil, ErrUpdateFailed
- }
- return &updated, nil
- }
- func (r *SQLiteRepo) Delete(id int64) error {
- res, err := r.db.Exec("DELETE FROM hosts WHERE id = ?", id)
- if err != nil {
- return err
- }
- rowsAffected, err := res.RowsAffected()
- if err != nil {
- return err
- }
- if rowsAffected == 0 {
- return ErrDeleteFailed
- }
- return err
- }
|