db.py
author Eugen Sawin <sawine@me73.com>
Wed, 06 Oct 2010 01:18:34 +0200
changeset 12 28c80ae695dc
parent 11 8a99ccb99361
child 13 4ef9c2142059
permissions -rw-r--r--
Added set customer 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@12
    96
def update_where(db_file, table, dep_column, dep_value, set_column, set_value):
sawine@12
    97
	con, cur = session(db_file)
sawine@12
    98
	values = (set_value, dep_value)	
sawine@12
    99
	sql = "update %s set %s=? where %s=?" % (table, set_column, dep_column)
sawine@12
   100
	cur.execute(sql, values)
sawine@12
   101
	con.commit()
sawine@12
   102
	cur.close()
sawine@12
   103
	test(db_file)
sawine@12
   104
sawine@5
   105
def find_last_project(db_file, time):
sawine@4
   106
	con, cur = session(db_file)
sawine@4
   107
	values = (time,)
sawine@5
   108
	sql = "select project from tasks where begin < ? and end is null order by \
sawine@5
   109
begin desc"
sawine@4
   110
	cur.execute(sql, values)
sawine@4
   111
	id = cur.fetchone()
sawine@4
   112
	if id:
sawine@4
   113
		values = (id[0],)
sawine@4
   114
		sql = "select name from projects where rowid=?"
sawine@4
   115
		cur.execute(sql, values)
sawine@5
   116
		project = cur.fetchone()[0]
sawine@4
   117
	else:
sawine@6
   118
		project = None#DEF_PROJECT
sawine@4
   119
	con.commit()
sawine@4
   120
	cur.close()
sawine@4
   121
	return project
sawine@4
   122
sawine@5
   123
def find_last_activity(db_file, time):
sawine@5
   124
	con, cur = session(db_file)
sawine@5
   125
	values = (time,)
sawine@5
   126
	sql = "select activity from tasks where begin < ? and end is null order by \
sawine@5
   127
begin desc"
sawine@5
   128
	cur.execute(sql, values)
sawine@5
   129
	id = cur.fetchone()
sawine@5
   130
	if id:
sawine@5
   131
		values = (id[0],)
sawine@5
   132
		sql = "select name from activities where rowid=?"
sawine@5
   133
		cur.execute(sql, values)
sawine@5
   134
		activity = cur.fetchone()[0]
sawine@5
   135
	else:
sawine@6
   136
		activity = None#DEF_ACTIVITY
sawine@5
   137
	con.commit()
sawine@5
   138
	cur.close()
sawine@5
   139
	return activity
sawine@5
   140
sawine@11
   141
def find_active_task(db_file, time=None):
sawine@7
   142
	con, cur = session(db_file)
sawine@11
   143
	if time:
sawine@11
   144
		values = (time, time)
sawine@11
   145
		sql = "select project, activity from tasks where begin < ? and \
sawine@11
   146
(end is null or end > ?)"
sawine@11
   147
	else:
sawine@11
   148
		values = ()
sawine@11
   149
		sql = "select project, activity from tasks where end is null"
sawine@11
   150
	cur.execute(sql, values)	
sawine@8
   151
	task = cur.fetchone()
sawine@8
   152
	if task:
sawine@8
   153
		task = task[0]	
sawine@7
   154
	cur.close()
sawine@8
   155
	return task			
sawine@7
   156
sawine@7
   157
def id_name(db_file, table, id):
sawine@7
   158
	con, cur = session(db_file)
sawine@7
   159
	values = (id,)
sawine@7
   160
	sql = "select name from %s where rowid=?" % table
sawine@7
   161
	cur.execute(sql, values)
sawine@7
   162
	id = cur.fetchone()
sawine@7
   163
	cur.close()
sawine@7
   164
	return id[0]
sawine@7
   165
sawine@4
   166
def row_id(db_file, table, name):
sawine@4
   167
	con, cur = session(db_file)
sawine@4
   168
	values = (name,)
sawine@4
   169
	sql = "select rowid from %s where name=?" % table
sawine@4
   170
	cur.execute(sql, values)
sawine@4
   171
	id = cur.fetchone()
sawine@4
   172
	if not id:
sawine@4
   173
		sql = "insert into %s(name) values(?)" % table
sawine@4
   174
		cur.execute(sql, values)
sawine@4
   175
		con.commit()
sawine@4
   176
		cur.close()
sawine@4
   177
		return row_id(db_file, table, name)
sawine@4
   178
	con.commit()
sawine@4
   179
	cur.close()
sawine@4
   180
	return id[0]
sawine@4
   181
sawine@4
   182
def project_id(db_file, name):
sawine@4
   183
	return row_id(db_file, "projects", name)
sawine@4
   184
sawine@4
   185
