db.py
author Eugen Sawin <sawine@me73.com>
Tue, 05 Oct 2010 15:38:38 +0200
changeset 11 8a99ccb99361
parent 9 fab8e1981155
child 12 28c80ae695dc
permissions -rw-r--r--
Added add break command.
sawine@3
     1
"""
sawine@3
     2
Database lib for cronrec.
sawine@3
     3
Author: Eugen Sawin (sawine@me73.com)
sawine@3
     4
Dependencies: libsqlite3-dev
sawine@3
     5
"""
sawine@3
     6
sawine@3
     7
import sqlite3
sawine@3
     8
sawine@3
     9
ACTIVITIES_TABLE = """activities(
sawine@3
    10
name text not null,
sawine@3
    11
description text)"""
sawine@3
    12
sawine@3
    13
COMPANIES_TABLE = """companies(
sawine@3
    14
name text not null,
sawine@3
    15
street text,
sawine@3
    16
area text,
sawine@3
    17
town text,
sawine@3
    18
country text,
sawine@3
    19
postal text)"""
sawine@3
    20
sawine@3
    21
PROJECTS_TABLE = """projects(
sawine@3
    22
name text not null,
sawine@3
    23
number int,
sawine@3
    24
customer int,
sawine@3
    25
constraint customer_fk foreign key(customer) references companies(rowid) on delete
sawine@3
    26
cascade)"""
sawine@3
    27
sawine@3
    28
RATES_TABLE = """rates(
sawine@3
    29
rate smallmoney
sawine@3
    30
flatrate smallmoney,
sawine@3
    31
project int,
sawine@3
    32
activity int,
sawine@3
    33
constraint project_fk foreign key(project) references projects(rowid) on delete
sawine@3
    34
cascade,
sawine@3
    35
constraint activity_fk foreign key(activity) references activities(rowid) on delete
sawine@3
    36
cascade)"""
sawine@3
    37
sawine@3
    38
TASKS_TABLE = """tasks(
sawine@3
    39
begin datetime,
sawine@3
    40
end datetime,
sawine@3
    41
project int,
sawine@3
    42
activity int,
sawine@3
    43
log text,
sawine@3
    44
constraint project_fk foreign key(project) references projects(rowid) on delete
sawine@3
    45
cascade,
sawine@3
    46
constraint activity_fk foreign key(activity) references activities(rowid) on delete
sawine@3
    47
cascade)"""
sawine@3
    48
sawine@8
    49
BREAKS_TABLE = """breaks(
sawine@8
    50
begin datetime,
sawine@8
    51
end datetime,
sawine@8
    52
task int,
sawine@8
    53
log text,
sawine@8
    54
constraint task_fk foreign key(task) references tasks(rowid) on delete
sawine@8
    55
cascade)"""
sawine@8
    56
sawine@3
    57
TABLES = (ACTIVITIES_TABLE, COMPANIES_TABLE, PROJECTS_TABLE, RATES_TABLE,
sawine@8
    58
TASKS_TABLE, BREAKS_TABLE)
sawine@3
    59
sawine@4
    60
DEF_PROJECT = "default"
sawine@4
    61
DEF_ACTIVITY = "default"
sawine@4
    62
sawine@3
    63
def session(db_file):
sawine@3
    64
	con = sqlite3.connect(db_file)
sawine@3
    65
	return con, con.cursor()
sawine@3
    66
sawine@6
    67
def test(db_file):
sawine@3
    68
	con, cur = session(db_file)
sawine@6
    69
	cur.execute("select * from projects")
sawine@6
    70
	print "\nprojects"
sawine@3
    71
	for c in cur:
sawine@3
    72
		print c
sawine@6
    73
	cur.execute("select * from activities")
sawine@6
    74
	print "\nactivities"
sawine@6
    75
	for c in cur:
sawine@6
    76
		print c
sawine@6
    77
	cur.execute("select * from tasks")
sawine@6
    78
	print "\ntasks"
sawine@6
    79
	for c in cur:
sawine@6
    80
		print c
sawine@8
    81
	cur.execute("select * from breaks")
sawine@8
    82
	print "\nbreaks"
sawine@8
    83
	for c in cur:
sawine@8
    84
		print c
sawine@6
    85
	con.commit()
sawine@6
    86
	cur.close()
sawine@3
    87
sawine@3
    88
def init(db_file):
sawine@3
    89
	con, cur = session(db_file)
sawine@3
    90
	for table in TABLES:
