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