def activity_id(db_file, name):
sawine@4
   186
	return row_id(db_file, "activities", name)
sawine@4
   187
sawine@9
   188
def end(db_file, project, activity, time, log):
sawine@6
   189
	print "ending: %s:%s" % (project, activity)
sawine@6
   190
	if activity or project:		
sawine@6
   191
		if not activity:
sawine@6
   192
			activity = find_last_activity(db_file, time)
sawine@6
   193
		elif not project:
sawine@6
   194
			project = find_last_project(db_file, time) 	
sawine@7
   195
		
sawine@6
   196
		con, cur = session(db_file)
sawine@7
   197
		if activity == "all" and project == "all":
sawine@9
   198
			values = (time, log)
sawine@9
   199
			sql = "update tasks set end=?, log=? where end is null"
sawine@7
   200
		else:
sawine@9
   201
			values = (time, log, project_id(db_file, project), 
sawine@9
   202
						activity_id(db_file, activity))
sawine@9
   203
			sql = "update tasks set end=?, log=? where project=? and activity=?"
sawine@6
   204
		cur.execute(sql, values)
sawine@6
   205
		con.commit()
sawine@6
   206
		cur.close()
sawine@6
   207
	test(db_file)
sawine@5
   208
sawine@3
   209
def begin(db_file, project, activity, time):
sawine@6
   210
	print "beginning: %s:%s" % (project, activity)
sawine@5
   211
	last_project = find_last_project(db_file, time) 
sawine@6
   212
	last_activity = find_last_activity(db_file, time)	
sawine@4
   213
	if not project:
sawine@5
   214
		project = last_project
sawine@6
   215
	elif not activity:
sawine@6
   216
			activity = DEF_ACTIVITY
sawine@5
   217
	if activity != last_activity or project != last_project:
sawine@9
   218
		end(db_file, last_project, last_activity, time, None)
sawine@6
   219
		con, cur = session(db_file)
sawine@6
   220
		values = (time, None, project_id(db_file, project), 
sawine@6
   221
					activity_id(db_file, activity), None)
sawine@6
   222
		sql = "insert into tasks values(?, ?, ?, ?, ?)"
sawine@6
   223
		cur.execute(sql, values)
sawine@6
   224
		con.commit()
sawine@6
   225
		cur.close()
sawine@6
   226
	test(db_file)
sawine@8
   227
sawine@8
   228
def is_paused(db_file, time):
sawine@8
   229
	con, cur = session(db_file)
sawine@11
   230
	values = (time,)
sawine@11
   231
	sql = "select rowid from breaks where begin < ? and end is null"
sawine@11
   232
	cur.execute(sql, values)
sawine@8
   233
	paused = cur.fetchone()
sawine@8
   234
	cur.close()
sawine@8
   235
	return paused
sawine@8
   236
sawine@11
   237
def pause(db_file, time):
sawine@8
   238
	print "pausing" 
sawine@8
   239
	if not is_paused(db_file, time):
sawine@11
   240
		task = find_active_task(db_file, time)
sawine@8
   241
		con, cur = session(db_file)
sawine@9
   242
		values = (time, None, task, None)
sawine@9
   243
		sql = "insert into breaks values(?, ?, ?, ?)"
sawine@8
   244
		cur.execute(sql, values)
sawine@8
   245
		con.commit()
sawine@8
   246
		cur.close()
sawine@8
   247
	test(db_file)
sawine@8
   248
sawine@9
   249
def resume(db_file, task, time, log):
sawine@8
   250
	print "resuming"
sawine@11
   251
	if is_paused(db_file, time):	
sawine@11
   252
		if not task:
sawine@11
   253
			task = find_active_task(db_file, time)	
sawine@8
   254
		con, cur = session(db_file)
sawine@9
   255
		values = (time, log, task)
sawine@11
   256
		sql = "update breaks set end=?, log=? where task=? and end is null"
sawine@8
   257
		cur.execute(sql, values)
sawine@8
   258
		con.commit()
sawine@8
   259
		cur.close()
sawine@8
   260
	test(db_file)
sawine@8
   261
sawine@8
   262
def status(db_file):
sawine@8
   263
	task = find_active_task(db_file)
sawine@8
   264
	con, cur = session(db_file)
sawine@8
   265
	result = None
sawine@8
   266
	if task:
sawine@8
   267
		values = (task,)
sawine@8
   268
		sql = "select project, activity from tasks where rowid=?"
sawine@8
   269
		cur.execute(sql, values)
sawine@8
   270
		result = cur.fetchone()
sawine@8
   271
		if result:
sawine@8
   272
			result = (id_name(db_file, "projects", result[0]),
sawine@8
   273
						id_name(db_file, "activities", result[1]))
sawine@8
   274
	return result
sawine@8
   275