sawine@3
    91
		sql = "create table " + table
sawine@3
    92
		cur.execute(sql)
sawine@3
    93
	con.commit()
sawine@3
    94
	cur.close()
sawine@3
    95
sawine@5
    96
def find_last_project(db_file, time):
sawine@4
    97
	con, cur = session(db_file)
sawine@4
    98
	values = (time,)
sawine@5
    99
	sql = "select project from tasks where begin < ? and end is null order by \
sawine@5
   100
begin desc"
sawine@4
   101
	cur.execute(sql, values)
sawine@4
   102
	id = cur.fetchone()
sawine@4
   103
	if id:
sawine@4
   104
		values = (id[0],)
sawine@4
   105
		sql = "select name from projects where rowid=?"
sawine@4
   106
		cur.execute(sql, values)
sawine@5
   107
		project = cur.fetchone()[0]
sawine@4
   108
	else:
sawine@6
   109
		project = None#DEF_PROJECT
sawine@4
   110
	con.commit()
sawine@4
   111
	cur.close()
sawine@4
   112
	return project
sawine@4
   113
sawine@5
   114
def find_last_activity(db_file, time):
sawine@5
   115
	con, cur = session(db_file)
sawine@5
   116
	values = (time,)
sawine@5
   117
	sql = "select activity from tasks where begin < ? and end is null order by \
sawine@5
   118
begin desc"
sawine@5
   119
	cur.execute(sql, values)
sawine@5
   120
	id = cur.fetchone()
sawine@5
   121
	if id:
sawine@5
   122
		values = (id[0],)
sawine@5
   123
		sql = "select name from activities where rowid=?"
sawine@5
   124
		cur.execute(sql, values)
sawine@5
   125
		activity = cur.fetchone()[0]
sawine@5
   126
	else:
sawine@6
   127
		activity = None#DEF_ACTIVITY
sawine@5
   128
	con.commit()
sawine@5
   129
	cur.close()
sawine@5
   130
	return activity
sawine@5
   131
sawine@11
   132
def find_active_task(db_file, time=None):
sawine@7
   133
	con, cur = session(db_file)
sawine@11
   134
	if time:
sawine@11
   135
		values = (time, time)
sawine@11
   136
		sql = "select project, activity from tasks where begin < ? and \
sawine@11
   137
(end is null or end > ?)"
sawine@11
   138
	else:
sawine@11
   139
		values = ()
sawine@11
   140
		sql = "select project, activity from tasks where end is null"
sawine@11
   141
	cur.execute(sql, values)	
sawine@8
   142
	task = cur.fetchone()
sawine@8
   143
	if task:
sawine@8
   144
		task = task[0]	
sawine@7
   145
	cur.close()
sawine@8
   146
	return task			
sawine@7
   147
sawine@7
   148
def id_name(db_file, table, id):
sawine@7
   149
	con, cur = session(db_file)
sawine@7
   150
	values = (id,)
sawine@7
   151
	sql = "select name from %s where rowid=?" % table
sawine@7
   152
	cur.execute(sql, values)
sawine@7
   153
	id = cur.fetchone()
sawine@7
   154
	cur.close()
sawine@7
   155
	return id[0]
sawine@7
   156
sawine@4
   157
def row_id(db_file, table, name):
sawine@4
   158
	con, cur = session(db_file)
sawine@4
   159
	values = (name,)
sawine@4
   160
	sql = "select rowid from %s where name=?" % table
sawine@4
   161
	cur.execute(sql, values)
sawine@4
   162
	id = cur.fetchone()
sawine@4
   163
	if not id:
sawine@4
   164
		sql = "insert into %s(name) values(?)" % table
sawine@4
   165
		cur.execute(sql, values)
sawine@4
   166
		con.commit()
sawine@4
   167
		cur.close()
sawine@4
   168
		return row_id(db_file, table, name)
sawine@4
   169
	con.commit()
sawine@4
   170
	cur.close()
sawine@4
   171
	return id[0]
sawine@4
   172
sawine@4
   173
def project_id(db_file, name):
sawine@4
   174
	return row_id(db_file, "projects", name)
sawine@4
   175
sawine@4
   176
def activity_id(db_file, name):
sawine@4
   177
	return row_id(db_file, "activities", name)
sawine@4
   178
sawine@9
   179
def end(db_file, project, activity, time, log):
sawine@6
   180
	print "ending: %s:%s" % (project, activity)
sawine@6
   181
	if activity or project:		
