2015-11-13 17:04:42 +08:00
package db
2016-02-01 22:34:19 +08:00
/ *
Stores the database functions related to tasks like
GetTaskByID ( id int )
GetTasks ( status string )
DeleteAll ( )
* /
2015-11-13 17:04:42 +08:00
import (
"database/sql"
2016-01-31 22:22:00 +08:00
"log"
"strings"
"time"
2016-02-01 21:45:04 +08:00
_ "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 17:04:42 +08:00
)
2016-01-31 21:48:19 +08:00
var database Database
2015-11-13 17:04:42 +08:00
var err error
2016-01-31 21:48:19 +08:00
//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 21:45:04 +08:00
return nil
2016-01-31 21:48:19 +08:00
}
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 21:45:04 +08:00
return nil
2016-01-31 21:48:19 +08:00
}
return stmt
}
func ( db Database ) query ( q string , args ... interface { } ) ( rows * sql . Rows ) {
2016-01-31 22:00:31 +08:00
rows , err := db . db . Query ( q , args ... )
2016-01-31 21:48:19 +08:00
if err != nil {
log . Println ( err )
2016-02-01 21:45:04 +08:00
return nil
2016-01-31 21:48:19 +08:00
}
return rows
}
2015-11-13 17:04:42 +08:00
func init ( ) {
2016-01-31 21:48:19 +08:00
database . db , err = sql . Open ( "sqlite3" , "./tasks.db" )
2015-11-13 17:04:42 +08:00
if err != nil {
2016-02-01 21:45:04 +08:00
log . Fatal ( err )
2015-11-13 17:04:42 +08:00
}
}
2015-11-21 14:39:15 +08:00
//Close function closes this database connection
2015-11-13 17:04:42 +08:00
func Close ( ) {
2016-01-31 21:48:19 +08:00
database . db . Close ( )
2015-11-13 17:04:42 +08:00
}
2015-11-21 14:39:15 +08:00
//GetTasks retrieves all the tasks depending on the
//status pending or trashed or completed
2016-02-03 01:40:44 +08:00
func GetTasks ( status , category string ) ( types . Context , error ) {
2015-11-13 17:04:42 +08:00
var task [ ] types . Task
2015-11-21 21:20:51 +08:00
var context types . Context
2015-11-21 14:39:15 +08:00
var TaskID int
2015-11-13 17:04:42 +08:00
var TaskTitle string
var TaskContent string
2015-11-14 18:10:21 +08:00
var TaskCreated time . Time
2016-01-31 20:30:10 +08:00
var TaskPriority string
2015-11-13 17:04:42 +08:00
var getTasksql string
2016-02-03 01:40:44 +08:00
var rows * sql . Rows
2015-11-21 21:20:51 +08:00
2016-02-03 01:40:44 +08:00
basicSQL := "select id, title, content, created_date, priority from task t"
if status == "pending" && category == "" {
2016-01-31 20:30:10 +08:00
getTasksql = basicSQL + " where finish_date is null and is_deleted='N' order by priority desc, created_date asc"
2015-11-21 21:20:51 +08:00
} else if status == "deleted" {
2016-01-31 20:30:10 +08:00
getTasksql = basicSQL + " where is_deleted='Y' order by priority desc, created_date asc"
2015-11-21 21:20:51 +08:00
} else if status == "completed" {
2016-01-31 20:30:10 +08:00
getTasksql = basicSQL + " where finish_date is not null order by priority desc, created_date asc"
2015-11-13 17:04:42 +08:00
}
2016-02-03 01:40:44 +08:00
if category != "" {
status = category
2016-02-06 15:09:38 +08:00
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-03 01:40:44 +08:00
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 17:04:42 +08:00
defer rows . Close ( )
2015-11-13 21:11:30 +08:00
for rows . Next ( ) {
2016-01-31 20:30:10 +08:00
err := rows . Scan ( & TaskID , & TaskTitle , & TaskContent , & TaskCreated , & TaskPriority )
TaskContent = string ( md . Markdown ( [ ] byte ( TaskContent ) ) )
// TaskContent = strings.Replace(TaskContent, "\n", "<br>", -1)
2015-11-13 21:11:30 +08:00
if err != nil {
2016-01-31 20:16:44 +08:00
log . Println ( err )
2015-11-13 17:04:42 +08:00
}
2015-11-14 18:10:21 +08:00
TaskCreated = TaskCreated . Local ( )
2016-01-31 20:30:10 +08:00
a := types . Task { Id : TaskID , Title : TaskTitle , Content : TaskContent , Created : TaskCreated . Format ( time . UnixDate ) [ 0 : 20 ] , Priority : TaskPriority }
2015-11-13 17:04:42 +08:00
task = append ( task , a )
}
2015-11-21 21:20:51 +08:00
context = types . Context { Tasks : task , Navigation : status }
2016-02-01 21:45:04 +08:00
return context , nil
2015-11-13 17:04:42 +08:00
}
2015-11-22 11:51:29 +08:00
//GetTaskByID function gets the tasks from the ID passed to the function, used to populate EditTask
2016-02-01 21:45:04 +08:00
func GetTaskByID ( id int ) ( types . Context , error ) {
2015-11-22 10:59:39 +08:00
var tasks [ ] types . Task
2015-11-13 17:04:42 +08:00
var task types . Task
2016-01-23 21:47:34 +08:00
2016-02-05 02:36:00 +08:00
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=?"
2016-01-31 20:30:10 +08:00
2016-01-31 21:48:19 +08:00
rows := database . query ( getTasksql , id )
2015-11-13 17:04:42 +08:00
defer rows . Close ( )
2015-11-13 21:11:30 +08:00
if rows . Next ( ) {
2016-02-05 02:36:00 +08:00
err := rows . Scan ( & task . Id , & task . Title , & task . Content , & task . Priority , & task . Category )
2015-11-13 21:11:30 +08:00
if err != nil {
2016-01-31 20:16:44 +08:00
log . Println ( err )
2016-01-31 20:30:10 +08:00
//send email to respective people
2015-11-13 17:04:42 +08:00
}
}
2015-11-22 10:59:39 +08:00
tasks = append ( tasks , task )
context := types . Context { Tasks : tasks , Navigation : "edit" }
2016-02-01 21:45:04 +08:00
return context , nil
2015-11-13 17:04:42 +08:00
}
2015-11-21 14:39:15 +08:00
//TrashTask is used to delete the task
2015-11-14 18:56:53 +08:00
func TrashTask ( id int ) error {
2016-01-31 21:56:14 +08:00
err := taskQuery ( "update task set is_deleted='Y',last_modified_at=datetime() where id=?" , id )
2015-11-14 18:56:53 +08:00
return err
}
2015-11-21 14:39:15 +08:00
//CompleteTask is used to mark tasks as complete
2015-11-14 18:56:53 +08:00
func CompleteTask ( id int ) error {
2016-01-31 21:56:14 +08:00
err := taskQuery ( "update task set is_deleted='Y', finish_date=datetime(),last_modified_at=datetime() where id=?" , id )
2015-11-13 17:04:42 +08:00
return err
}
2015-11-21 14:39:15 +08:00
//DeleteAll is used to empty the trash
2015-11-13 17:04:42 +08:00
func DeleteAll ( ) error {
2016-01-31 21:56:14 +08:00
err := taskQuery ( "delete from task where is_deleted='Y'" )
2015-11-13 17:04:42 +08:00
return err
}
2015-11-21 14:39:15 +08:00
//RestoreTask is used to restore tasks from the Trash
2015-11-13 17:04:42 +08:00
func RestoreTask ( id int ) error {
2016-01-31 21:56:14 +08:00
err := taskQuery ( "update task set is_deleted='N',last_modified_at=datetime() where id=?" , id )
2016-01-31 20:30:10 +08:00
return err
}
2016-01-31 21:48:19 +08:00
//RestoreTaskFromComplete is used to restore tasks from the Trash
2016-01-31 20:30:10 +08:00
func RestoreTaskFromComplete ( id int ) error {
2016-01-31 21:56:14 +08:00
err := taskQuery ( "update task set finish_date=null,last_modified_at=datetime() where id=?" , id )
2016-01-09 13:03:35 +08:00
return err
}
2015-11-21 14:39:15 +08:00
//DeleteTask is used to delete the task from the database
2015-11-13 17:04:42 +08:00
func DeleteTask ( id int ) error {
2016-01-31 21:56:14 +08:00
err := taskQuery ( "delete from task where id = ?" , id )
2015-11-13 17:04:42 +08:00
return err
}
2015-11-21 14:39:15 +08:00
//AddTask is used to add the task in the database
2016-02-03 01:40:44 +08:00
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 14:58:00 +08:00
categoryID := GetCategoryByName ( category )
2016-02-03 01:40:44 +08:00
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 17:04:42 +08:00
return err
}
2016-02-06 02:09:09 +08:00
//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 14:39:15 +08:00
//UpdateTask is used to update the tasks in the database
2016-02-06 04:07:45 +08:00
func UpdateTask ( id int , title , content , category string , priority int ) error {
2016-02-06 02:09:09 +08:00
categoryID := GetCategoryIdByName ( category )
2016-02-06 04:07:45 +08:00
err := taskQuery ( "update task set title=?, content=?, cat_id=?, priority = ? where id=?" , title , content , categoryID , priority , id )
2016-01-31 21:56:14 +08:00
return err
}
2016-01-31 22:22:00 +08:00
//taskQuery encapsulates running multiple queries which don't do much things
2016-01-31 21:56:14 +08:00
func taskQuery ( sql string , args ... interface { } ) error {
2016-01-31 22:10:15 +08:00
SQL := database . prepare ( sql )
2016-01-31 21:48:19 +08:00
tx := database . begin ( )
2016-01-31 22:00:31 +08:00
_ , err = tx . Stmt ( SQL ) . Exec ( args ... )
2015-11-13 21:11:30 +08:00
if err != nil {
2016-01-31 20:16:44 +08:00
log . Println ( err )
2015-11-13 17:04:42 +08:00
tx . Rollback ( )
} else {
2016-01-31 22:22:00 +08:00
tx . Commit ( )
2015-11-13 17:04:42 +08:00
}
return err
}
2015-11-21 14:39:15 +08:00
//SearchTask is used to return the search results depending on the query
2015-11-21 22:12:20 +08:00
func SearchTask ( query string ) types . Context {
2015-11-21 19:03:34 +08:00
stmt := "select id, title, content, created_date from task where title like '%" + query + "%' or content like '%" + query + "%'"
2015-11-13 17:04:42 +08:00
var task [ ] types . Task
2015-11-21 14:39:15 +08:00
var TaskID int
2015-11-13 17:04:42 +08:00
var TaskTitle string
var TaskContent string
2015-11-21 19:03:34 +08:00
var TaskCreated time . Time
2015-11-21 22:12:20 +08:00
var context types . Context
2015-11-13 17:04:42 +08:00
2016-01-31 21:48:19 +08:00
rows := database . query ( stmt , query , query )
2015-11-13 21:11:30 +08:00
for rows . Next ( ) {
2015-11-21 19:03:34 +08:00
err := rows . Scan ( & TaskID , & TaskTitle , & TaskContent , & TaskCreated )
2015-11-13 21:11:30 +08:00
if err != nil {
2016-01-31 20:16:44 +08:00
log . Println ( err )
2015-11-13 17:04:42 +08:00
}
TaskTitle = strings . Replace ( TaskTitle , query , "<span class='highlight'>" + query + "</span>" , - 1 )
TaskContent = strings . Replace ( TaskContent , query , "<span class='highlight'>" + query + "</span>" , - 1 )
2016-01-31 20:30:10 +08:00
TaskContent = string ( md . Markdown ( [ ] byte ( TaskContent ) ) )
2015-11-21 19:03:34 +08:00
a := types . Task { Id : TaskID , Title : TaskTitle , Content : TaskContent , Created : TaskCreated . Format ( time . UnixDate ) [ 0 : 20 ] }
2015-11-13 17:04:42 +08:00
task = append ( task , a )
}
2015-11-21 22:12:20 +08:00
context = types . Context { Tasks : task , Search : query }
return context
2015-11-13 17:04:42 +08:00
}