Skip to content

Commit

Permalink
Create query repo
Browse files Browse the repository at this point in the history
  • Loading branch information
dkumiszhan committed Jul 22, 2023
1 parent bd2b7dc commit f6a19de
Show file tree
Hide file tree
Showing 3 changed files with 301 additions and 0 deletions.
9 changes: 9 additions & 0 deletions backend/entities/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package entities

type Query struct {
ID string `json:"id,omitempty"`
Content string `json:"content,omitempty"`
OwnerID string `json:"owner_id,omitempty"`
Active bool `json:"active,omitempty"`
Description string `json:"description,omitempty"`
}
142 changes: 142 additions & 0 deletions backend/repos/query.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package repos

import (
"errors"
"fmt"
"strings"

"github.com/google/uuid"
"github.com/honeynet/ochi/backend/entities"

"github.com/jmoiron/sqlx"
"github.com/jmoiron/sqlx/reflectx"
_ "github.com/mattn/go-sqlite3"
)

type QueryRepo struct {
findByOwnerQuery *sqlx.Stmt
deleteQuery *sqlx.Stmt
createQuery *sqlx.NamedStmt
updateQuery *sqlx.Stmt
getByIdQuery *sqlx.Stmt
db *sqlx.DB
}

func NewQueryRepo(db *sqlx.DB) (*QueryRepo, error) {
r := &QueryRepo{}
db.Mapper = reflectx.NewMapperFunc("json", strings.ToLower)
_, err := db.Exec(`CREATE TABLE IF NOT EXISTS queries (
id TEXT PRIMARY KEY NOT NULL
, content TEXT NOT NULL
, owner_id TEXT NOT NULL
, active INTEGER NOT NULL
, description TEXT NOT NULL
, CONSTRAINT id_unique UNIQUE (id)
)`)
if err != nil {
return nil, err
}
r.findByOwnerQuery, err = db.Preparex("SELECT * FROM queries WHERE owner_id=?")
if err != nil {
return nil, err
}
r.createQuery, err = db.PrepareNamed("INSERT INTO queries (id, owner_id, content, active, description) VALUES (:id, :owner_id, :content, :active, :description)")
if err != nil {
return nil, err
}
r.updateQuery, err = db.Preparex("UPDATE queries SET content=?, active=?, description=? WHERE id=?")
if err != nil {
return nil, err
}
r.getByIdQuery, err = db.Preparex("SELECT * FROM queries WHERE id=?")
if err != nil {
return nil, err
}
r.deleteQuery, err = db.Preparex("DELETE FROM queries WHERE id=?")
if err != nil {
return nil, err
}
return r, nil
}

// Get a user
func (r *QueryRepo) FindByOwnerId(ownerId string) ([]entities.Query, error) {
qs := []entities.Query{}
err := r.findByOwnerQuery.Select(&qs, ownerId)
return qs, err
}

// Create a query
func (r *QueryRepo) Create(owner_id, content, description string, active bool) (entities.Query, error) {
id, err := uuid.NewRandom()
if err != nil {
return entities.Query{}, err
}
q := entities.Query{ID: id.String(), Content: content, OwnerID: owner_id, Active: active, Description: description}
_, err = r.createQuery.Exec(&q)
if err != nil {
return entities.Query{}, err
}
return q, nil
}

// Update a query
func (r *QueryRepo) Update(id, content, description string, active bool) error {
res, err := r.updateQuery.Exec(content, active, description, id)
if err != nil {
return err
}
if cnt, err := res.RowsAffected(); err != nil {
return err
} else if cnt == 0 {
return errors.New(fmt.Sprintf("%s not found", id))
}
return nil
}

// GetByID
func (r *QueryRepo) GetByID(id string) (entities.Query, error) {
q := entities.Query{}
err := r.getByIdQuery.Get(&q, id)
return q, err
}

// Delete a query
func (r *QueryRepo) Delete(id string) error {
res, err := r.deleteQuery.Exec(id)
if err != nil {
return err
}
if cnt, err := res.RowsAffected(); err != nil {
return err
} else if cnt == 0 {
return errors.New(fmt.Sprintf("%s not found", id))
}
return nil
}

// // Find a user
// func (r *QueryRepo) Find(email string) (entities.User, error) {
// u := entities.User{Email: email}
// err := r.readEmail.Get(&u, email)
// if err == sql.ErrNoRows {
// var id uuid.UUID
// id, err = uuid.NewRandom()
// if err != nil {
// return u, err
// }
// u.ID = id.String()
// _, err = r.create.Exec(&u)
// if err != nil {
// return u, err
// }
// }
// return u, err
// }

