Tasks/db/tasks.go

293 lines
8.3 KiB
Go
Raw Normal View History

2015-11-13 14:34:42 +05:30
package db
2016-02-01 20:04:19 +05:30
/*
Stores the database functions related to tasks like
GetTaskByID(id int)
GetTasks(status string)
DeleteAll()
*/
2015-11-13 14:34:42 +05:30
import (
"database/sql"
2016-01-31 19:52:00 +05:30
"log"
"strings"
"time"
2016-02-01 19:15:04 +05:30
_ "github.com/mattn/go-sqlite3" //we want to use sqlite natively
md "github.com/shurcooL/github_flavored_markdown"
"github.com/thewhitetulip/Tasks/types"
2015-11-13 14:34:42 +05:30
)
var database Database
2015-11-13 14:34:42 +05:30
var err error
//Database encapsulates database
type Database struct {
db *sql.DB
}
func (db Database) begin() (tx *sql.Tx) {
tx, err := db.db.Begin()
if err != nil {
log.Println(err)
2016-02-01 19:15:04 +05:30
return nil
}
return tx
}
func (db Database) prepare(q string) (stmt *sql.Stmt) {
stmt, err := db.db.Prepare(q)
if err != nil {
log.Println(err)
2016-02-01 19:15:04 +05:30
return nil
}
return stmt
}
func (db Database) query(q string, args ...interface{}) (rows *sql.Rows) {
2016-01-31 15:00:31 +01:00
rows, err := db.db.Query(q, args...)
if err != nil {
log.Println(err)
2016-02-01 19:15:04 +05:30
return nil
}
return rows
}
2015-11-13 14:34:42 +05:30
func init() {
database.db, err = sql.Open("sqlite3", "./tasks.db")
2015-11-13 14:34:42 +05:30
if err != nil {
2016-02-01 19:15:04 +05:30
log.Fatal(err)
2015-11-13 14:34:42 +05:30
}
}
2015-11-21 12:09:15 +05:30
//Close function closes this database connection
2015-11-13 14:34:42 +05:30
func Close() {
database.db.Close()
2015-11-13 14:34:42 +05:30
}
2015-11-21 12:09:15 +05:30
//GetTasks retrieves all the tasks depending on the
//status pending or trashed or completed
2016-02-02 23:10:44 +05:30
func GetTasks(status, category string) (types.Context, error) {
var tasks []types.Task
var task types.Task
var TaskCreated time.Time
var context types.Context
2015-11-13 14:34:42 +05:30
var getTasksql string
2016-02-02 23:10:44 +05:30
var rows *sql.Rows
2015-11-21 18:50:51 +05:30
comments := GetComments()
2016-02-02 23:10:44 +05:30
basicSQL := "select id, title, content, created_date, priority from task t"
if status == "pending" && category == "" {
getTasksql = basicSQL + " where finish_date is null and is_deleted='N' order by priority desc, created_date asc"
2015-11-21 18:50:51 +05:30
} else if status == "deleted" {
getTasksql = basicSQL + " where is_deleted='Y' order by priority desc, created_date asc"
2015-11-21 18:50:51 +05:30
} else if status == "completed" {
getTasksql = basicSQL + " where finish_date is not null order by priority desc, created_date asc"
2015-11-13 14:34:42 +05:30
}
2016-02-02 23:10:44 +05:30
if category != "" {
status = category
getTasksql = "select t.id, title, content, created_date, priority from task t, category c where c.id = t.cat_id and name = ? and t.is_deleted!='Y' and t.finish_date is null order by priority desc, created_date asc, finish_date asc"
2016-02-02 23:10:44 +05:30
rows, err = database.db.Query(getTasksql, category)
if err != nil {
log.Println("something went wrong while getting query")
}
} else {
rows = database.query(getTasksql)
}
2015-11-13 14:34:42 +05:30
defer rows.Close()
2015-11-13 18:41:30 +05:30
for rows.Next() {
task = types.Task{}
err := rows.Scan(&task.Id, &task.Title, &task.Content, &TaskCreated, &task.Priority)
task.Content = string(md.Markdown([]byte(task.Content)))
// TaskContent = strings.Replace(TaskContent, "\n", "<br>", -1)
2015-11-13 18:41:30 +05:30
if err != nil {
log.Println(err)
2015-11-13 14:34:42 +05:30
}
if comments[task.Id] != nil {
task.Comments = comments[task.Id]
}
TaskCreated = TaskCreated.Local()
task.Created = TaskCreated.Format(time.UnixDate)[0:20]
tasks = append(tasks, task)
2015-11-13 14:34:42 +05:30
}
context = types.Context{Tasks: tasks, Navigation: status}
2016-02-01 19:15:04 +05:30
return context, nil
2015-11-13 14:34:42 +05:30
}
2015-11-22 09:21:29 +05:30
//GetTaskByID function gets the tasks from the ID passed to the function, used to populate EditTask
2016-02-01 19:15:04 +05:30
func GetTaskByID(id int) (types.Context, error) {
2015-11-22 08:29:39 +05:30
var tasks []types.Task
2015-11-13 14:34:42 +05:30
var task types.Task
2016-01-23 19:17:34 +05:30
2016-02-05 00:06:00 +05:30
getTasksql := "select t.id, t.title, t.content, t.priority, c.name from task t left outer join category c where c.id = t.cat_id and t.id=?"
rows := database.query(getTasksql, id)
2015-11-13 14:34:42 +05:30
defer rows.Close()
2015-11-13 18:41:30 +05:30
if rows.Next() {
2016-02-05 00:06:00 +05:30
err := rows.Scan(&task.Id, &task.Title, &task.Content, &task.Priority, &task.Category)
2015-11-13 18:41:30 +05:30
if err != nil {
log.Println(err)
//send email to respective people
2015-11-13 14:34:42 +05:30
}
}
2015-11-22 08:29:39 +05:30
tasks = append(tasks, task)
context := types.Context{Tasks: tasks, Navigation: "edit"}
2016-02-01 19:15:04 +05:30
return context, nil
2015-11-13 14:34:42 +05:30
}
2015-11-21 12:09:15 +05:30
//TrashTask is used to delete the task
2015-11-14 16:26:53 +05:30
func TrashTask(id int) error {
err := taskQuery("update task set is_deleted='Y',last_modified_at=datetime() where id=?", id)
2015-11-14 16:26:53 +05:30
return err
}
2015-11-21 12:09:15 +05:30
//CompleteTask is used to mark tasks as complete
2015-11-14 16:26:53 +05:30
func CompleteTask(id int) error {
err := taskQuery("update task set is_deleted='Y', finish_date=datetime(),last_modified_at=datetime() where id=?", id)
2015-11-13 14:34:42 +05:30
return err
}
2015-11-21 12:09:15 +05:30
//DeleteAll is used to empty the trash
2015-11-13 14:34:42 +05:30
func DeleteAll() error {
err := taskQuery("delete from task where is_deleted='Y'")
2015-11-13 14:34:42 +05:30
return err
}
2015-11-21 12:09:15 +05:30
//RestoreTask is used to restore tasks from the Trash
2015-11-13 14:34:42 +05:30
func RestoreTask(id int) error {
err := taskQuery("update task set is_deleted='N',last_modified_at=datetime() where id=?", id)
return err
}
//RestoreTaskFromComplete is used to restore tasks from the Trash
func RestoreTaskFromComplete(id int) error {
err := taskQuery("update task set finish_date=null,last_modified_at=datetime() where id=?", id)
2016-01-09 10:33:35 +05:30
return err
}
2015-11-21 12:09:15 +05:30
//DeleteTask is used to delete the task from the database
2015-11-13 14:34:42 +05:30
func DeleteTask(id int) error {
err := taskQuery("delete from task where id = ?", id)
2015-11-13 14:34:42 +05:30
return err
}
2015-11-21 12:09:15 +05:30
//AddTask is used to add the task in the database
2016-02-02 23:10:44 +05:30
func AddTask(title, content, category string, taskPriority int) error {
var err error
if category == "" {
err = taskQuery("insert into task(title, content, priority, created_date, last_modified_at) values(?,?,?,datetime(), datetime())", title, content, taskPriority)
} else {
2016-02-06 12:28:00 +05:30
categoryID := GetCategoryByName(category)
2016-02-02 23:10:44 +05:30
err = taskQuery("insert into task(title, content, priority, created_date, last_modified_at, cat_id) values(?,?,?,datetime(), datetime(), ?)", title, content, taskPriority, categoryID)
}
2015-11-13 14:34:42 +05:30
return err
}
2016-02-05 23:39:09 +05:30
//GetCategoryIdByName will return the category ID for the category, used in the edit task
//function where we need to be able to update the categoryID of the task
func GetCategoryIdByName(category string) int {
var categoryID int
getTasksql := "select id from category where name=?"
rows := database.query(getTasksql, category)
defer rows.Close()
if rows.Next() {
err := rows.Scan(&categoryID)
if err != nil {
log.Println(err)
//send email to respective people
}
}
return categoryID
}
2015-11-21 12:09:15 +05:30
//UpdateTask is used to update the tasks in the database
2016-02-06 01:37:45 +05:30
func UpdateTask(id int, title, content, category string, priority int) error {
2016-02-05 23:39:09 +05:30
categoryID := GetCategoryIdByName(category)
2016-02-06 01:37:45 +05:30
err := taskQuery("update task set title=?, content=?, cat_id=?, priority = ? where id=?", title, content, categoryID, priority, id)
return err
}
2016-01-31 19:52:00 +05:30
//taskQuery encapsulates running multiple queries which don't do much things
func taskQuery(sql string, args ...interface{}) error {
2016-01-31 19:40:15 +05:30
SQL := database.prepare(sql)
tx := database.begin()
2016-01-31 15:00:31 +01:00
_, err = tx.Stmt(SQL).Exec(args...)
2015-11-13 18:41:30 +05:30
if err != nil {
log.Println(err)
2015-11-13 14:34:42 +05:30
tx.Rollback()
} else {
2016-01-31 19:52:00 +05:30
tx.Commit()
2015-11-13 14:34:42 +05:30
}
return err
}
2015-11-21 12:09:15 +05:30
//SearchTask is used to return the search results depending on the query
2015-11-21 19:42:20 +05:30
func SearchTask(query string) types.Context {
2015-11-21 16:33:34 +05:30
stmt := "select id, title, content, created_date from task where title like '%" + query + "%' or content like '%" + query + "%'"
2015-11-13 14:34:42 +05:30
var task []types.Task
2015-11-21 12:09:15 +05:30
var TaskID int
2015-11-13 14:34:42 +05:30
var TaskTitle string
var TaskContent string
2015-11-21 16:33:34 +05:30
var TaskCreated time.Time
2015-11-21 19:42:20 +05:30
var context types.Context
2015-11-13 14:34:42 +05:30
rows := database.query(stmt, query, query)
2015-11-13 18:41:30 +05:30
for rows.Next() {
2015-11-21 16:33:34 +05:30
err := rows.Scan(&TaskID, &TaskTitle, &TaskContent, &TaskCreated)
2015-11-13 18:41:30 +05:30
if err != nil {
log.Println(err)
2015-11-13 14:34:42 +05:30
}
TaskTitle = strings.Replace(TaskTitle, query, "<span class='highlight'>"+query+"</span>", -1)
TaskContent = strings.Replace(TaskContent, query, "<span class='highlight'>"+query+"</span>", -1)
TaskContent = string(md.Markdown([]byte(TaskContent)))
2015-11-21 16:33:34 +05:30
a := types.Task{Id: TaskID, Title: TaskTitle, Content: TaskContent, Created: TaskCreated.Format(time.UnixDate)[0:20]}
2015-11-13 14:34:42 +05:30
task = append(task, a)
}
2015-11-21 19:42:20 +05:30
context = types.Context{Tasks: task, Search: query}
return context
2015-11-13 14:34:42 +05:30
}
//GetComments is used to get comments, all of them.
//We do not want 100 different pages to show tasks, we want to use as few pages as possible
//so we are going to populate everything on the damn home pages
func GetComments() map[int][]types.Comment {
commentMap := make(map[int][]types.Comment)
var id int
var message types.Comment
stmt := "select taskID, content from comments;"
rows := database.query(stmt)
for rows.Next() {
err := rows.Scan(&id, &message.Content)
if err != nil {
}
commentMap[id] = append(commentMap[id], message)
}
return commentMap
}
//AddComments will be used to add comments in the database
func AddComments(id int, comment string) error {
stmt := "insert into comments(taskID, content) values (?,?)"
err := taskQuery(stmt, id, comment)
if err != nil {
return err
}
log.Println("added comment to task ID ", id)
return nil
}