sawine@6
   182
		if not activity:
sawine@6
   183
			activity = find_last_activity(db_file, time)
sawine@6
   184
		elif not project:
sawine@6
   185
			project = find_last_project(db_file, time) 	
sawine@7
   186
		
sawine@6
   187
		con, cur = session(db_file)
sawine@7
   188
		if activity == "all" and project == "all":
sawine@9
   189
			values = (time, log)
sawine@9
   190
			sql = "update tasks set end=?, log=? where end is null"
sawine@7
   191
		else:
sawine@9
   192
			values = (time, log, project_id(db_file, project), 
sawine@9
   193
						activity_id(db_file, activity))
sawine@9
   194
			sql = "update tasks set end=?, log=? where project=? and activity=?"
sawine@6
   195
		cur.execute(sql, values)
sawine@6
   196
		con.commit()
sawine@6
   197
		cur.close()
sawine@6
   198
	test(db_file)
sawine@5
   199
sawine@3
   200
def begin(db_file, project, activity, time):
sawine@6
   201
	print "beginning: %s:%s" % (project, activity)
sawine@5
   202
	last_project = find_last_project(db_file, time) 
sawine@6
   203
	last_activity = find_last_activity(db_file, time)	
sawine@4
   204
	if not project:
sawine@5
   205
		project = last_project
sawine@6
   206
	elif not activity:
sawine@6
   207
			activity = DEF_ACTIVITY
sawine@5
   208
	if activity != last_activity or project != last_project:
sawine@9
   209
		end(db_file, last_project, last_activity, time, None)
sawine@6
   210
		con, cur = session(db_file)
sawine@6
   211
		values = (time, None, project_id(db_file, project), 
sawine@6
   212
					activity_id(db_file, activity), None)
sawine@6
   213
		sql = "insert into tasks values(?, ?, ?, ?, ?)"
sawine@6
   214
		cur.execute(sql, values)
sawine@6
   215
		con.commit()
sawine@6
   216
		cur.close()
sawine@6
   217
	test(db_file)
sawine@8
   218
sawine@8
   219
def is_paused(db_file, time):
sawine@8
   220
	con, cur = session(db_file)
sawine@11
   221
	values = (time,)
sawine@11
   222
	sql = "select rowid from breaks where begin < ? and end is null"
sawine@11
   223
	cur.execute(sql, values)
sawine@8
   224
	paused = cur.fetchone()
sawine@8
   225
	cur.close()
sawine@8
   226
	return paused
sawine@8
   227
sawine@11
   228
def pause(db_file, time):
sawine@8
   229
	print "pausing" 
sawine@8
   230
	if not is_paused(db_file, time):
sawine@11
   231
		task = find_active_task(db_file, time)
sawine@8
   232
		con, cur = session(db_file)
sawine@9
   233
		values = (time, None, task, None)
sawine@9
   234
		sql = "insert into breaks values(?, ?, ?, ?)"
sawine@8
   235
		cur.execute(sql, values)
sawine@8
   236
		con.commit()
sawine@8
   237
		cur.close()
sawine@8
   238
	test(db_file)
sawine@8
   239
sawine@9
   240
def resume(db_file, task, time, log):
sawine@8
   241
	print "resuming"
sawine@11
   242
	if is_paused(db_file, time):	
sawine@11
   243
		if not task:
sawine@11
   244
			task = find_active_task(db_file, time)	
sawine@8
   245
		con, cur = session(db_file)
sawine@9
   246
		values = (time, log, task)
sawine@11
   247
		sql = "update breaks set end=?, log=? where task=? and end is null"
sawine@8
   248
		cur.execute(sql, values)
sawine@8
   249
		con.commit()
sawine@8
   250
		cur.close()
sawine@8
   251
	test(db_file)
sawine@8
   252
sawine@8
   253
def status(db_file):
sawine@8
   254
	task = find_active_task(db_file)
sawine@8
   255
	con, cur = session(db_file)
sawine@8
   256
	result = None
sawine@8
   257
	if task:
sawine@8
   258
		values = (task,)
sawine@8
   259
		sql = "select project, activity from tasks where rowid=?"
sawine@8
   260
		cur.execute(sql, values)
sawine@8
   261
		result = cur.fetchone()
sawine@8
   262
		if result:
sawine@8
   263
			result = (id_name(db_file, "projects", result[0]),
sawine@8
   264
						id_name(db_file, "activities", result[1]))
sawine@8
   265
	return result
sawine@8
   266