// Close the db
func (r *QueryRepo) Close() {
if r.db != nil {
r.db.Close()
}
}
150 changes: 150 additions & 0 deletions backend/repos/query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package repos

import (
"fmt"
"testing"

"github.com/jmoiron/sqlx"
"github.com/stretchr/testify/require"
)

func TestQuery(t *testing.T) {
r := initRepo(t)
u1, err := r.FindByOwnerId("test@test")
require.NoError(t, err)
require.Empty(t, u1)

q, err := r.Create("123", "hello there", "this is desription", true)
require.NoError(t, err)
require.NotEmpty(t, q.ID)

u1, err = r.FindByOwnerId("123")
require.NoError(t, err)
require.Equal(t, len(u1), 1)

require.Equal(t, u1[0], q)

err = r.Delete("Not found")
require.Error(t, err)

err = r.Delete(q.ID)
require.NoError(t, err)

u1, err = r.FindByOwnerId("123")
require.NoError(t, err)
require.Empty(t, u1)
}

func TestGetById_Missing(t *testing.T) {
r := initRepo(t)

_, err := r.GetByID("non-existing")
require.ErrorContains(t, err, "sql: no rows in result set")
}

func TestGetById_Existing(t *testing.T) {
r := initRepo(t)
q, err := r.Create("001", "content", "description", true)
require.NoError(t, err)
require.Equal(t, "001", q.OwnerID)
require.Equal(t, "content", q.Content)
require.Equal(t, "description", q.Description)

q1, err := r.GetByID(q.ID)
require.NoError(t, err)
require.Equal(t, q, q1)
}

func TestFindByOwnerId_Missing(t *testing.T) {
r := initRepo(t)

qs, err := r.FindByOwnerId("non-existing")
require.NoError(t, err)
require.Empty(t, qs)
}

func TestFindByOwnerId_Existing(t *testing.T) {
r := initRepo(t)

q, err := r.Create("001", "content", "description", true)
require.NoError(t, err)
require.Equal(t, "001", q.OwnerID)
require.Equal(t, "content", q.Content)
require.Equal(t, "description", q.Description)

q1, err := r.Create("001", "content1", "description1", true)
require.NoError(t, err)
require.Equal(t, "001", q1.OwnerID)
require.Equal(t, "content1", q1.Content)
require.Equal(t, "description1", q1.Description)

q2, err := r.Create("001", "content2", "description2", true)
require.NoError(t, err)
require.Equal(t, "001", q2.OwnerID)
require.Equal(t, "content2", q2.Content)
require.Equal(t, "description2", q2.Description)

qs, err := r.FindByOwnerId("001")
require.NoError(t, err)
require.Contains(t, qs, q)
require.Contains(t, qs, q1)
require.Contains(t, qs, q2)
}

func TestDeleteQuery_Missing(t *testing.T) {
r := initRepo(t)

err := r.Delete("non-existing")
require.ErrorContains(t, err, "non-existing not found")
}

func TestDeleteQuery_Existing(t *testing.T) {
r := initRepo(t)

q, err := r.Create("001", "content", "description", true)
require.NoError(t, err)

err = r.Delete(q.ID)
require.NoError(t, err)

err = r.Delete(q.ID)
require.Error(t, err)

_, err = r.GetByID(q.ID)
require.Error(t, err)
}

func TestUpdateQuery_Missing(t *testing.T) {
r := initRepo(t)

err := r.Update("non-existing", "content", "description", true)
require.ErrorContains(t, err, "non-existing not found")
}

func TestUpdateQuery_Existing(t *testing.T) {
r := initRepo(t)

q, err := r.Create("001", "content", "description", true)
require.NoError(t, err)

err = r.Update(q.ID, "content-new", "description-new", false)
require.NoError(t, err)

q1, err := r.GetByID(q.ID)
require.Equal(t, "content-new", q1.Content)
require.Equal(t, "description-new", q1.Description)
require.Equal(t, false, q1.Active)
}

func initRepo(t *testing.T) *QueryRepo {
tmp := t.TempDir()
dbPath := fmt.Sprintf("%s/test.db", tmp)
db, err := sqlx.Connect("sqlite3", dbPath)
require.NoError(t, err)

// defer os.Remove("./querytest.db")
r, err := NewQueryRepo(db)
require.NoError(t, err)
require.NotNil(t, r)
return r
}

0 comments on commit f6a19de

Please sign in to comment.