You can subscribe to this list here.
2008 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2009 |
Jan
|
Feb
(1) |
Mar
(15) |
Apr
(20) |
May
(2) |
Jun
(9) |
Jul
(3) |
Aug
(2) |
Sep
(17) |
Oct
(16) |
Nov
(38) |
Dec
(40) |
2010 |
Jan
(51) |
Feb
(11) |
Mar
(24) |
Apr
(31) |
May
(24) |
Jun
(3) |
Jul
(9) |
Aug
(1) |
Sep
(29) |
Oct
(33) |
Nov
(81) |
Dec
(6) |
2011 |
Jan
(2) |
Feb
(4) |
Mar
(13) |
Apr
(4) |
May
(24) |
Jun
(4) |
Jul
(19) |
Aug
(46) |
Sep
(10) |
Oct
(28) |
Nov
(31) |
Dec
|
From: <nc...@us...> - 2011-08-13 08:28:12
|
Revision: 843 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=843&view=rev Author: ncjones Date: 2011-08-13 08:28:05 +0000 (Sat, 13 Aug 2011) Log Message: ----------- Use sport service for sports CRUD. ticket:138 Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowprofile.py pytrainer/trunk/pytrainer/profile.py Added Paths: ----------- pytrainer/trunk/pytrainer/gui/color.py pytrainer/trunk/pytrainer/test/gui/color_test.py Added: pytrainer/trunk/pytrainer/gui/color.py =================================================================== --- pytrainer/trunk/pytrainer/gui/color.py (rev 0) +++ pytrainer/trunk/pytrainer/gui/color.py 2011-08-13 08:28:05 UTC (rev 843) @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import gtk.gdk +from pytrainer.lib.color import Color + +class ColorConverter(object): + + """Converts between Pytrainer and GDK color instances.""" + + def convert_to_gdk_color(self, color): + """Convert a Pytrainer color to a GDK color.""" + color_format = "#{0:06x}".format(color.rgb_val) + return gtk.gdk.color_parse(color_format) + + def convert_to_color(self, gdk_col): + """Convert a GDK color to a Pytrainer color.""" + red = gdk_col.red >> 8 + green = gdk_col.green >> 8 + blue = gdk_col.blue >> 8 + rgb_val = (red << 16) + (green << 8) + blue + return Color(rgb_val) Modified: pytrainer/trunk/pytrainer/gui/windowprofile.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowprofile.py 2011-08-13 08:26:55 UTC (rev 842) +++ pytrainer/trunk/pytrainer/gui/windowprofile.py 2011-08-13 08:28:05 UTC (rev 843) @@ -21,9 +21,13 @@ from windowcalendar import WindowCalendar from pytrainer.equipment import EquipmentService from pytrainer.gui.equipment import EquipmentUi +from pytrainer.sport import Sport, SportService import gtk import gobject import logging +import pytrainer +import pytrainer.lib.color +from pytrainer.gui.color import ColorConverter class WindowProfile(SimpleGladeApp): def __init__(self, data_path = None, parent=None, pytrainer_main=None): @@ -35,7 +39,8 @@ self.data_path = data_path SimpleGladeApp.__init__(self, data_path+glade_path, root, domain) self.conf_options = parent.profile_options - self.stored_color = "000000" + self.stored_color = pytrainer.lib.color.Color(0) + self._sport_service = SportService(self.pytrainer_main.ddbb) def new(self): self.gender_options = { @@ -151,52 +156,27 @@ #print widget, pointer, frame if frame==2: self.saveOptions() - sport_list = self.parent.getSportList() - logging.debug("Got sport_list: %s" % str(sport_list) ) - if sport_list == 0: - pass - elif sport_list == -1: - self.sportlistbutton.set_label("It is not possible connect to the server") - else: - store = gtk.ListStore( - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gobject.TYPE_STRING, - gtk.gdk.Pixbuf, - object) - for i in sport_list: - try: - met = float(i[1]) - except: - met = "" - try: - weight = float(i[2]) - except: - weight = "" - try: - max_pace = int(i[4]) - if max_pace is None or max_pace == 0: - max_pace = "" - except Exception as e: - #print type(e), e - max_pace = "" - - colorPixBuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 25, 15) - colorPixBuf.fill(0 if i[5] in (None,'') else long(i[5]+'00',16)) - - iter = store.append() - store.set ( - iter, - 0, str(i[0]), - 1, met, - 2, weight, - 3, max_pace, - 4, colorPixBuf, - ) - self.sportTreeView.set_model(store) - self.sportTreeView.set_cursor(0) - self.sportlist.show() + sport_list = self._sport_service.get_all_sports() + store = gtk.ListStore( + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gobject.TYPE_STRING, + gtk.gdk.Pixbuf, + object) + for sport in sport_list: + iter = store.append() + colorPixBuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 25, 15) + colorPixBuf.fill(sport.color.rgba_val) + store.set(iter, + 0, sport.name, + 1, sport.met, + 2, sport.weight, + 3, sport.max_pace, + 4, colorPixBuf) + self.sportTreeView.set_model(store) + self.sportTreeView.set_cursor(0) + self.sportlist.show() elif frame == 5: #Startup Parameters page selected self.init_params_tab() @@ -321,19 +301,21 @@ self.addsport.show() def on_newsport_accept_clicked(self,widget): - sport = self.newsportentry.get_text() - met = self.newmetentry.get_text() - weight = self.newweightentry.get_text() - maxpace = self.newmaxpace.get_text() - if sport.lower() in [s[0].lower() for s in self.parent.getSportList()]: - msg = "Sport '%s' already exists" % sport + sport = Sport() + sport.name = unicode(self.newsportentry.get_text()) + sport.met = self._trim_to_null(self.newmetentry.get_text()) + sport.weight = self.newweightentry.get_text() + sport.max_pace = self._trim_to_null(self.newmaxpace.get_text()) + sport.color = self.stored_color + if sport.name.lower() in [s.name.lower() for s in self._sport_service.get_all_sports()]: + msg = "Sport '%s' already exists" % sport.name logging.error(msg) md = gtk.MessageDialog(None, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE, _(msg)) md.set_title(_("Sport Creation Error")) md.run() md.destroy() return - self.parent.addNewSport(sport,met,weight,maxpace,self.stored_color) + self._sport_service.store_sport(sport) self.parent.actualize_mainsportlist() self.on_switch_page(None,None,2) self.hidesportsteps() @@ -350,8 +332,9 @@ self.deletesport.show() def on_deletesport_clicked(self,widget): - sport = self.sportnamedel.get_text() - self.parent.delSport(sport) + sport_name = self.sportnamedel.get_text() + sport = self._sport_service.get_sport_by_name(sport_name) + self._sport_service.remove_sport(sport) self.parent.actualize_mainsportlist() self.on_switch_page(None,None,2) self.hidesportsteps() @@ -362,48 +345,34 @@ selected,iter = self.sportTreeView.get_selection().get_selected() if iter: self.buttonbox.set_sensitive(0) - sport = selected.get_value(iter,0) - name,met,weight,maxpace,color = self.parent.getSportInfo(sport) - self.editsportentry.set_text(sport) - self.sportnameedit.set_text(sport) - if weight is not None: - self.editweightentry.set_text(str(weight)) - else: - self.editweightentry.set_text("") - if met is not None: - self.editmetentry.set_text(str(met)) - else: - self.editmetentry.set_text("") - if maxpace is not None: - self.editmaxpace.set_text(str(maxpace)) - else: - self.editmaxpace.set_text("") - if color == None: - color = "0000" - + sport_desc = selected.get_value(iter,0) + sport = self._sport_service.get_sport_by_name(sport_desc) + self.editsportentry.set_text(sport.name) + self.sportnameedit.set_text(sport.name) + self.editweightentry.set_text(str(sport.weight)) + met_str = "" if sport.met is None else str(sport.met) + self.editmetentry.set_text(met_str) + max_pace_str = "" if sport.max_pace is None else str(sport.max_pace) + self.editmaxpace.set_text(max_pace_str) colorPixBuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 250, 20) - colorPixBuf.fill(long("0x%s00" % color, 16)) + colorPixBuf.fill(sport.color.rgba_val) self.editcolor.set_from_pixbuf(colorPixBuf) - self.hidesportsteps() self.editsport.show() def on_editcolor_clicked(self, widget): selected,iter = self.sportTreeView.get_selection().get_selected() if iter: - sport = selected.get_value(iter,0) - name,met,weight,maxpace,color = self.parent.getSportInfo(sport) - if color==None: - color = "000000" + sport_desc = selected.get_value(iter,0) + sport = self._sport_service.get_sport_by_name(sport_desc) colorseldlg = gtk.ColorSelectionDialog("test") colorseldlg.colorsel.set_has_palette(True) - colorseldlg.colorsel.set_current_color(gtk.gdk.color_parse("#"+color)) + colorseldlg.colorsel.set_current_color(ColorConverter().convert_to_gdk_color(sport.color)) colorseldlg.run() - col = colorseldlg.colorsel.get_current_color() - self.stored_color = ("%02x" % col.red)[:2] + ("%02x" % col.green)[:2] + ("%02x" % col.blue)[:2] - + gdk_color = colorseldlg.colorsel.get_current_color() + self.stored_color = ColorConverter().convert_to_color(gdk_color) colorPixBuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, 250, 20) - colorPixBuf.fill(long("0x%s00" % self.stored_color, 16)) + colorPixBuf.fill(self.stored_color.rgba_val) self.newcolor.set_from_pixbuf(colorPixBuf) self.editcolor.set_from_pixbuf(colorPixBuf) @@ -414,17 +383,23 @@ def on_editsport_accept_clicked(self,widget): oldnamesport = self.sportnameedit.get_text() - newnamesport = self.editsportentry.get_text() - newmetsport = self.editmetentry.get_text() - newweightsport = self.editweightentry.get_text() - newmaxpace = self.editmaxpace.get_text() - self.parent.updateSport(oldnamesport,newnamesport,newmetsport,newweightsport, newmaxpace, self.stored_color) + sport = self._sport_service.get_sport_by_name(oldnamesport) + sport.name = unicode(self.editsportentry.get_text()) + sport.weight = self.editweightentry.get_text() + sport.met = self._trim_to_null(self.editmetentry.get_text()) + sport.max_pace = self._trim_to_null(self.editmaxpace.get_text()) + sport.color = self.stored_color + self._sport_service.store_sport(sport) self.parent.actualize_mainsportlist() self.on_switch_page(None,None,2) self.hidesportsteps() self.buttonbox.set_sensitive(1) self.sportlist.show() + def _trim_to_null(self, string): + trimmed = string.strip() + return None if trimmed == "" else trimmed + def on_sportcancel_clicked(self,widget): self.hidesportsteps() self.buttonbox.set_sensitive(1) Modified: pytrainer/trunk/pytrainer/profile.py =================================================================== --- pytrainer/trunk/pytrainer/profile.py 2011-08-13 08:26:55 UTC (rev 842) +++ pytrainer/trunk/pytrainer/profile.py 2011-08-13 08:28:05 UTC (rev 843) @@ -228,39 +228,6 @@ #else: # return connection - def addNewSport(self,sport,met,weight,maxpace,color): - """31.08.2008 - dgranda - It adds a new sport. - arguments: - sport: sport's name - met: - weight: - returns: id_sports from new sport""" - logging.debug(">>") - logging.debug("Adding new sport: "+sport+"|"+weight+"|"+met+"|"+maxpace+"|"+str(color)) - sport = [sport,met,weight,maxpace,color] - self.pytrainer_main.ddbb.insert("sports","name,met,weight,max_pace,color",sport) - sport_id = self.pytrainer_main.ddbb.select("sports","id_sports","name=\"%s\"" %(sport)) - logging.debug("<<") - return sport_id - - def delSport(self,sport): - logging.debug(">>") - condition = "name=\"%s\"" %sport - id_sport = self.pytrainer_main.ddbb.select("sports","id_sports",condition)[0][0] - logging.debug("removing records from sport "+ sport + " (id_sport: "+str(id_sport)+")") - self.pytrainer_main.ddbb.delete("records","sport=\"%d\""%id_sport) - self.pytrainer_main.ddbb.delete("sports","id_sports=\"%d\""%id_sport) - logging.debug("<<") - - def updateSport(self,oldnamesport,newnamesport,newmetsport,newweightsport,newmaxpace=None,newcolor=None): - logging.debug("--") - self.pytrainer_main.ddbb.update("sports","name,met,weight,max_pace,color",[newnamesport,newmetsport,newweightsport, newmaxpace, newcolor],"name=\"%s\""%oldnamesport) - - def getSportInfo(self,namesport): - logging.debug("--") - return self.pytrainer_main.ddbb.select("sports","name,met,weight,max_pace,color","name=\"%s\""%namesport)[0] - def editProfile(self): logging.debug(">>") from gui.windowprofile import WindowProfile Added: pytrainer/trunk/pytrainer/test/gui/color_test.py =================================================================== --- pytrainer/trunk/pytrainer/test/gui/color_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/gui/color_test.py 2011-08-13 08:28:05 UTC (rev 843) @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +from pytrainer.gui.color import ColorConverter +from pytrainer.lib.color import Color +import gtk.gdk +import unittest + +class ColorConverterTest(unittest.TestCase): + + def setUp(self): + self._converter = ColorConverter() + + def test_convert_to_gdk_color_should_create_gdk_color_with_equivalent_rgb_values(self): + color = Color(0xaaff33) + gdk_color = self._converter.convert_to_gdk_color(color) + self.assertEquals(0x3333, gdk_color.blue) + self.assertEquals(0xffff, gdk_color.green) + self.assertEquals(0xaaaa, gdk_color.red) + + def test_convert_to_color_should_create_color_with_equivalent_rgb_values(self): + gdk_col = gtk.gdk.color_parse("#aaff33") + color = self._converter.convert_to_color(gdk_col) + self.assertEqual(0xaaff33, color.rgb_val) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-13 08:27:03
|
Revision: 842 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=842&view=rev Author: ncjones Date: 2011-08-13 08:26:55 +0000 (Sat, 13 Aug 2011) Log Message: ----------- Add sport service. ticket:138 Modified Paths: -------------- pytrainer/trunk/pytrainer/sport.py pytrainer/trunk/pytrainer/test/sport_test.py Modified: pytrainer/trunk/pytrainer/sport.py =================================================================== --- pytrainer/trunk/pytrainer/sport.py 2011-08-13 08:26:10 UTC (rev 841) +++ pytrainer/trunk/pytrainer/sport.py 2011-08-13 08:26:55 UTC (rev 842) @@ -16,7 +16,8 @@ #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -from pytrainer.lib.color import Color +from pytrainer.lib.color import Color, color_from_hex_string +import logging class Sport(object): @@ -90,3 +91,130 @@ self._color = color color = property(_get_color, _set_color) + +class SportServiceException(Exception): + + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + +_TABLE = "sports" + +_ID_COLUMN = "id_sports" + +_NAME_COLUMN = "name" + +_UPDATE_COLUMNS = _NAME_COLUMN + ",weight,met,max_pace,color" + +_SELECT_COLUMNS = _ID_COLUMN + "," + _UPDATE_COLUMNS + +class SportService(object): + + """Provides access to stored sports.""" + + def __init__(self, ddbb): + self._ddbb = ddbb + + def _create_sport(self, row): + sport = Sport() + sport.id = row[0] + sport.name = unicode(row[1]) + sport.weight = row[2] + sport.met = row[3] + sport.max_pace = row[4] + sport.color = color_from_hex_string(row[5]) + return sport + + def _create_row(self, sport): + return [sport.name, + sport.weight, + sport.met, + sport.max_pace, + sport.color.to_hex_string()] + + def _create_id_where_clause(self, sport_id): + return _ID_COLUMN + "=" + str(sport_id) + + def _create_name_where_clause(self, sport_name): + return _NAME_COLUMN + "=\"{0}\"".format(sport_name) + + def get_sport(self, sport_id): + """Get the sport with the specified id. + + If no sport with the given id exists then None is returned.""" + resultSet = self._ddbb.select(_TABLE, _SELECT_COLUMNS, self._create_id_where_clause(sport_id)) + if len(resultSet) == 0: + return None + else: + return self._create_sport(resultSet[0]) + + def get_sport_by_name(self, name): + """Get the sport with the specified name. + + If no sport with the given name exists then None is returned.""" + sport_id = self._get_sport_id_from_name(name) + return self.get_sport(sport_id) + + def _get_sport_id_from_name(self, name): + result_set = self._ddbb.select(_TABLE, _ID_COLUMN, self._create_name_where_clause(name)) + if len(result_set) > 0: + return result_set[0][0] + return None + + def get_all_sports(self): + """Get all stored sports.""" + result_set = self._ddbb.select(_TABLE, _SELECT_COLUMNS) + logging.debug("Retrieved all sports ({0} results).".format(len(result_set))) + sports = [] + for row in result_set: + sport = self._create_sport(row) + sports.append(sport) + return sports + + def store_sport(self, sport): + """Store a new or update an existing sport. + + The stored object is returned.""" + if (sport.id is None): + sport_id = self._store_new_sport(sport) + else: + sport_id = self._update_existing_sport(sport) + return self.get_sport(sport_id) + + def _store_new_sport(self, sport): + self._assert_unique(sport) + self._ddbb.insert(_TABLE, _UPDATE_COLUMNS, self._create_row(sport)) + logging.debug("Stored new sport: '{0}'.".format(sport.name)) + return self._get_sport_id_from_name(sport.name) + + def _update_existing_sport(self, sport): + self._assert_exists(sport) + self._assert_unique(sport) + self._ddbb.update(_TABLE, _UPDATE_COLUMNS, self._create_row(sport), self._create_id_where_clause(sport.id)) + logging.debug("Updated sport: '{0}'.".format(sport.name)) + return sport.id + + def _assert_unique(self, sport): + id = self._get_sport_id_from_name(sport.name) + if id is not None and id != sport.id: + raise SportServiceException("A sport already exists with name '{0}'".format(sport.name)) + logging.debug("Asserted sport name is unique: '{0}'.".format(sport.name)) + + def _assert_exists(self, sport): + result_set = self._ddbb.select(_TABLE, _ID_COLUMN, self._create_id_where_clause(sport.id)) + if (result_set == []): + raise SportServiceException("Sport does not exist with id: '{0}'.".format(sport.id)) + logging.debug("Asserted sport exists with id: '{0}'.".format(sport.id)) + + def remove_sport(self, sport): + """Delete a stored sport. + + All records associated with the sport will also be deleted.""" + if (sport.id is None): + raise SportServiceException("Cannot remove sport which has not been stored: '{0}'.".format(sport.name)) + self._assert_exists(sport) + self._ddbb.delete("records", "sport=" + str(sport.id)) + self._ddbb.delete(_TABLE, self._create_id_where_clause(sport.id)) + logging.debug("Deleted sport: '{0}'.".format(sport.name)) Modified: pytrainer/trunk/pytrainer/test/sport_test.py =================================================================== --- pytrainer/trunk/pytrainer/test/sport_test.py 2011-08-13 08:26:10 UTC (rev 841) +++ pytrainer/trunk/pytrainer/test/sport_test.py 2011-08-13 08:26:55 UTC (rev 842) @@ -17,7 +17,10 @@ #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import unittest -from pytrainer.sport import Sport +from pytrainer.sport import Sport, SportService, SportServiceException +import mock +from pytrainer.lib.sqliteUtils import Sql +import pytrainer class SportTest(unittest.TestCase): @@ -212,3 +215,164 @@ pass else: self.fail() + + +class SportServiceTest(unittest.TestCase): + + def setUp(self): + self.mock_ddbb = mock.Mock(spec=Sql) + self.sport_service = SportService(self.mock_ddbb) + + def test_store_sport_should_insert_row_when_sport_has_no_id(self): + self.mock_ddbb.select.return_value = [] + sport = Sport() + sport.name = u"Test name" + self.sport_service.store_sport(sport) + self.mock_ddbb.insert.assert_called_with("sports", "name,weight,met,max_pace,color", + [u"Test name", 0.0, None, None, "0000ff"]) + + def test_store_sport_should_update_row_when_sport_has_id(self): + def mock_select(table, columns, where): + if columns == "id_sports": + return [[1]] + else: + return [(1, u"", 0, 0, 0, "0")] + self.mock_ddbb.select = mock.Mock(wraps=mock_select) + sport = Sport() + sport.id = 1 + sport.name = u"New name" + self.sport_service.store_sport(sport) + self.mock_ddbb.update.assert_called_with("sports", "name,weight,met,max_pace,color", + [u"New name", 0.0, None, None, "0000ff"], "id_sports=1") + + def test_store_sport_should_return_stored_sport(self): + sport_ids = [] + def update_sport_ids(*args): + sport_ids.append([1]) + self.mock_ddbb.insert.side_effect = update_sport_ids + def mock_select(table, columns, where): + if columns == "id_sports": + return sport_ids + else: + return [(2, u"", 0, 0, 0, "0")] + self.mock_ddbb.select = mock.Mock(wraps=mock_select) + sport = Sport() + stored_sport = self.sport_service.store_sport(sport) + self.assertEquals(2, stored_sport.id) + + def test_store_sport_should_error_when_sport_has_unknown_id(self): + self.mock_ddbb.select.return_value = [] + sport = Sport() + sport.id = 100 + try: + self.sport_service.store_sport(sport) + except(SportServiceException): + pass + else: + self.fail() + + def test_store_sport_should_error_when_new_sport_has_duplicate_name(self): + self.mock_ddbb.select.return_value = [(1, u"Test name", 150, 12.5, 200, "0")] + sport = Sport() + sport.name = u"Test name" + try: + self.sport_service.store_sport(sport) + except(SportServiceException): + pass + else: + self.fail() + + def test_store_sport_should_error_when_existing_sport_has_duplicate_name(self): + def mock_select(table, columns, where): + if columns == pytrainer.sport._ID_COLUMN: + return [[2]] + else: + return [(1, u"Test name", 0, 0.0, "0"), (2, u"New name", 0, 0.0, "0")] + self.mock_ddbb.select = mock.Mock(wraps=mock_select) + sport = Sport() + sport.id = 1 + sport.name = u"New name" + try: + self.sport_service.store_sport(sport) + except(SportServiceException): + pass + else: + self.fail() + + def test_get_sport_returns_none_for_nonexistant_sport(self): + self.mock_ddbb.select.return_value = [] + sport = self.sport_service.get_sport(1) + self.assertEquals(None, sport) + + def test_get_sport_returns_sport_with_id(self): + self.mock_ddbb.select.return_value = [(1, u"", 0, 0, 0, "0")] + sport = self.sport_service.get_sport(1) + self.assertEquals(1, sport.id) + + def test_get_sport_by_name_returns_none_for_nonexistant_sport(self): + self.mock_ddbb.select.return_value = [] + sport = self.sport_service.get_sport("no such sport") + self.assertEquals(None, sport) + + def test_get_sport_by_name_returns_sport_with_name(self): + def mock_select(table, columns, where): + if columns == "id_sport": + return [(1)] + else: + return [(1, u"rugby", 0, 0, 0, "0")] + self.mock_ddbb.select = mock.Mock(wraps=mock_select) + sport = self.sport_service.get_sport("rugby") + self.assertEquals(u"rugby", sport.name) + + def test_get_all_sports_should_return_all_sports_in_query_result(self): + self.mock_ddbb.select.return_value = [(1, u"Test name", 0, 0, 0, "0"), (2, u"Test name 2", 0, 0, 0, "0")] + sports = self.sport_service.get_all_sports() + self.assertEquals(2, len(sports)) + sport1 = sports[0] + self.assertEquals(1, sport1.id) + sport2 = sports[1] + self.assertEquals(2, sport2.id) + + def test_get_all_sports_should_return_no_sports_when_query_result_empty(self): + self.mock_ddbb.select.return_value = [] + sports = self.sport_service.get_all_sports() + self.assertEquals(0, len(sports)) + + def test_remove_sport_should_error_when_sport_has_no_id(self): + self.mock_ddbb.select.return_value = [(1, u"Test name", 150, 12.5, 200, "0")] + sport = Sport() + try: + self.sport_service.remove_sport(sport) + except(SportServiceException): + pass + else: + self.fail() + + def test_remove_sport_should_error_when_sport_has_unknown_id(self): + self.mock_ddbb.select.return_value = [] + sport = Sport() + sport.id = 100 + try: + self.sport_service.remove_sport(sport) + except(SportServiceException): + pass + else: + self.fail() + + def test_remove_sport_should_delete_sport_with_specified_id(self): + self.mock_ddbb.select.return_value = [[1]] + sport = Sport() + sport.id = 1 + self.sport_service.remove_sport(sport) + self.mock_ddbb.delete.assert_called_with("sports", "id_sports=1") + + def test_remove_sport_should_remove_associated_entries(self): + self.mock_ddbb.select.return_value = [[1]] + sport = Sport() + sport.id = 1 + delete_arguments = [] + def mock_delete(*args): + delete_arguments.append(args) + self.mock_ddbb.delete = mock.Mock(wraps=mock_delete) + self.sport_service.remove_sport(sport) + self.assertEquals(("records", "sport=1"), delete_arguments[0]) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-13 08:26:16
|
Revision: 841 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=841&view=rev Author: ncjones Date: 2011-08-13 08:26:10 +0000 (Sat, 13 Aug 2011) Log Message: ----------- Add sport entity class. ticket:138 Added Paths: ----------- pytrainer/trunk/pytrainer/lib/color.py pytrainer/trunk/pytrainer/sport.py pytrainer/trunk/pytrainer/test/lib/ pytrainer/trunk/pytrainer/test/lib/__init__.py pytrainer/trunk/pytrainer/test/lib/color_test.py pytrainer/trunk/pytrainer/test/sport_test.py Added: pytrainer/trunk/pytrainer/lib/color.py =================================================================== --- pytrainer/trunk/pytrainer/lib/color.py (rev 0) +++ pytrainer/trunk/pytrainer/lib/color.py 2011-08-13 08:26:10 UTC (rev 841) @@ -0,0 +1,45 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +class Color(object): + + """A color represented as a 24-bit RGB value.""" + + def __init__(self, rgb_val=0): + rgb_val_int = int(rgb_val) + if rgb_val_int < 0: + raise ValueError("RGB value must not be negative.") + if rgb_val_int > 0xffffff: + raise ValueError("RGB value must not be greater than 0xffffff.") + self._rgb_val = rgb_val_int + + def _get_rgb_val(self): + return self._rgb_val + + rgb_val = property(_get_rgb_val) + + def _get_rgba_val(self): + return self._rgb_val << 8 + + rgba_val = property(_get_rgba_val) + + def to_hex_string(self): + return "{0:06x}".format(self._rgb_val) + +def color_from_hex_string(hex_string): + return Color(int(hex_string, 16)) Added: pytrainer/trunk/pytrainer/sport.py =================================================================== --- pytrainer/trunk/pytrainer/sport.py (rev 0) +++ pytrainer/trunk/pytrainer/sport.py 2011-08-13 08:26:10 UTC (rev 841) @@ -0,0 +1,92 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +from pytrainer.lib.color import Color + +class Sport(object): + + """A type of exercise. For example: "running" or "cycling".""" + + def __init__(self): + self._id = None + self.name = u"" + self.weight = 0.0 + self.met = None + self.max_pace = None + self.color = Color(0x0000ff) + + def _get_id(self): + return self._id + + def _set_id(self, id): + self._id = int(id) + + id = property(_get_id, _set_id) + + def _get_name(self): + return self._name + + def _set_name(self, name): + if not isinstance(name, unicode): + raise TypeError("Name must be unicode string, not {0}.".format(type(name).__name__)) + self._name = name + + name = property(_get_name, _set_name) + + def _get_weight(self): + return self._weight + + def _set_weight(self, weight): + weight_float = float(weight) + if weight_float < 0: + raise ValueError("Weight must not be negative.") + self._weight = weight_float + + weight = property(_get_weight, _set_weight) + + def _get_met(self): + return self._met + + def _set_met(self, met): + met_float = float(met) if met is not None else None + if met_float is not None and met_float < 0: + raise ValueError("MET must not be negative.") + self._met = met_float + + met = property(_get_met, _set_met) + + def _get_max_pace(self): + return self._max_pace + + def _set_max_pace(self, max_pace): + max_pace_int = int(max_pace) if max_pace is not None else None + if max_pace_int is not None and max_pace_int < 0: + raise ValueError("Max pace must not be negative.") + self._max_pace = max_pace_int + + max_pace = property(_get_max_pace, _set_max_pace) + + def _get_color(self): + return self._color + + def _set_color(self, color): + if color is None: + raise ValueError("Color must be valued.") + self._color = color + + color = property(_get_color, _set_color) Added: pytrainer/trunk/pytrainer/test/lib/__init__.py =================================================================== Added: pytrainer/trunk/pytrainer/test/lib/color_test.py =================================================================== --- pytrainer/trunk/pytrainer/test/lib/color_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/lib/color_test.py 2011-08-13 08:26:10 UTC (rev 841) @@ -0,0 +1,87 @@ +# -*- coding: utf-8 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +from pytrainer.lib.color import Color, color_from_hex_string +import unittest + +class ColorTest(unittest.TestCase): + + def test_constructor_should_accept_integer(self): + color = Color(12345) + self.assertEqual(12345, color.rgb_val) + + def test_constructor_should_accept_integer_string(self): + color = Color("12345") + self.assertEqual(12345, color.rgb_val) + + def test_constructor_should_not_accept_non_integer_string(self): + try: + Color("ff00ff") + except(ValueError): + pass + else: + self.fail() + + def test_constructor_should_not_accept_none(self): + try: + Color(None) + except(TypeError): + pass + else: + self.fail() + + def test_constructor_should_not_accept_negative_value(self): + try: + Color(-1) + except(ValueError): + pass + else: + self.fail() + + def test_constructor_should_not_accept_value_over_24_bit(self): + try: + Color(2 ** 24) + except(ValueError): + pass + else: + self.fail() + + def test_rgb_value_should_default_to_0(self): + color = Color() + self.assertEqual(0, color.rgb_val) + + def test_rgb_value_should_be_read_only(self): + color = Color() + try: + color.rgb_val = 1 + except(AttributeError): + pass + else: + self.fail() + + def test_rgba_value_should_be_rgb_value_with_two_trailing_zero_hex_digits(self): + color = Color(0x1177ff) + self.assertEquals(0x1177ff00, color.rgba_val) + + def test_to_hex_string_should_create_six_digit_hex_value(self): + color = Color(0xfab) + self.assertEquals("000fab", color.to_hex_string()) + + def test_color_from_hex_string_should_correctly_decode_hex_value(self): + color = color_from_hex_string("fab") + self.assertEquals(0xfab, color.rgb_val) Added: pytrainer/trunk/pytrainer/test/sport_test.py =================================================================== --- pytrainer/trunk/pytrainer/test/sport_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/sport_test.py 2011-08-13 08:26:10 UTC (rev 841) @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import unittest +from pytrainer.sport import Sport + +class SportTest(unittest.TestCase): + + def test_id_should_default_to_none(self): + sport = Sport() + self.assertEquals(None, sport.id) + + def test_id_should_accept_integer(self): + sport = Sport() + sport.id = 1 + self.assertEquals(1, sport.id) + + def test_id_should_accept_integer_string(self): + sport = Sport() + sport.id = "1" + self.assertEquals(1, sport.id) + + def test_id_should_not_accept_non_integer_string(self): + sport = Sport() + try: + sport.id = "1.1" + except(ValueError): + pass + else: + self.fail() + + def test_id_should_not_accept_none(self): + sport = Sport() + try: + sport.id = None + except(TypeError): + pass + else: + self.fail() + + def test_name_should_default_to_empty_string(self): + sport = Sport() + self.assertEquals(u"", sport.name) + + def test_name_should_accept_unicode_string(self): + sport = Sport() + sport.name = u"Unicycling" + self.assertEquals(u"Unicycling", sport.name) + + def test_name_should_not_accept_non_unicode_string(self): + sport = Sport() + try: + sport.name = "Juggling" + except(TypeError): + pass + else: + self.fail() + + def test_name_should_not_accept_none(self): + sport = Sport() + try: + sport.name = None + except(TypeError): + pass + else: + self.fail() + + def test_met_should_default_to_None(self): + sport = Sport() + self.assertEquals(None, sport.met) + + def test_met_should_accept_float(self): + sport = Sport() + sport.met = 22.5 + self.assertEquals(22.5, sport.met) + + def test_met_should_accept_float_string(self): + sport = Sport() + sport.met = "22.5" + self.assertEquals(22.5, sport.met) + + def test_met_should_not_accept_non_float_string(self): + sport = Sport() + try: + sport.met = "22.5kg" + except(ValueError): + pass + else: + self.fail() + + def test_met_should_not_accept_negative_value(self): + sport = Sport() + try: + sport.met = -1 + except(ValueError): + pass + else: + self.fail() + + def test_met_should_accept_none(self): + sport = Sport() + sport.met = None + self.assertEquals(None, sport.met) + + def test_weight_should_default_to_zero(self): + sport = Sport() + self.assertEquals(0, sport.weight) + + def test_weight_should_accept_float(self): + sport = Sport() + sport.weight = 22.5 + self.assertEquals(22.5, sport.weight) + + def test_weight_should_accept_float_string(self): + sport = Sport() + sport.weight = "22.5" + self.assertEquals(22.5, sport.weight) + + def test_weight_should_not_accept_non_float_string(self): + sport = Sport() + try: + sport.weight = "22.5kg" + except(ValueError): + pass + else: + self.fail() + + def test_weight_should_not_accept_negative_value(self): + sport = Sport() + try: + sport.weight = -1 + except(ValueError): + pass + else: + self.fail() + + def test_weight_should_not_accept_none(self): + sport = Sport() + try: + sport.weight = None + except(TypeError): + pass + else: + self.fail() + + def test_max_pace_should_default_to_none(self): + sport = Sport() + self.assertEquals(None, sport.max_pace) + + def test_max_pace_should_accept_integer(self): + sport = Sport() + sport.max_pace = 220 + self.assertEquals(220, sport.max_pace) + + def test_max_pace_should_accept_integer_string(self): + sport = Sport() + sport.max_pace = "220" + self.assertEquals(220, sport.max_pace) + + def test_max_pace_should_not_accept_non_integer_string(self): + sport = Sport() + try: + sport.max_pace = "225s" + except(ValueError): + pass + else: + self.fail() + + def test_max_pace_should_take_floor_of_float(self): + sport = Sport() + sport.max_pace = 220.6 + self.assertEquals(220, sport.max_pace) + + def test_max_pace_should_not_accept_negative_value(self): + sport = Sport() + try: + sport.max_pace = -1 + except(ValueError): + pass + else: + self.fail() + + def test_max_pace_should_accept_none(self): + sport = Sport() + sport.max_pace = None + self.assertEquals(None, sport.max_pace) + + def test_color_should_default_to_blue(self): + sport = Sport() + self.assertEquals(0x0000ff, sport.color.rgb_val) + + def test_color_should_not_accept_none(self): + sport = Sport() + try: + sport.color = None + except(ValueError): + pass + else: + self.fail() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-13 08:24:56
|
Revision: 840 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=840&view=rev Author: ncjones Date: 2011-08-13 08:24:50 +0000 (Sat, 13 Aug 2011) Log Message: ----------- Fix persisting of null values. ticket:138 Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/sqliteUtils.py Modified: pytrainer/trunk/pytrainer/lib/sqliteUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-08-09 22:46:46 UTC (rev 839) +++ pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-08-13 08:24:50 UTC (rev 840) @@ -90,11 +90,19 @@ for i in val: if count>0: string+="," - string+="""\"%s\"""" %i + string+= self._to_sql_value(i) count = count+1 sql = "insert into %s (%s) values (%s)" %(table,cells,string) cur.execute(sql) self.db.commit() + + def _to_sql_value(self, value): + if value == None: + return "null" + elif type(value) in [str, unicode]: + return "\"" + value + "\"" + else: + return str(value) def freeExec(self,sql): cur = self.db.cursor() @@ -119,7 +127,7 @@ for val in values: if count>0: string+="," - string += """%s=%s """ %(cells[count],values[count] if type(values[count]) not in [str, unicode] else "'%s'" % values[count]) + string += """%s=%s """ %(cells[count], self._to_sql_value(values[count])) count = count+1 string +=" where %s" %condition This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <dg...@us...> - 2011-08-09 22:46:52
|
Revision: 839 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=839&view=rev Author: dgranda Date: 2011-08-09 22:46:46 +0000 (Tue, 09 Aug 2011) Log Message: ----------- Loading environment preferences -basically log_file- before start logging. It prevented application to start Modified Paths: -------------- pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2011-08-09 11:25:02 UTC (rev 838) +++ pytrainer/trunk/pytrainer/main.py 2011-08-09 22:46:46 UTC (rev 839) @@ -59,9 +59,9 @@ #Process command line options self.startup_options = self.get_options() #Setup logging - self.set_logging(self.startup_options.log_level, self.startup_options.log_type) self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() + self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-09 11:25:08
|
Revision: 838 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=838&view=rev Author: ncjones Date: 2011-08-09 11:25:02 +0000 (Tue, 09 Aug 2011) Log Message: ----------- Add missing test package __init__.py files. ticket:138 Added Paths: ----------- pytrainer/trunk/pytrainer/test/__init__.py pytrainer/trunk/pytrainer/test/gui/__init__.py pytrainer/trunk/pytrainer/test/upgrade/__init__.py Added: pytrainer/trunk/pytrainer/test/__init__.py =================================================================== Added: pytrainer/trunk/pytrainer/test/gui/__init__.py =================================================================== Added: pytrainer/trunk/pytrainer/test/upgrade/__init__.py =================================================================== This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-08 12:39:19
|
Revision: 837 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=837&view=rev Author: ncjones Date: 2011-08-08 12:39:11 +0000 (Mon, 08 Aug 2011) Log Message: ----------- Move test modules to source package hierachy. ticket:139 Added Paths: ----------- pytrainer/trunk/pytrainer/test/ pytrainer/trunk/pytrainer/test/environment_test.py pytrainer/trunk/pytrainer/test/equipment_test.py pytrainer/trunk/pytrainer/test/gui/ pytrainer/trunk/pytrainer/test/gui/equipment_test.py pytrainer/trunk/pytrainer/test/upgrade/ pytrainer/trunk/pytrainer/test/upgrade/data_test.py Removed Paths: ------------- pytrainer/trunk/test/pytrainer/environment_test.py pytrainer/trunk/test/pytrainer/equipment_test.py pytrainer/trunk/test/pytrainer/gui/equipment_test.py pytrainer/trunk/test/pytrainer/upgrade/data_test.py Copied: pytrainer/trunk/pytrainer/test/environment_test.py (from rev 836, pytrainer/trunk/test/pytrainer/environment_test.py) =================================================================== --- pytrainer/trunk/pytrainer/test/environment_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/environment_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -0,0 +1,75 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import unittest + +from mock import Mock + +import pytrainer.platform +from pytrainer.environment import Environment + +TEST_DIR_NAME = "/test/.pytrainer_test" + +PLATFORM = pytrainer.platform.get_platform() + +class Test(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_get_conf_dir(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME, environment.conf_dir) + + def test_get_conf_dir_default(self): + test_platform = Mock(spec=pytrainer.platform.get_platform()) + test_platform.get_default_conf_dir.return_value = "/test/.pytrainer_test" + environment = Environment(test_platform, None) + self.assertEquals("/test/.pytrainer_test", environment.conf_dir) + + def test_get_conf_file(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME + "/conf.xml", environment.conf_file) + + def test_get_log_file(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME + "/log.out", environment.log_file) + + def test_get_temp_dir(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME + "/tmp", environment.temp_dir) + + def test_get_gpx_dir(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME + "/gpx", environment.gpx_dir) + + def test_get_extension_dir(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME + "/extensions", environment.extension_dir) + + def test_get_plugin_dir(self): + environment = Environment(PLATFORM, TEST_DIR_NAME) + self.assertEquals(TEST_DIR_NAME + "/plugins", environment.plugin_dir) + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file Copied: pytrainer/trunk/pytrainer/test/equipment_test.py (from rev 836, pytrainer/trunk/test/pytrainer/equipment_test.py) =================================================================== --- pytrainer/trunk/pytrainer/test/equipment_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/equipment_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -0,0 +1,348 @@ +# -*- coding: utf-8 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import unittest +import mock +from pytrainer.equipment import Equipment, EquipmentService,\ + EquipmentServiceException +from pytrainer.lib.sqliteUtils import Sql + +class EquipmentTest(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_id_defaults_to_none(self): + equipment = Equipment() + self.assertEqual(None, equipment.id) + + def test_id_set_to_integer(self): + equipment = Equipment() + equipment.id = 2 + self.assertEquals(2, equipment.id) + + def test_id_set_to_numeric_string(self): + equipment = Equipment() + equipment.id = "3" + self.assertEquals(3, equipment.id) + + def test_id_set_to_non_numeric_string(self): + equipment = Equipment() + try: + equipment.id = "test" + except(ValueError): + pass + else: + self.fail("Should not be able to set equipment id to non numeric value.") + + def test_description_defaults_to_empty_string(self): + equipment = Equipment() + self.assertEquals(u"", equipment.description) + + def test_description_set_to_string(self): + equipment = Equipment() + try: + equipment.description = "100$ Shoes" + except(TypeError): + pass + else: + self.fail("Should not be able to set description to non unicode string value.") + + def test_description_set_to_unicode_string(self): + equipment = Equipment() + equipment.description = u"Zapatos de €100" + self.assertEquals(u"Zapatos de €100", equipment.description) + + def test_description_set_to_non_string(self): + equipment = Equipment() + try: + equipment.description = 42 + except(TypeError): + pass + else: + self.fail("Should not be able to set description to non string value.") + + def test_active_defaults_to_true(self): + equipment = Equipment() + self.assertTrue(equipment.active) + + def test_active_set_to_boolean(self): + equipment = Equipment() + equipment.active = False + self.assertFalse(equipment.active) + + def test_active_set_to_non_boolean(self): + equipment = Equipment() + try: + equipment.active = "test" + except(TypeError): + pass + else: + self.fail("Should not be able to set active to non-boolean value.") + + def test_life_expectancy_defaults_to_zero(self): + equipment = Equipment() + self.assertEqual(0, equipment.life_expectancy) + + def test_life_expectancy_set_to_integer(self): + equipment = Equipment() + equipment.life_expectancy = 2 + self.assertEquals(2, equipment.life_expectancy) + + def test_life_expectancy_set_to_numeric_string(self): + equipment = Equipment() + equipment.life_expectancy = "3" + self.assertEquals(3, equipment.life_expectancy) + + def test_life_expectancy_set_to_non_numeric_string(self): + equipment = Equipment() + try: + equipment.life_expectancy = "test" + except(ValueError): + pass + else: + self.fail("Should not be able to set life expectancy to non numeric value.") + + def test_prior_usage_defaults_to_zero(self): + equipment = Equipment() + self.assertEqual(0, equipment.prior_usage) + + def test_prior_usage_set_to_integer(self): + equipment = Equipment() + equipment.prior_usage = 2 + self.assertEquals(2, equipment.prior_usage) + + def test_prior_usage_set_to_numeric_string(self): + equipment = Equipment() + equipment.prior_usage = "3" + self.assertEquals(3, equipment.prior_usage) + + def test_prior_usage_set_to_non_numeric_string(self): + equipment = Equipment() + try: + equipment.prior_usage = "test" + except(ValueError): + pass + else: + self.fail("Should not be able to set life expectancy to non numeric value.") + + def test_notes_defaults_to_empty_string(self): + equipment = Equipment() + self.assertEquals(u"", equipment.notes) + + def test_notes_set_to_string(self): + equipment = Equipment() + try: + equipment.notes = "100$ Shoes" + except(TypeError): + pass + else: + self.fail("Should not be able to set notes to non-unicode string value.") + + def test_notes_set_to_unicode_string(self): + equipment = Equipment() + equipment.notes = u"Zapatos de €100." + self.assertEquals(u"Zapatos de €100.", equipment.notes) + + def test_notes_set_to_non_string(self): + equipment = Equipment() + try: + equipment.notes = 42 + except(TypeError): + pass + else: + self.fail("Should not be able to set notes to non-string value.") + + def test_equals_new_instances(self): + equipment1 = Equipment() + equipment2 = Equipment() + self.assertNotEqual(equipment1, equipment2, "") + + def test_equals_instances_with_same_id(self): + equipment1 = Equipment() + equipment1.id = 1 + equipment2 = Equipment() + equipment2.id = 1 + self.assertEqual(equipment1, equipment2, "Equipment instances with same id should be equal.") + + def test_equals_instances_with_different_ids(self): + equipment1 = Equipment() + equipment1.id = 1 + equipment2 = Equipment() + equipment2.id = 2 + self.assertNotEqual(equipment1, equipment2, "Equipment instances with different ids should not be equal.") + +class EquipmentServiceTest(unittest.TestCase): + + def setUp(self): + self.mock_ddbb = mock.Mock(spec=Sql) + self.equipment_service = EquipmentService(self.mock_ddbb) + + def tearDown(self): + pass + + def test_get_equipment_item(self): + self.mock_ddbb.select.return_value = [(1, u"Test Description", True, 500, 200, u"Test notes.")] + item = self.equipment_service.get_equipment_item(1) + self.assertEquals(1, item.id) + self.assertEquals("Test Description", item.description) + self.assertTrue(item.active) + self.assertEquals(500, item.life_expectancy) + self.assertEquals(200, item.prior_usage) + self.assertEquals("Test notes.", item.notes) + + def test_get_equipment_item_non_unicode(self): + self.mock_ddbb.select.return_value = [(1, "Test Description", True, 500, 200, "Test notes.")] + item = self.equipment_service.get_equipment_item(1) + self.assertEquals("Test Description", item.description) + self.assertEquals("Test notes.", item.notes) + + def test_get_equipment_item_non_existant(self): + self.mock_ddbb.select.return_value = [] + item = self.equipment_service.get_equipment_item(1) + self.assertEquals(None, item) + + def test_get_all_equipment(self): + self.mock_ddbb.select.return_value = [(1, u"Test item 1", True, 500, 200, u"Test notes 1."), + (2, u"Test item 2", False, 600, 300, u"Test notes 2.")] + items = self.equipment_service.get_all_equipment() + item = items[0] + self.assertEquals(1, item.id) + self.assertEquals("Test item 1", item.description) + self.assertTrue(item.active) + self.assertEquals(500, item.life_expectancy) + self.assertEquals(200, item.prior_usage) + self.assertEquals("Test notes 1.", item.notes) + item = items[1] + self.assertEquals(2, item.id) + self.assertEquals("Test item 2", item.description) + self.assertFalse(item.active) + self.assertEquals(600, item.life_expectancy) + self.assertEquals(300, item.prior_usage) + self.assertEquals("Test notes 2.", item.notes) + + def test_get_all_equipment_non_existant(self): + self.mock_ddbb.select.return_value = [] + items = self.equipment_service.get_all_equipment() + self.assertEquals([], items) + + def test_get_active_equipment(self): + self.mock_ddbb.select.return_value = [(1, u"Test item 1", True, 500, 200, u"Test notes 1."), + (2, u"Test item 2", True, 600, 300, u"Test notes 2.")] + items = self.equipment_service.get_active_equipment() + item = items[0] + self.assertEquals(1, item.id) + self.assertEquals("Test item 1", item.description) + self.assertTrue(item.active) + self.assertEquals(500, item.life_expectancy) + self.assertEquals(200, item.prior_usage) + self.assertEquals("Test notes 1.", item.notes) + item = items[1] + self.assertEquals(2, item.id) + self.assertEquals("Test item 2", item.description) + self.assertTrue(item.active) + self.assertEquals(600, item.life_expectancy) + self.assertEquals(300, item.prior_usage) + self.assertEquals("Test notes 2.", item.notes) + + def test_get_active_equipment_non_existant(self): + self.mock_ddbb.select.return_value = [] + items = self.equipment_service.get_active_equipment() + self.assertEquals([], items) + + def test_store_equipment(self): + equipment = Equipment() + equipment.description = u"test description" + equipment_ids = [] + def mock_select(table, columns, where): + if columns == "id": + return equipment_ids + else: + return [(2, u"", 1, 0, 0,u"")] + def update_equipment_ids(*args): + equipment_ids.append([1]) + self.mock_ddbb.select = mock.Mock(wraps=mock_select) + self.mock_ddbb.insert.side_effect = update_equipment_ids + stored_equipment = self.equipment_service.store_equipment(equipment) + self.mock_ddbb.insert.assert_called_with("equipment", + "description,active,life_expectancy,prior_usage,notes", + ["test description", 1, 0, 0,"" ]) + self.assertEquals(2, stored_equipment.id) + + def test_store_equipment_duplicate_description(self): + self.mock_ddbb.select.return_value = [(1,)] + equipment = Equipment() + equipment.description = u"test item" + try: + self.equipment_service.store_equipment(equipment) + self.fail("Should not be able to store new item with non-unique description.") + except(EquipmentServiceException): + pass + + def test_update_equipment(self): + equipment = Equipment() + equipment.id = 1 + equipment.description = u"new description" + self.mock_ddbb.select.return_value = [(1, u"old description", 1, 0, 0,u"")] + self.equipment_service.store_equipment(equipment) + self.mock_ddbb.update.assert_called_with("equipment", + "description,active,life_expectancy,prior_usage,notes", + ["new description", 1, 0, 0,"" ], + "id = 1") + + def test_update_equipment_non_existant(self): + self.mock_ddbb.select.return_value = [] + equipment = Equipment() + equipment.id = 1 + try: + self.equipment_service.store_equipment(equipment) + self.fail("Should not be able to update an item which did not previously exist.") + except(EquipmentServiceException): + pass + + def test_update_equipment_duplicate_description(self): + self.mock_ddbb.select.return_value = [(1, u"test item", True, 500, 200, u"Test notes.")] + equipment = Equipment() + equipment.id = 2 + equipment.description = u"test item" + try: + self.equipment_service.store_equipment(equipment) + self.fail("Should not be able to change item description to non-unique value.") + except(EquipmentServiceException): + pass + + def test_get_equipment_usage(self): + self.mock_ddbb.select.return_value = [(250,)] + equipment = Equipment() + equipment.id = 1 + usage = self.equipment_service.get_equipment_usage(equipment) + self.assertEquals(250, usage) + + def test_get_equipment_usage_none(self): + self.mock_ddbb.select.return_value = [(None,)] + equipment = Equipment() + equipment.id = 1 + usage = self.equipment_service.get_equipment_usage(equipment) + self.assertEquals(0, usage) + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() Copied: pytrainer/trunk/pytrainer/test/gui/equipment_test.py (from rev 836, pytrainer/trunk/test/pytrainer/gui/equipment_test.py) =================================================================== --- pytrainer/trunk/pytrainer/test/gui/equipment_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/gui/equipment_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -0,0 +1,162 @@ +# -*- coding: utf-8 -*- +from unittest import TestCase +from mock import Mock +from pytrainer.equipment import Equipment, EquipmentService +from pytrainer.gui.equipment import EquipmentStore + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +class EquipmentStoreTest(TestCase): + + def setUp(self): + self.mock_equipment_service = Mock(spec=EquipmentService) + self.mock_equipment_service.get_equipment_usage.return_value = 0 + + def tearDown(self): + pass + + def test_get_item_id(self): + equipment = Equipment() + equipment.id = 1 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals(1, equipment_store.get_value(iter, 0)) + + def test_get_item_description(self): + equipment = Equipment() + equipment.id = 1 + equipment.description = u"item description" + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals("item description", equipment_store.get_value(iter, 1)) + + def test_get_item_usage_percent(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 100 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals(50, equipment_store.get_value(iter, 2)) + + def test_get_item_usage_percent_prior_usage(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + equipment.prior_usage = 50 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 100 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals(75, equipment_store.get_value(iter, 2)) + + def test_get_item_usage_percent_zero_usage(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 0 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals(0, equipment_store.get_value(iter, 2)) + + def test_get_item_usage_percent_usage_exceeds_life_expectancy(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 300 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals(100, equipment_store.get_value(iter, 2), "Progress bar cannot exceed 100%.") + + + def test_get_item_usage_text(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 100 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals("100 / 200", equipment_store.get_value(iter, 3)) + + def test_get_item_usage_text_rounded(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 100.5 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals("101 / 200", equipment_store.get_value(iter, 3)) + + def test_get_item_usage_text_prior_usage(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + equipment.prior_usage = 50 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 100 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals("150 / 200", equipment_store.get_value(iter, 3)) + + def test_get_item_usage_text_zero_usage(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 0 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals("0 / 200", equipment_store.get_value(iter, 3)) + + def test_get_item_usage_text_usage_exceeds_life_expectancy(self): + equipment = Equipment() + equipment.id = 1 + equipment.life_expectancy = 200 + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + self.mock_equipment_service.get_equipment_usage.return_value = 300 + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertEquals("300 / 200", equipment_store.get_value(iter, 3)) + + def test_get_item_active(self): + equipment = Equipment() + equipment.id = 1 + equipment.active = False + self.mock_equipment_service.get_all_equipment.return_value = [equipment] + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + self.assertFalse(equipment_store.get_value(iter, 4)) + + def test_multiple_equipment_items(self): + equipment1 = Equipment() + equipment1.id = 1 + equipment2 = Equipment() + equipment2.id = 2 + self.mock_equipment_service.get_all_equipment.return_value = [equipment1, equipment2] + equipment_store = EquipmentStore(self.mock_equipment_service) + iter = equipment_store.get_iter_first() + iter = equipment_store.iter_next(iter) + self.assertEquals(2, equipment_store.get_value(iter, 0)) + + Copied: pytrainer/trunk/pytrainer/test/upgrade/data_test.py (from rev 836, pytrainer/trunk/test/pytrainer/upgrade/data_test.py) =================================================================== --- pytrainer/trunk/pytrainer/test/upgrade/data_test.py (rev 0) +++ pytrainer/trunk/pytrainer/test/upgrade/data_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -0,0 +1,106 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import unittest +from mock import Mock +from pytrainer.upgrade.data import InstalledData, DataState +import pytrainer.upgrade.context + +class InstalledDataTest(unittest.TestCase): + + def setUp(self): + self._mock_migratable_db = Mock() + self._mock_ddbb = Mock() + self._mock_version_provider = Mock() + self._mock_upgrade_context = Mock() + self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_version_provider, self._mock_upgrade_context) + + def test_get_version_should_return_migrate_version_when_available(self): + self._mock_migratable_db.get_version.return_value = 1 + self.assertEquals(1, self._installed_data.get_version()) + + def test_get_version_should_return_legacy_version_when_available(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_version_provider.get_legacy_version.return_value = 2 + self.assertEquals(2, self._installed_data.get_version()) + + def test_get_version_should_return_none_when_no_existing_version(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_version_provider.get_legacy_version.return_value = None + self.assertEquals(None, self._installed_data.get_version()) + + def test_get_state_should_return_current_when_data_version_equals_repository_version(self): + self._mock_migratable_db.get_version.return_value = 1 + self._mock_migratable_db.get_upgrade_version.return_value = 1 + self.assertEquals(DataState.CURRENT, self._installed_data.get_state()) + + def test_get_state_should_return_fresh_when_data_version_unavailable(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_version_provider.get_legacy_version.return_value = None + self.assertEquals(DataState.FRESH, self._installed_data.get_state()) + + def test_get_state_should_return_stale_when_data_version_less_than_repository_version(self): + self._mock_migratable_db.get_version.return_value = 1 + self._mock_migratable_db.get_upgrade_version.return_value = 2 + self.assertEquals(DataState.STALE, self._installed_data.get_state()) + + def test_get_state_should_return_legacy_when_data_version_is_legacy(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_version_provider.get_legacy_version.return_value = 1 + self.assertEquals(DataState.LEGACY, self._installed_data.get_state()) + + def test_get_state_should_raise_error_when_version_too_large(self): + self._mock_migratable_db.is_versioned.return_value = True + self._mock_migratable_db.get_version.return_value = 2 + self._mock_migratable_db.get_upgrade_version.return_value = 1 + try: + self._installed_data.get_state() + except ValueError: + pass + else: + self.fail() + + def test_get_available_version_returns_migratable_db_upgrade_version(self): + self._mock_migratable_db.get_upgrade_version.return_value = 1 + self.assertEquals(1, self._installed_data.get_available_version()) + + def test_is_versioned_returns_migratable_db_is_versioned(self): + self._mock_migratable_db.is_versioned.return_value = True + self.assertEquals(True, self._installed_data.is_versioned()) + + def test_initialize_version_versions_migratable_db(self): + self._installed_data.initialize_version(1) + self._mock_migratable_db.version.assert_called_with(1) + + def test_initialize_creates_db_tables(self): + self._installed_data.initialize() + self.assertTrue(self._mock_ddbb.create_tables.called) + + def test_upgrade_upgrades_migratable_db(self): + self._installed_data.upgrade() + self.assertTrue(self._mock_migratable_db.upgrade.called) + + def test_upgrade_initializes_global_upgrade_context(self): + self._installed_data.upgrade() + self.assertEqual(self._mock_upgrade_context, pytrainer.upgrade.context.UPGRADE_CONTEXT) + + def test_update_to_current_delegates_to_data_state(self): + mock_state = Mock() + self._installed_data.get_state = Mock(return_value=mock_state) + self._installed_data.update_to_current() + self.assertTrue(mock_state.update_to_current.called) Deleted: pytrainer/trunk/test/pytrainer/environment_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/environment_test.py 2011-08-06 13:13:35 UTC (rev 836) +++ pytrainer/trunk/test/pytrainer/environment_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -1,75 +0,0 @@ -# -*- coding: iso-8859-1 -*- - -#Copyright (C) Nathan Jones nc...@us... - -#This program is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public License -#as published by the Free Software Foundation; either version 2 -#of the License, or (at your option) any later version. - -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with this program; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import unittest - -from mock import Mock - -import pytrainer.platform -from pytrainer.environment import Environment - -TEST_DIR_NAME = "/test/.pytrainer_test" - -PLATFORM = pytrainer.platform.get_platform() - -class Test(unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass - - def test_get_conf_dir(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME, environment.conf_dir) - - def test_get_conf_dir_default(self): - test_platform = Mock(spec=pytrainer.platform.get_platform()) - test_platform.get_default_conf_dir.return_value = "/test/.pytrainer_test" - environment = Environment(test_platform, None) - self.assertEquals("/test/.pytrainer_test", environment.conf_dir) - - def test_get_conf_file(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME + "/conf.xml", environment.conf_file) - - def test_get_log_file(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME + "/log.out", environment.log_file) - - def test_get_temp_dir(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME + "/tmp", environment.temp_dir) - - def test_get_gpx_dir(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME + "/gpx", environment.gpx_dir) - - def test_get_extension_dir(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME + "/extensions", environment.extension_dir) - - def test_get_plugin_dir(self): - environment = Environment(PLATFORM, TEST_DIR_NAME) - self.assertEquals(TEST_DIR_NAME + "/plugins", environment.plugin_dir) - - -if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.testName'] - unittest.main() \ No newline at end of file Deleted: pytrainer/trunk/test/pytrainer/equipment_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/equipment_test.py 2011-08-06 13:13:35 UTC (rev 836) +++ pytrainer/trunk/test/pytrainer/equipment_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -1,348 +0,0 @@ -# -*- coding: utf-8 -*- - -#Copyright (C) Nathan Jones nc...@us... - -#This program is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public License -#as published by the Free Software Foundation; either version 2 -#of the License, or (at your option) any later version. - -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with this program; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import unittest -import mock -from pytrainer.equipment import Equipment, EquipmentService,\ - EquipmentServiceException -from pytrainer.lib.sqliteUtils import Sql - -class EquipmentTest(unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass - - def test_id_defaults_to_none(self): - equipment = Equipment() - self.assertEqual(None, equipment.id) - - def test_id_set_to_integer(self): - equipment = Equipment() - equipment.id = 2 - self.assertEquals(2, equipment.id) - - def test_id_set_to_numeric_string(self): - equipment = Equipment() - equipment.id = "3" - self.assertEquals(3, equipment.id) - - def test_id_set_to_non_numeric_string(self): - equipment = Equipment() - try: - equipment.id = "test" - except(ValueError): - pass - else: - self.fail("Should not be able to set equipment id to non numeric value.") - - def test_description_defaults_to_empty_string(self): - equipment = Equipment() - self.assertEquals(u"", equipment.description) - - def test_description_set_to_string(self): - equipment = Equipment() - try: - equipment.description = "100$ Shoes" - except(TypeError): - pass - else: - self.fail("Should not be able to set description to non unicode string value.") - - def test_description_set_to_unicode_string(self): - equipment = Equipment() - equipment.description = u"Zapatos de €100" - self.assertEquals(u"Zapatos de €100", equipment.description) - - def test_description_set_to_non_string(self): - equipment = Equipment() - try: - equipment.description = 42 - except(TypeError): - pass - else: - self.fail("Should not be able to set description to non string value.") - - def test_active_defaults_to_true(self): - equipment = Equipment() - self.assertTrue(equipment.active) - - def test_active_set_to_boolean(self): - equipment = Equipment() - equipment.active = False - self.assertFalse(equipment.active) - - def test_active_set_to_non_boolean(self): - equipment = Equipment() - try: - equipment.active = "test" - except(TypeError): - pass - else: - self.fail("Should not be able to set active to non-boolean value.") - - def test_life_expectancy_defaults_to_zero(self): - equipment = Equipment() - self.assertEqual(0, equipment.life_expectancy) - - def test_life_expectancy_set_to_integer(self): - equipment = Equipment() - equipment.life_expectancy = 2 - self.assertEquals(2, equipment.life_expectancy) - - def test_life_expectancy_set_to_numeric_string(self): - equipment = Equipment() - equipment.life_expectancy = "3" - self.assertEquals(3, equipment.life_expectancy) - - def test_life_expectancy_set_to_non_numeric_string(self): - equipment = Equipment() - try: - equipment.life_expectancy = "test" - except(ValueError): - pass - else: - self.fail("Should not be able to set life expectancy to non numeric value.") - - def test_prior_usage_defaults_to_zero(self): - equipment = Equipment() - self.assertEqual(0, equipment.prior_usage) - - def test_prior_usage_set_to_integer(self): - equipment = Equipment() - equipment.prior_usage = 2 - self.assertEquals(2, equipment.prior_usage) - - def test_prior_usage_set_to_numeric_string(self): - equipment = Equipment() - equipment.prior_usage = "3" - self.assertEquals(3, equipment.prior_usage) - - def test_prior_usage_set_to_non_numeric_string(self): - equipment = Equipment() - try: - equipment.prior_usage = "test" - except(ValueError): - pass - else: - self.fail("Should not be able to set life expectancy to non numeric value.") - - def test_notes_defaults_to_empty_string(self): - equipment = Equipment() - self.assertEquals(u"", equipment.notes) - - def test_notes_set_to_string(self): - equipment = Equipment() - try: - equipment.notes = "100$ Shoes" - except(TypeError): - pass - else: - self.fail("Should not be able to set notes to non-unicode string value.") - - def test_notes_set_to_unicode_string(self): - equipment = Equipment() - equipment.notes = u"Zapatos de €100." - self.assertEquals(u"Zapatos de €100.", equipment.notes) - - def test_notes_set_to_non_string(self): - equipment = Equipment() - try: - equipment.notes = 42 - except(TypeError): - pass - else: - self.fail("Should not be able to set notes to non-string value.") - - def test_equals_new_instances(self): - equipment1 = Equipment() - equipment2 = Equipment() - self.assertNotEqual(equipment1, equipment2, "") - - def test_equals_instances_with_same_id(self): - equipment1 = Equipment() - equipment1.id = 1 - equipment2 = Equipment() - equipment2.id = 1 - self.assertEqual(equipment1, equipment2, "Equipment instances with same id should be equal.") - - def test_equals_instances_with_different_ids(self): - equipment1 = Equipment() - equipment1.id = 1 - equipment2 = Equipment() - equipment2.id = 2 - self.assertNotEqual(equipment1, equipment2, "Equipment instances with different ids should not be equal.") - -class EquipmentServiceTest(unittest.TestCase): - - def setUp(self): - self.mock_ddbb = mock.Mock(spec=Sql) - self.equipment_service = EquipmentService(self.mock_ddbb) - - def tearDown(self): - pass - - def test_get_equipment_item(self): - self.mock_ddbb.select.return_value = [(1, u"Test Description", True, 500, 200, u"Test notes.")] - item = self.equipment_service.get_equipment_item(1) - self.assertEquals(1, item.id) - self.assertEquals("Test Description", item.description) - self.assertTrue(item.active) - self.assertEquals(500, item.life_expectancy) - self.assertEquals(200, item.prior_usage) - self.assertEquals("Test notes.", item.notes) - - def test_get_equipment_item_non_unicode(self): - self.mock_ddbb.select.return_value = [(1, "Test Description", True, 500, 200, "Test notes.")] - item = self.equipment_service.get_equipment_item(1) - self.assertEquals("Test Description", item.description) - self.assertEquals("Test notes.", item.notes) - - def test_get_equipment_item_non_existant(self): - self.mock_ddbb.select.return_value = [] - item = self.equipment_service.get_equipment_item(1) - self.assertEquals(None, item) - - def test_get_all_equipment(self): - self.mock_ddbb.select.return_value = [(1, u"Test item 1", True, 500, 200, u"Test notes 1."), - (2, u"Test item 2", False, 600, 300, u"Test notes 2.")] - items = self.equipment_service.get_all_equipment() - item = items[0] - self.assertEquals(1, item.id) - self.assertEquals("Test item 1", item.description) - self.assertTrue(item.active) - self.assertEquals(500, item.life_expectancy) - self.assertEquals(200, item.prior_usage) - self.assertEquals("Test notes 1.", item.notes) - item = items[1] - self.assertEquals(2, item.id) - self.assertEquals("Test item 2", item.description) - self.assertFalse(item.active) - self.assertEquals(600, item.life_expectancy) - self.assertEquals(300, item.prior_usage) - self.assertEquals("Test notes 2.", item.notes) - - def test_get_all_equipment_non_existant(self): - self.mock_ddbb.select.return_value = [] - items = self.equipment_service.get_all_equipment() - self.assertEquals([], items) - - def test_get_active_equipment(self): - self.mock_ddbb.select.return_value = [(1, u"Test item 1", True, 500, 200, u"Test notes 1."), - (2, u"Test item 2", True, 600, 300, u"Test notes 2.")] - items = self.equipment_service.get_active_equipment() - item = items[0] - self.assertEquals(1, item.id) - self.assertEquals("Test item 1", item.description) - self.assertTrue(item.active) - self.assertEquals(500, item.life_expectancy) - self.assertEquals(200, item.prior_usage) - self.assertEquals("Test notes 1.", item.notes) - item = items[1] - self.assertEquals(2, item.id) - self.assertEquals("Test item 2", item.description) - self.assertTrue(item.active) - self.assertEquals(600, item.life_expectancy) - self.assertEquals(300, item.prior_usage) - self.assertEquals("Test notes 2.", item.notes) - - def test_get_active_equipment_non_existant(self): - self.mock_ddbb.select.return_value = [] - items = self.equipment_service.get_active_equipment() - self.assertEquals([], items) - - def test_store_equipment(self): - equipment = Equipment() - equipment.description = u"test description" - equipment_ids = [] - def mock_select(table, columns, where): - if columns == "id": - return equipment_ids - else: - return [(2, u"", 1, 0, 0,u"")] - def update_equipment_ids(*args): - equipment_ids.append([1]) - self.mock_ddbb.select = mock.Mock(wraps=mock_select) - self.mock_ddbb.insert.side_effect = update_equipment_ids - stored_equipment = self.equipment_service.store_equipment(equipment) - self.mock_ddbb.insert.assert_called_with("equipment", - "description,active,life_expectancy,prior_usage,notes", - ["test description", 1, 0, 0,"" ]) - self.assertEquals(2, stored_equipment.id) - - def test_store_equipment_duplicate_description(self): - self.mock_ddbb.select.return_value = [(1,)] - equipment = Equipment() - equipment.description = u"test item" - try: - self.equipment_service.store_equipment(equipment) - self.fail("Should not be able to store new item with non-unique description.") - except(EquipmentServiceException): - pass - - def test_update_equipment(self): - equipment = Equipment() - equipment.id = 1 - equipment.description = u"new description" - self.mock_ddbb.select.return_value = [(1, u"old description", 1, 0, 0,u"")] - self.equipment_service.store_equipment(equipment) - self.mock_ddbb.update.assert_called_with("equipment", - "description,active,life_expectancy,prior_usage,notes", - ["new description", 1, 0, 0,"" ], - "id = 1") - - def test_update_equipment_non_existant(self): - self.mock_ddbb.select.return_value = [] - equipment = Equipment() - equipment.id = 1 - try: - self.equipment_service.store_equipment(equipment) - self.fail("Should not be able to update an item which did not previously exist.") - except(EquipmentServiceException): - pass - - def test_update_equipment_duplicate_description(self): - self.mock_ddbb.select.return_value = [(1, u"test item", True, 500, 200, u"Test notes.")] - equipment = Equipment() - equipment.id = 2 - equipment.description = u"test item" - try: - self.equipment_service.store_equipment(equipment) - self.fail("Should not be able to change item description to non-unique value.") - except(EquipmentServiceException): - pass - - def test_get_equipment_usage(self): - self.mock_ddbb.select.return_value = [(250,)] - equipment = Equipment() - equipment.id = 1 - usage = self.equipment_service.get_equipment_usage(equipment) - self.assertEquals(250, usage) - - def test_get_equipment_usage_none(self): - self.mock_ddbb.select.return_value = [(None,)] - equipment = Equipment() - equipment.id = 1 - usage = self.equipment_service.get_equipment_usage(equipment) - self.assertEquals(0, usage) - -if __name__ == "__main__": - #import sys;sys.argv = ['', 'Test.testName'] - unittest.main() Deleted: pytrainer/trunk/test/pytrainer/gui/equipment_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/gui/equipment_test.py 2011-08-06 13:13:35 UTC (rev 836) +++ pytrainer/trunk/test/pytrainer/gui/equipment_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -1,162 +0,0 @@ -# -*- coding: utf-8 -*- -from unittest import TestCase -from mock import Mock -from pytrainer.equipment import Equipment, EquipmentService -from pytrainer.gui.equipment import EquipmentStore - -#Copyright (C) Nathan Jones nc...@us... - -#This program is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public License -#as published by the Free Software Foundation; either version 2 -#of the License, or (at your option) any later version. - -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with this program; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -class EquipmentStoreTest(TestCase): - - def setUp(self): - self.mock_equipment_service = Mock(spec=EquipmentService) - self.mock_equipment_service.get_equipment_usage.return_value = 0 - - def tearDown(self): - pass - - def test_get_item_id(self): - equipment = Equipment() - equipment.id = 1 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals(1, equipment_store.get_value(iter, 0)) - - def test_get_item_description(self): - equipment = Equipment() - equipment.id = 1 - equipment.description = u"item description" - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals("item description", equipment_store.get_value(iter, 1)) - - def test_get_item_usage_percent(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 100 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals(50, equipment_store.get_value(iter, 2)) - - def test_get_item_usage_percent_prior_usage(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - equipment.prior_usage = 50 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 100 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals(75, equipment_store.get_value(iter, 2)) - - def test_get_item_usage_percent_zero_usage(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 0 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals(0, equipment_store.get_value(iter, 2)) - - def test_get_item_usage_percent_usage_exceeds_life_expectancy(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 300 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals(100, equipment_store.get_value(iter, 2), "Progress bar cannot exceed 100%.") - - - def test_get_item_usage_text(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 100 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals("100 / 200", equipment_store.get_value(iter, 3)) - - def test_get_item_usage_text_rounded(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 100.5 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals("101 / 200", equipment_store.get_value(iter, 3)) - - def test_get_item_usage_text_prior_usage(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - equipment.prior_usage = 50 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 100 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals("150 / 200", equipment_store.get_value(iter, 3)) - - def test_get_item_usage_text_zero_usage(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 0 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals("0 / 200", equipment_store.get_value(iter, 3)) - - def test_get_item_usage_text_usage_exceeds_life_expectancy(self): - equipment = Equipment() - equipment.id = 1 - equipment.life_expectancy = 200 - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - self.mock_equipment_service.get_equipment_usage.return_value = 300 - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertEquals("300 / 200", equipment_store.get_value(iter, 3)) - - def test_get_item_active(self): - equipment = Equipment() - equipment.id = 1 - equipment.active = False - self.mock_equipment_service.get_all_equipment.return_value = [equipment] - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - self.assertFalse(equipment_store.get_value(iter, 4)) - - def test_multiple_equipment_items(self): - equipment1 = Equipment() - equipment1.id = 1 - equipment2 = Equipment() - equipment2.id = 2 - self.mock_equipment_service.get_all_equipment.return_value = [equipment1, equipment2] - equipment_store = EquipmentStore(self.mock_equipment_service) - iter = equipment_store.get_iter_first() - iter = equipment_store.iter_next(iter) - self.assertEquals(2, equipment_store.get_value(iter, 0)) - - Deleted: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-06 13:13:35 UTC (rev 836) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-08 12:39:11 UTC (rev 837) @@ -1,106 +0,0 @@ -# -*- coding: iso-8859-1 -*- - -#Copyright (C) Nathan Jones nc...@us... - -#This program is free software; you can redistribute it and/or -#modify it under the terms of the GNU General Public License -#as published by the Free Software Foundation; either version 2 -#of the License, or (at your option) any later version. - -#This program is distributed in the hope that it will be useful, -#but WITHOUT ANY WARRANTY; without even the implied warranty of -#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -#GNU General Public License for more details. - -#You should have received a copy of the GNU General Public License -#along with this program; if not, write to the Free Software -#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -import unittest -from mock import Mock -from pytrainer.upgrade.data import InstalledData, DataState -import pytrainer.upgrade.context - -class InstalledDataTest(unittest.TestCase): - - def setUp(self): - self._mock_migratable_db = Mock() - self._mock_ddbb = Mock() - self._mock_version_provider = Mock() - self._mock_upgrade_context = Mock() - self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_version_provider, self._mock_upgrade_context) - - def test_get_version_should_return_migrate_version_when_available(self): - self._mock_migratable_db.get_version.return_value = 1 - self.assertEquals(1, self._installed_data.get_version()) - - def test_get_version_should_return_legacy_version_when_available(self): - self._mock_migratable_db.is_versioned.return_value = False - self._mock_version_provider.get_legacy_version.return_value = 2 - self.assertEquals(2, self._installed_data.get_version()) - - def test_get_version_should_return_none_when_no_existing_version(self): - self._mock_migratable_db.is_versioned.return_value = False - self._mock_version_provider.get_legacy_version.return_value = None - self.assertEquals(None, self._installed_data.get_version()) - - def test_get_state_should_return_current_when_data_version_equals_repository_version(self): - self._mock_migratable_db.get_version.return_value = 1 - self._mock_migratable_db.get_upgrade_version.return_value = 1 - self.assertEquals(DataState.CURRENT, self._installed_data.get_state()) - - def test_get_state_should_return_fresh_when_data_version_unavailable(self): - self._mock_migratable_db.is_versioned.return_value = False - self._mock_version_provider.get_legacy_version.return_value = None - self.assertEquals(DataState.FRESH, self._installed_data.get_state()) - -... [truncated message content] |
From: <nc...@us...> - 2011-08-06 13:13:41
|
Revision: 836 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=836&view=rev Author: ncjones Date: 2011-08-06 13:13:35 +0000 (Sat, 06 Aug 2011) Log Message: ----------- Remove unused build_db method. Modified Paths: -------------- pytrainer/trunk/pytrainer/gui/windowprofile.py pytrainer/trunk/pytrainer/lib/ddbb.py pytrainer/trunk/pytrainer/profile.py Modified: pytrainer/trunk/pytrainer/gui/windowprofile.py =================================================================== --- pytrainer/trunk/pytrainer/gui/windowprofile.py 2011-08-06 11:14:27 UTC (rev 835) +++ pytrainer/trunk/pytrainer/gui/windowprofile.py 2011-08-06 13:13:35 UTC (rev 836) @@ -196,7 +196,6 @@ ) self.sportTreeView.set_model(store) self.sportTreeView.set_cursor(0) - #self.sportlistbutton.hide() self.sportlist.show() elif frame == 5: #Startup Parameters page selected self.init_params_tab() @@ -277,14 +276,6 @@ logging.debug("NewGraph deactivated") self.pytrainer_main.startup_options.newgraph = False - def on_sportlistbutton_clicked(self,widget): - sport_list = self.parent.getSportList() - if sport_list == 0: - self.parent.build_ddbb() - self.sportlistbutton.hide() - self.sportlist.show() - - def on_accept_clicked(self,widget): self.saveOptions() self.close_window() Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2011-08-06 11:14:27 UTC (rev 835) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2011-08-06 13:13:35 UTC (rev 836) @@ -139,12 +139,6 @@ def disconnect(self): self.ddbbObject.disconnect() - def build_ddbb(self): #TODO Is this needed? - self.ddbbObject.createDDBB() - self.ddbbObject.connect() - self.ddbbObject.createTables() - self.ddbbObject.createTableVersion() - def select(self,table,cells,condition=None, mod=None): return self.ddbbObject.select(table,cells,condition,mod) Modified: pytrainer/trunk/pytrainer/profile.py =================================================================== --- pytrainer/trunk/pytrainer/profile.py 2011-08-06 11:14:27 UTC (rev 835) +++ pytrainer/trunk/pytrainer/profile.py 2011-08-06 13:13:35 UTC (rev 836) @@ -261,10 +261,6 @@ logging.debug("--") return self.pytrainer_main.ddbb.select("sports","name,met,weight,max_pace,color","name=\"%s\""%namesport)[0] - def build_ddbb(self): - logging.debug("--") - self.pytrainer_main.ddbb.build_ddbb() - def editProfile(self): logging.debug(">>") from gui.windowprofile import WindowProfile This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-06 11:14:33
|
Revision: 835 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=835&view=rev Author: ncjones Date: 2011-08-06 11:14:27 +0000 (Sat, 06 Aug 2011) Log Message: ----------- Add unit tests for InstalledData. Modified Paths: -------------- pytrainer/trunk/test/pytrainer/upgrade/data_test.py Modified: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-06 11:14:02 UTC (rev 834) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-06 11:14:27 UTC (rev 835) @@ -19,6 +19,7 @@ import unittest from mock import Mock from pytrainer.upgrade.data import InstalledData, DataState +import pytrainer.upgrade.context class InstalledDataTest(unittest.TestCase): @@ -73,3 +74,33 @@ pass else: self.fail() + + def test_get_available_version_returns_migratable_db_upgrade_version(self): + self._mock_migratable_db.get_upgrade_version.return_value = 1 + self.assertEquals(1, self._installed_data.get_available_version()) + + def test_is_versioned_returns_migratable_db_is_versioned(self): + self._mock_migratable_db.is_versioned.return_value = True + self.assertEquals(True, self._installed_data.is_versioned()) + + def test_initialize_version_versions_migratable_db(self): + self._installed_data.initialize_version(1) + self._mock_migratable_db.version.assert_called_with(1) + + def test_initialize_creates_db_tables(self): + self._installed_data.initialize() + self.assertTrue(self._mock_ddbb.create_tables.called) + + def test_upgrade_upgrades_migratable_db(self): + self._installed_data.upgrade() + self.assertTrue(self._mock_migratable_db.upgrade.called) + + def test_upgrade_initializes_global_upgrade_context(self): + self._installed_data.upgrade() + self.assertEqual(self._mock_upgrade_context, pytrainer.upgrade.context.UPGRADE_CONTEXT) + + def test_update_to_current_delegates_to_data_state(self): + mock_state = Mock() + self._installed_data.get_state = Mock(return_value=mock_state) + self._installed_data.update_to_current() + self.assertTrue(mock_state.update_to_current.called) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-06 11:14:08
|
Revision: 834 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=834&view=rev Author: ncjones Date: 2011-08-06 11:14:02 +0000 (Sat, 06 Aug 2011) Log Message: ----------- Fix initialisation of upgrade context. Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/test/pytrainer/upgrade/data_test.py Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-04 13:05:34 UTC (rev 833) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-06 11:14:02 UTC (rev 834) @@ -28,17 +28,18 @@ """Initializes the installation's data.""" db_url = ddbb.get_connection_url() migratable_db = MigratableDb(MIGRATE_REPOSITORY_PATH, db_url) - InstalledData(migratable_db, ddbb, LegacyVersionProvider(conf_dir)).update_to_current() + InstalledData(migratable_db, ddbb, LegacyVersionProvider(conf_dir), UpgradeContext(conf_dir)).update_to_current() class InstalledData(object): """Encapsulates an installation's existing data and provides means to check version state and upgrade.""" - def __init__(self, migratable_db, ddbb, legacy_version_provider): + def __init__(self, migratable_db, ddbb, legacy_version_provider, upgrade_context): self._migratable_db = migratable_db self._ddbb = ddbb self._legacy_version_provider = legacy_version_provider + self._upgrade_context = upgrade_context def update_to_current(self): """Check the current state of the installation's data and update them @@ -119,7 +120,7 @@ def upgrade(self): logging.info("Upgrading data from version '%s' to version '%s'.", self.get_version(), self.get_available_version()) - pytrainer.upgrade.context.UPGRADE_CONTEXT = UpgradeContext(self._conf_dir) + pytrainer.upgrade.context.UPGRADE_CONTEXT = self._upgrade_context self._migratable_db.upgrade() class DataState(object): Modified: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-04 13:05:34 UTC (rev 833) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-06 11:14:02 UTC (rev 834) @@ -26,7 +26,8 @@ self._mock_migratable_db = Mock() self._mock_ddbb = Mock() self._mock_version_provider = Mock() - self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_version_provider) + self._mock_upgrade_context = Mock() + self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_version_provider, self._mock_upgrade_context) def test_get_version_should_return_migrate_version_when_available(self): self._mock_migratable_db.get_version.return_value = 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-04 13:05:40
|
Revision: 833 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=833&view=rev Author: ncjones Date: 2011-08-04 13:05:34 +0000 (Thu, 04 Aug 2011) Log Message: ----------- Return None instead of -1 to indicate no version. Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/test/pytrainer/upgrade/data_test.py Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-04 13:05:04 UTC (rev 832) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-04 13:05:34 UTC (rev 833) @@ -74,7 +74,7 @@ else: return DataState.STALE else: - if version == -1: + if version == None: return DataState.FRESH else: return DataState.LEGACY @@ -82,7 +82,7 @@ def get_version(self): """Get the version number of an installation's data. - If the data is empty then -1 is returned.""" + If the data is empty then None is returned.""" if self.is_versioned(): return self._migratable_db.get_version() else: @@ -99,7 +99,7 @@ return 10 elif legacy_version == 9: return 10 - return -1 + return None def get_available_version(self): return self._migratable_db.get_upgrade_version() Modified: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-04 13:05:04 UTC (rev 832) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-04 13:05:34 UTC (rev 833) @@ -37,10 +37,10 @@ self._mock_version_provider.get_legacy_version.return_value = 2 self.assertEquals(2, self._installed_data.get_version()) - def test_get_version_should_return_negative_one_when_no_existing_version(self): + def test_get_version_should_return_none_when_no_existing_version(self): self._mock_migratable_db.is_versioned.return_value = False self._mock_version_provider.get_legacy_version.return_value = None - self.assertEquals(-1, self._installed_data.get_version()) + self.assertEquals(None, self._installed_data.get_version()) def test_get_state_should_return_current_when_data_version_equals_repository_version(self): self._mock_migratable_db.get_version.return_value = 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-04 13:05:10
|
Revision: 832 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=832&view=rev Author: ncjones Date: 2011-08-04 13:05:04 +0000 (Thu, 04 Aug 2011) Log Message: ----------- Add logging when initializing environment. Modified Paths: -------------- pytrainer/trunk/pytrainer/environment.py pytrainer/trunk/pytrainer/main.py Modified: pytrainer/trunk/pytrainer/environment.py =================================================================== --- pytrainer/trunk/pytrainer/environment.py 2011-08-04 13:04:27 UTC (rev 831) +++ pytrainer/trunk/pytrainer/environment.py 2011-08-04 13:05:04 UTC (rev 832) @@ -32,6 +32,7 @@ """ self.conf_dir = conf_dir if conf_dir is not None else platform.get_default_conf_dir() + logging.info("Initializing environment. Conf dir is: '{0}'.".format(self.conf_dir)) self.conf_file = self.conf_dir + "/conf.xml" self.log_file = self.conf_dir + "/log.out" self.temp_dir = self.conf_dir + "/tmp" Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2011-08-04 13:04:27 UTC (rev 831) +++ pytrainer/trunk/pytrainer/main.py 2011-08-04 13:05:04 UTC (rev 832) @@ -58,10 +58,10 @@ self.version ="1.9.0-dev" #Process command line options self.startup_options = self.get_options() + #Setup logging + self.set_logging(self.startup_options.log_level, self.startup_options.log_type) self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) self.environment.create_directories() - #Setup logging - self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-04 13:04:33
|
Revision: 831 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=831&view=rev Author: ncjones Date: 2011-08-04 13:04:27 +0000 (Thu, 04 Aug 2011) Log Message: ----------- Check for invalid database state. Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/test/pytrainer/upgrade/data_test.py Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-04 13:03:44 UTC (rev 830) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-04 13:04:27 UTC (rev 831) @@ -64,13 +64,17 @@ data_state.update_to_current(self) def get_state(self): + version = self.get_version() + available_version= self.get_available_version() if self.is_versioned(): - if self.get_version() == self.get_available_version(): + if version == available_version: return DataState.CURRENT + elif version > available_version: + raise ValueError("Current version ({0}) is greater than available version ({1}).".format(version, available_version)) else: return DataState.STALE else: - if self.get_version() == -1: + if version == -1: return DataState.FRESH else: return DataState.LEGACY Modified: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-04 13:03:44 UTC (rev 830) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-04 13:04:27 UTC (rev 831) @@ -19,7 +19,6 @@ import unittest from mock import Mock from pytrainer.upgrade.data import InstalledData, DataState -from migrate.versioning.exceptions import DatabaseNotControlledError class InstalledDataTest(unittest.TestCase): @@ -53,14 +52,23 @@ self._mock_version_provider.get_legacy_version.return_value = None self.assertEquals(DataState.FRESH, self._installed_data.get_state()) - def test_get_state_should_return_stale_when_data_version_less_than_repository_version(self): self._mock_migratable_db.get_version.return_value = 1 self._mock_migratable_db.get_upgrade_version.return_value = 2 self.assertEquals(DataState.STALE, self._installed_data.get_state()) - def test_get_state_should_return_legacy_when_data_version_is_legacy(self): self._mock_migratable_db.is_versioned.return_value = False self._mock_version_provider.get_legacy_version.return_value = 1 self.assertEquals(DataState.LEGACY, self._installed_data.get_state()) + + def test_get_state_should_raise_error_when_version_too_large(self): + self._mock_migratable_db.is_versioned.return_value = True + self._mock_migratable_db.get_version.return_value = 2 + self._mock_migratable_db.get_upgrade_version.return_value = 1 + try: + self._installed_data.get_state() + except ValueError: + pass + else: + self.fail() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-04 13:03:50
|
Revision: 830 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=830&view=rev Author: ncjones Date: 2011-08-04 13:03:44 +0000 (Thu, 04 Aug 2011) Log Message: ----------- Fix data module unit tests. Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/test/pytrainer/upgrade/data_test.py Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-02 12:52:19 UTC (rev 829) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-08-04 13:03:44 UTC (rev 830) @@ -28,17 +28,17 @@ """Initializes the installation's data.""" db_url = ddbb.get_connection_url() migratable_db = MigratableDb(MIGRATE_REPOSITORY_PATH, db_url) - InstalledData(migratable_db, ddbb, conf_dir).update_to_current() + InstalledData(migratable_db, ddbb, LegacyVersionProvider(conf_dir)).update_to_current() class InstalledData(object): """Encapsulates an installation's existing data and provides means to check version state and upgrade.""" - def __init__(self, migratable_db, ddbb, conf_dir): + def __init__(self, migratable_db, ddbb, legacy_version_provider): self._migratable_db = migratable_db self._ddbb = ddbb - self._conf_dir = conf_dir + self._legacy_version_provider = legacy_version_provider def update_to_current(self): """Check the current state of the installation's data and update them @@ -84,7 +84,7 @@ else: # Calculate data version in older version that does not use the # current data versioning scheme. - legacy_version = self._get_legacy_version() + legacy_version = self._legacy_version_provider.get_legacy_version() if legacy_version is not None: legacy_version = int(legacy_version) if legacy_version <= 6: @@ -97,16 +97,6 @@ return 10 return -1 - def _get_legacy_version(self): - # In versions 1.7 and 1.8 the database version was stored as a property - # in the config file. Versions earlier than 1.7 are not supported for - # upgrades. - config_file = self._conf_dir + "/conf.xml" - parser = etree.XMLParser(encoding="UTF8", recover=True) - xml_tree = etree.parse(config_file, parser=parser) - config_element = xml_tree.getroot() - return config_element.get("DB_version") - def get_available_version(self): return self._migratable_db.get_upgrade_version() @@ -161,3 +151,21 @@ DataState.FRESH = DataState("FRESH", _update_fresh) DataState.STALE = DataState("STALE", _update_stale) DataState.LEGACY = DataState("LEGACY", _update_legacy) + +class LegacyVersionProvider(object): + + """Provides the DB version number for data not using the current data + versioning scheme.""" + + def __init__(self, conf_dir): + self._conf_dir = conf_dir + + def get_legacy_version(self): + # In versions 1.7 and 1.8 the database version was stored as a property + # in the config file. Versions earlier than 1.7 are not supported for + # upgrades. + config_file = self._conf_dir + "/conf.xml" + parser = etree.XMLParser(encoding="UTF8", recover=True) + xml_tree = etree.parse(config_file, parser=parser) + config_element = xml_tree.getroot() + return config_element.get("DB_version") Modified: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-02 12:52:19 UTC (rev 829) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-08-04 13:03:44 UTC (rev 830) @@ -26,8 +26,8 @@ def setUp(self): self._mock_migratable_db = Mock() self._mock_ddbb = Mock() - self._mock_profile = Mock() - self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_profile, "") + self._mock_version_provider = Mock() + self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_version_provider) def test_get_version_should_return_migrate_version_when_available(self): self._mock_migratable_db.get_version.return_value = 1 @@ -35,12 +35,12 @@ def test_get_version_should_return_legacy_version_when_available(self): self._mock_migratable_db.is_versioned.return_value = False - self._mock_profile.getValue.return_value = 2 + self._mock_version_provider.get_legacy_version.return_value = 2 self.assertEquals(2, self._installed_data.get_version()) def test_get_version_should_return_negative_one_when_no_existing_version(self): self._mock_migratable_db.is_versioned.return_value = False - self._mock_profile.getValue.return_value = None + self._mock_version_provider.get_legacy_version.return_value = None self.assertEquals(-1, self._installed_data.get_version()) def test_get_state_should_return_current_when_data_version_equals_repository_version(self): @@ -50,7 +50,7 @@ def test_get_state_should_return_fresh_when_data_version_unavailable(self): self._mock_migratable_db.is_versioned.return_value = False - self._mock_profile.getValue.return_value = None + self._mock_version_provider.get_legacy_version.return_value = None self.assertEquals(DataState.FRESH, self._installed_data.get_state()) @@ -60,7 +60,7 @@ self.assertEquals(DataState.STALE, self._installed_data.get_state()) - def test_get_state_should_return_legacy_when_data_version_from_profile(self): + def test_get_state_should_return_legacy_when_data_version_is_legacy(self): self._mock_migratable_db.is_versioned.return_value = False - self._mock_profile.getValue.return_value = 1 + self._mock_version_provider.get_legacy_version.return_value = 1 self.assertEquals(DataState.LEGACY, self._installed_data.get_state()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-08-02 12:52:25
|
Revision: 829 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=829&view=rev Author: ncjones Date: 2011-08-02 12:52:19 +0000 (Tue, 02 Aug 2011) Log Message: ----------- Fix version checking for pytrainer built with distutils. ticket:132 Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/migratedb.py pytrainer/trunk/setup.py Modified: pytrainer/trunk/pytrainer/upgrade/migratedb.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-07-29 22:50:26 UTC (rev 828) +++ pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-08-02 12:52:19 UTC (rev 829) @@ -18,12 +18,22 @@ from migrate.versioning.api import db_version, upgrade, version, version_control from migrate.versioning.exceptions import DatabaseNotControlledError +import logging +import os +import sys class MigratableDb(object): """Object bridge for sqlalchemy-migrate API functions.""" def __init__(self, repository_path, db_url): - self._repository_path = repository_path + """Create a migratable DB. + + Arguments: + repository_path -- The path to the migrate repository, relative to the + pypath. + db_url -- the connection URL string for the DB. + """ + self._repository_path = _get_resource_absolute_path(repository_path) self._db_url = db_url def is_versioned(self): @@ -53,3 +63,12 @@ def upgrade(self): """Run all available upgrade scripts for the repository.""" upgrade(self._db_url, self._repository_path) + +def _get_resource_absolute_path(resource_name): + """Get the absolute path to a resource on the python system path.""" + for path in sys.path: + candidate = os.path.join(path, resource_name) + if os.path.exists(candidate): + logging.debug("Found resource: %s", candidate) + return candidate + raise ValueError("Resource '{0}' could not be found".format(resource_name)) Modified: pytrainer/trunk/setup.py =================================================================== --- pytrainer/trunk/setup.py 2011-07-29 22:50:26 UTC (rev 828) +++ pytrainer/trunk/setup.py 2011-08-02 12:52:19 UTC (rev 829) @@ -28,7 +28,9 @@ 'pytrainer.lib', 'pytrainer.upgrade' ], - + package_data={ + 'pytrainer.upgrade': ['migrate.cfg', 'versions/*.sql', 'versions/*.py'] + }, data_files=[ ('share/pytrainer/glade/',glob("glade/*.glade")), ('share/pytrainer/glade/',glob("glade/*.png")), This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 22:50:32
|
Revision: 828 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=828&view=rev Author: ncjones Date: 2011-07-29 22:50:26 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Declare new pytrainer.upgrade package in setup script. ticket:132 Modified Paths: -------------- pytrainer/trunk/setup.py Modified: pytrainer/trunk/setup.py =================================================================== --- pytrainer/trunk/setup.py 2011-07-29 22:18:48 UTC (rev 827) +++ pytrainer/trunk/setup.py 2011-07-29 22:50:26 UTC (rev 828) @@ -25,7 +25,8 @@ packages=[ 'pytrainer', 'pytrainer.gui', 'pytrainer.extensions', - 'pytrainer.lib' + 'pytrainer.lib', + 'pytrainer.upgrade' ], data_files=[ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 22:18:54
|
Revision: 827 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=827&view=rev Author: ncjones Date: 2011-07-29 22:18:48 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Removing unused migrate dir. ticket:132 Removed Paths: ------------- pytrainer/trunk/pytrainer/migrate/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 10:02:11
|
Revision: 826 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=826&view=rev Author: ncjones Date: 2011-07-29 10:02:05 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Fix loading legacy version. Modified Paths: -------------- pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/upgrade/data.py Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2011-07-29 10:01:41 UTC (rev 825) +++ pytrainer/trunk/pytrainer/main.py 2011-07-29 10:02:05 UTC (rev 826) @@ -76,7 +76,7 @@ logging.debug('connecting to DDBB') self.ddbb.connect() - initialize_data(self.ddbb, self.profile, self.environment.conf_dir) + initialize_data(self.ddbb, self.environment.conf_dir) if self.startup_options.check: logging.debug("Checking DB as per user's request") self.sanityCheck() Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:01:41 UTC (rev 825) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:02:05 UTC (rev 826) @@ -17,27 +17,27 @@ #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import logging +from lxml import etree import pytrainer from pytrainer.upgrade.context import UpgradeContext from pytrainer.upgrade.migratedb import MigratableDb MIGRATE_REPOSITORY_PATH = "pytrainer/upgrade" -def initialize_data(ddbb, profile, conf_dir): +def initialize_data(ddbb, conf_dir): """Initializes the installation's data.""" db_url = ddbb.get_connection_url() migratable_db = MigratableDb(MIGRATE_REPOSITORY_PATH, db_url) - InstalledData(migratable_db, ddbb, profile, conf_dir).update_to_current() + InstalledData(migratable_db, ddbb, conf_dir).update_to_current() class InstalledData(object): """Encapsulates an installation's existing data and provides means to check version state and upgrade.""" - def __init__(self, migratable_db, ddbb, profile, conf_dir): + def __init__(self, migratable_db, ddbb, conf_dir): self._migratable_db = migratable_db self._ddbb = ddbb - self._profile = profile self._conf_dir = conf_dir def update_to_current(self): @@ -83,10 +83,8 @@ return self._migratable_db.get_version() else: # Calculate data version in older version that does not use the - # current data versioning scheme. Versions earlier than 1.7 are not - # supported for upgrades. In versions 1.7 and 1.8 the database - # version was stored as a property in the profile config file. - legacy_version = self._profile.getValue("pytraining", "DB_version") + # current data versioning scheme. + legacy_version = self._get_legacy_version() if legacy_version is not None: legacy_version = int(legacy_version) if legacy_version <= 6: @@ -99,6 +97,16 @@ return 10 return -1 + def _get_legacy_version(self): + # In versions 1.7 and 1.8 the database version was stored as a property + # in the config file. Versions earlier than 1.7 are not supported for + # upgrades. + config_file = self._conf_dir + "/conf.xml" + parser = etree.XMLParser(encoding="UTF8", recover=True) + xml_tree = etree.parse(config_file, parser=parser) + config_element = xml_tree.getroot() + return config_element.get("DB_version") + def get_available_version(self): return self._migratable_db.get_upgrade_version() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 10:01:48
|
Revision: 825 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=825&view=rev Author: ncjones Date: 2011-07-29 10:01:41 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Adding basic info logging to version checking. Modified Paths: -------------- pytrainer/trunk/pytrainer/upgrade/data.py Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:01:17 UTC (rev 824) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:01:41 UTC (rev 825) @@ -16,6 +16,7 @@ #along with this program; if not, write to the Free Software #Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +import logging import pytrainer from pytrainer.upgrade.context import UpgradeContext from pytrainer.upgrade.migratedb import MigratableDb @@ -59,7 +60,7 @@ """ data_state = self.get_state() - #TODO logging + logging.info("Initializing data. Data state is: '%s'.", data_state) data_state.update_to_current(self) def get_state(self): @@ -107,12 +108,15 @@ def initialize_version(self, initial_version): """Initialize the version metadata.""" + logging.info("Initializing version metadata to version: '%s'.", initial_version) self._migratable_db.version(initial_version) def initialize(self): + logging.info("Initializing new database.") self._ddbb.create_tables() def upgrade(self): + logging.info("Upgrading data from version '%s' to version '%s'.", self.get_version(), self.get_available_version()) pytrainer.upgrade.context.UPGRADE_CONTEXT = UpgradeContext(self._conf_dir) self._migratable_db.upgrade() @@ -126,6 +130,9 @@ self.name = name self._update_function = update_function + def __str__(self): + return self.name + def update_to_current(self, installed_data): """Update the installed data so it is compatible with the current version.""" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 10:01:23
|
Revision: 824 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=824&view=rev Author: ncjones Date: 2011-07-29 10:01:17 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Remove DB_version property from configuration file. Modified Paths: -------------- pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/profile.py pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/test/pytrainer/upgrade/data_test.py Added Paths: ----------- pytrainer/trunk/pytrainer/upgrade/context.py pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2011-07-29 10:00:27 UTC (rev 823) +++ pytrainer/trunk/pytrainer/main.py 2011-07-29 10:01:17 UTC (rev 824) @@ -56,7 +56,6 @@ def __init__(self,filename = None, data_path = None): #Version constants self.version ="1.9.0-dev" - self.DB_version = 9 #Process command line options self.startup_options = self.get_options() self.environment = Environment(platform.get_platform(), self.startup_options.conf_dir) @@ -64,7 +63,7 @@ #Setup logging self.set_logging(self.startup_options.log_level, self.startup_options.log_type) logging.debug('>>') - logging.debug("PyTrainer version %s, DB version %s" % (self.version, self.DB_version)) + logging.debug("PyTrainer version %s" % (self.version)) self.data_path = data_path self.date = Date() self.ddbb = None @@ -77,7 +76,7 @@ logging.debug('connecting to DDBB') self.ddbb.connect() - initialize_data(self.ddbb, self.profile) + initialize_data(self.ddbb, self.profile, self.environment.conf_dir) if self.startup_options.check: logging.debug("Checking DB as per user's request") self.sanityCheck() Modified: pytrainer/trunk/pytrainer/profile.py =================================================================== --- pytrainer/trunk/pytrainer/profile.py 2011-07-29 10:00:27 UTC (rev 823) +++ pytrainer/trunk/pytrainer/profile.py 2011-07-29 10:01:17 UTC (rev 824) @@ -56,7 +56,6 @@ "prf_ddbbuser":"", "prf_ddbbpass":"", "version":"0.0", - "DB_version":"0", "prf_us_system":"False", "prf_hrzones_karvonen":"False", "prf_maxhr":"", Added: pytrainer/trunk/pytrainer/upgrade/context.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/context.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/context.py 2011-07-29 10:01:17 UTC (rev 824) @@ -0,0 +1,31 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +class UpgradeContext(object): + + """Context used by upgrade scripts. + + Provides access to the application base dir.""" + + def __init__(self, conf_dir): + self.conf_dir = conf_dir + +# sqlalchemy-migrate does not provide any means to inject the context object in +# to upgrade scripts so instead we provide access via this global which must be +# initialised before upgrading. +UPGRADE_CONTEXT = None Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:00:27 UTC (rev 823) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:01:17 UTC (rev 824) @@ -22,21 +22,22 @@ MIGRATE_REPOSITORY_PATH = "pytrainer/upgrade" -def initialize_data(ddbb, profile): +def initialize_data(ddbb, profile, conf_dir): """Initializes the installation's data.""" db_url = ddbb.get_connection_url() migratable_db = MigratableDb(MIGRATE_REPOSITORY_PATH, db_url) - InstalledData(migratable_db, ddbb, profile).update_to_current() + InstalledData(migratable_db, ddbb, profile, conf_dir).update_to_current() class InstalledData(object): """Encapsulates an installation's existing data and provides means to check version state and upgrade.""" - def __init__(self, migratable_db, ddbb, profile): + def __init__(self, migratable_db, ddbb, profile, conf_dir): self._migratable_db = migratable_db self._ddbb = ddbb self._profile = profile + self._conf_dir = conf_dir def update_to_current(self): """Check the current state of the installation's data and update them @@ -112,6 +113,7 @@ self._ddbb.create_tables() def upgrade(self): + pytrainer.upgrade.context.UPGRADE_CONTEXT = UpgradeContext(self._conf_dir) self._migratable_db.upgrade() class DataState(object): Added: pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/011_remove_db_version.py 2011-07-29 10:01:17 UTC (rev 824) @@ -0,0 +1,10 @@ +from lxml import etree +from pytrainer.upgrade.context import UPGRADE_CONTEXT + +def upgrade(migrate_engine): + config_file = UPGRADE_CONTEXT.conf_dir + "/conf.xml" + parser = etree.XMLParser(encoding="UTF8", recover=True) + xml_tree = etree.parse(config_file, parser=parser) + config_element = xml_tree.getroot() + del config_element.attrib["DB_version"] + xml_tree.write(config_file, xml_declaration=True, encoding="UTF-8") Modified: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-07-29 10:00:27 UTC (rev 823) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-07-29 10:01:17 UTC (rev 824) @@ -27,7 +27,7 @@ self._mock_migratable_db = Mock() self._mock_ddbb = Mock() self._mock_profile = Mock() - self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_profile) + self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_profile, "") def test_get_version_should_return_migrate_version_when_available(self): self._mock_migratable_db.get_version.return_value = 1 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 10:00:33
|
Revision: 823 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=823&view=rev Author: ncjones Date: 2011-07-29 10:00:27 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Use data module for startup version check and initial table creation. Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/ddbb.py pytrainer/trunk/pytrainer/main.py pytrainer/trunk/pytrainer/upgrade/data.py Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2011-07-29 09:59:45 UTC (rev 822) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2011-07-29 10:00:27 UTC (rev 823) @@ -135,10 +135,6 @@ print "ERROR: Unable to connect to database" print connection_msg sys.exit(connection_ok) - #Do a quick check to ensure all tables are present in DB - if not self.checkDBTables(): - #Some tables missing - do DB check - self.checkDBIntegrity() def disconnect(self): self.ddbbObject.disconnect() @@ -298,21 +294,6 @@ ret_val = self.ddbbObject.freeExec(sql) return ret_val[0][0] - def checkDBTables(self): - '''Quick check that all expected tables existing in DB - return True if OK, False if any tables are missing - ''' - global tablesList - logging.debug('>>') - tablesDB = self.ddbbObject.getTableList() - logging.debug('Tables in DB: '+str(tablesDB)); - #Check Tables - for entry in tablesList: - logging.debug("Entry: "+entry) - if entry not in tablesDB: - return False - return True - def create_tables(self): global tablesList global tablesDefaultData Modified: pytrainer/trunk/pytrainer/main.py =================================================================== --- pytrainer/trunk/pytrainer/main.py 2011-07-29 09:59:45 UTC (rev 822) +++ pytrainer/trunk/pytrainer/main.py 2011-07-29 10:00:27 UTC (rev 823) @@ -33,6 +33,7 @@ from os import path from pytrainer import platform +from upgrade.data import initialize_data from environment import Environment from record import Record from waypoint import Waypoint @@ -75,22 +76,12 @@ self.ddbb = DDBB(self.profile, self) logging.debug('connecting to DDBB') self.ddbb.connect() - - #Get user's DB version - currentDB_version = self.profile.getValue("pytraining","DB_version") - logging.debug("Current DB version: "+str(currentDB_version)) - # DB check can be triggered either via new version (mandatory) or as runtime parameter (--check) + + initialize_data(self.ddbb, self.profile) if self.startup_options.check: logging.debug("Checking DB as per user's request") self.sanityCheck() - elif currentDB_version is None: - logging.debug("No stored DB version. Checking DB") - self.sanityCheck() - elif self.DB_version > int(currentDB_version): - logging.debug("DB version newer than user's version") - self.sanityCheck() - else: - logging.info('No sanity check requested') + self.record = Record(data_path,self) self.athlete = Athlete(data_path,self) self.stats = Stats(data_path,self) @@ -511,6 +502,4 @@ logging.debug('>>') logging.info('Checking database integrity') self.ddbb.checkDBIntegrity() - logging.info('Setting DB version to: ' + str(self.DB_version)) - self.profile.setValue("pytraining","DB_version", str(self.DB_version)) logging.debug('<<') Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 09:59:45 UTC (rev 822) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 10:00:27 UTC (rev 823) @@ -21,6 +21,12 @@ from pytrainer.upgrade.migratedb import MigratableDb MIGRATE_REPOSITORY_PATH = "pytrainer/upgrade" + +def initialize_data(ddbb, profile): + """Initializes the installation's data.""" + db_url = ddbb.get_connection_url() + migratable_db = MigratableDb(MIGRATE_REPOSITORY_PATH, db_url) + InstalledData(migratable_db, ddbb, profile).update_to_current() class InstalledData(object): @@ -52,6 +58,7 @@ """ data_state = self.get_state() + #TODO logging data_state.update_to_current(self) def get_state(self): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 09:59:51
|
Revision: 822 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=822&view=rev Author: ncjones Date: 2011-07-29 09:59:45 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Initialise empty DB from version checker. Modified Paths: -------------- pytrainer/trunk/pytrainer/lib/ddbb.py pytrainer/trunk/pytrainer/lib/mysqlUtils.py pytrainer/trunk/pytrainer/lib/sqliteUtils.py pytrainer/trunk/pytrainer/upgrade/data.py Modified: pytrainer/trunk/pytrainer/lib/ddbb.py =================================================================== --- pytrainer/trunk/pytrainer/lib/ddbb.py 2011-07-29 09:59:10 UTC (rev 821) +++ pytrainer/trunk/pytrainer/lib/ddbb.py 2011-07-29 09:59:45 UTC (rev 822) @@ -125,6 +125,9 @@ ddbb_user = self.configuration.getValue("pytraining","prf_ddbbuser") ddbb_pass = self.configuration.getValue("pytraining","prf_ddbbpass") self.ddbbObject = Sql(ddbb_host,ddbb,ddbb_user,ddbb_pass,self.configuration) + + def get_connection_url(self): + return self.ddbbObject.get_connection_url() def connect(self): connection_ok, connection_msg = self.ddbbObject.connect() @@ -309,12 +312,8 @@ if entry not in tablesDB: return False return True - - def checkDBIntegrity(self): - '''17.11.2009 - dgranda - Retrieves tables and columns from database, checks current ones and adds something if missed. New in version 1.7.0 - args: none - returns: none''' + + def create_tables(self): global tablesList global tablesDefaultData logging.debug('>>') @@ -352,6 +351,13 @@ else: self.ddbbObject.checkTable(entry,tablesList[entry]) + def checkDBIntegrity(self): + '''17.11.2009 - dgranda + Retrieves tables and columns from database, checks current ones and adds something if missed. New in version 1.7.0 + args: none + returns: none''' + self.create_tables() + #Run any functions to update or correct data #These functions _must_ be safe to run at any time (i.e. not be version specfic or only safe to run once) self.populate_date_time_local() Modified: pytrainer/trunk/pytrainer/lib/mysqlUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/mysqlUtils.py 2011-07-29 09:59:10 UTC (rev 821) +++ pytrainer/trunk/pytrainer/lib/mysqlUtils.py 2011-07-29 09:59:45 UTC (rev 822) @@ -30,6 +30,9 @@ self.ddbb_host = host self.ddbb = ddbb self.db = None + + def get_connection_url(self): + return "mysql://{user}:{passwd}@{host}/{db}".format(user=self.ddbb_user, passwd=self.ddbb_pass, host=self.ddbb_host, db=self.ddbb) def connect(self): #si devolvemos 1 ha ido todo con exito Modified: pytrainer/trunk/pytrainer/lib/sqliteUtils.py =================================================================== --- pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-07-29 09:59:10 UTC (rev 821) +++ pytrainer/trunk/pytrainer/lib/sqliteUtils.py 2011-07-29 09:59:45 UTC (rev 822) @@ -32,6 +32,9 @@ self.db = None confdir = configuration.confdir self.ddbb = "%s/pytrainer.ddbb" %confdir + + def get_connection_url(self): + return "sqlite:///" + self.ddbb def connect(self): #si devolvemos 1 ha ido todo con exito Modified: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 09:59:10 UTC (rev 821) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 09:59:45 UTC (rev 822) @@ -27,8 +27,9 @@ """Encapsulates an installation's existing data and provides means to check version state and upgrade.""" - def __init__(self, migratable_db, profile): + def __init__(self, migratable_db, ddbb, profile): self._migratable_db = migratable_db + self._ddbb = ddbb self._profile = profile def update_to_current(self): @@ -100,6 +101,9 @@ """Initialize the version metadata.""" self._migratable_db.version(initial_version) + def initialize(self): + self._ddbb.create_tables() + def upgrade(self): self._migratable_db.upgrade() @@ -119,7 +123,7 @@ self._update_function(installed_data) def _update_fresh(data): - # TODO create empty DB + data.initialize() data.initialize_version(data.get_available_version()) def _update_stale(data): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-29 09:59:17
|
Revision: 821 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=821&view=rev Author: ncjones Date: 2011-07-29 09:59:10 +0000 (Fri, 29 Jul 2011) Log Message: ----------- Create data version checking module. Added Paths: ----------- pytrainer/trunk/pytrainer/upgrade/data.py pytrainer/trunk/pytrainer/upgrade/migratedb.py pytrainer/trunk/test/pytrainer/upgrade/ pytrainer/trunk/test/pytrainer/upgrade/data_test.py Added: pytrainer/trunk/pytrainer/upgrade/data.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/data.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/data.py 2011-07-29 09:59:10 UTC (rev 821) @@ -0,0 +1,135 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import pytrainer +from pytrainer.upgrade.context import UpgradeContext +from pytrainer.upgrade.migratedb import MigratableDb + +MIGRATE_REPOSITORY_PATH = "pytrainer/upgrade" + +class InstalledData(object): + + """Encapsulates an installation's existing data and provides means to + check version state and upgrade.""" + + def __init__(self, migratable_db, profile): + self._migratable_db = migratable_db + self._profile = profile + + def update_to_current(self): + """Check the current state of the installation's data and update them + if necessary so they are compatible with the latest version. + + The update steps depend on the state of the installation's data. The + possible states and the update steps from those states are: + + 1. Current (data is up to date): + - do nothing + 2. Fresh (new installation): + - initialise empty db + - initialise db version metadata + 3. Stale: (data requires upgrading): + - run upgrade scripts + 4. Legacy (data requires upgrading but is missing version metadata): + - initialise db version metadata + - run upgrade scripts + + """ + data_state = self.get_state() + data_state.update_to_current(self) + + def get_state(self): + if self.is_versioned(): + if self.get_version() == self.get_available_version(): + return DataState.CURRENT + else: + return DataState.STALE + else: + if self.get_version() == -1: + return DataState.FRESH + else: + return DataState.LEGACY + + def get_version(self): + """Get the version number of an installation's data. + + If the data is empty then -1 is returned.""" + if self.is_versioned(): + return self._migratable_db.get_version() + else: + # Calculate data version in older version that does not use the + # current data versioning scheme. Versions earlier than 1.7 are not + # supported for upgrades. In versions 1.7 and 1.8 the database + # version was stored as a property in the profile config file. + legacy_version = self._profile.getValue("pytraining", "DB_version") + if legacy_version is not None: + legacy_version = int(legacy_version) + if legacy_version <= 6: + return legacy_version + elif legacy_version == 7: + return 9 + elif legacy_version == 8: + return 10 + elif legacy_version == 9: + return 10 + return -1 + + def get_available_version(self): + return self._migratable_db.get_upgrade_version() + + def is_versioned(self): + """ Check if the version metadata has been initiaized.""" + return self._migratable_db.is_versioned() + + def initialize_version(self, initial_version): + """Initialize the version metadata.""" + self._migratable_db.version(initial_version) + + def upgrade(self): + self._migratable_db.upgrade() + +class DataState(object): + + """The state of an installation's data. + + The state knows how to update the data to the "current" state.""" + + def __init__(self, name, update_function): + self.name = name + self._update_function = update_function + + def update_to_current(self, installed_data): + """Update the installed data so it is compatible with the current + version.""" + self._update_function(installed_data) + +def _update_fresh(data): + # TODO create empty DB + data.initialize_version(data.get_available_version()) + +def _update_stale(data): + data.upgrade() + +def _update_legacy(data): + data.initialize_version(data.get_version()) + data.upgrade() + +DataState.CURRENT = DataState("CURRENT", lambda data: None) +DataState.FRESH = DataState("FRESH", _update_fresh) +DataState.STALE = DataState("STALE", _update_stale) +DataState.LEGACY = DataState("LEGACY", _update_legacy) Added: pytrainer/trunk/pytrainer/upgrade/migratedb.py =================================================================== --- pytrainer/trunk/pytrainer/upgrade/migratedb.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/migratedb.py 2011-07-29 09:59:10 UTC (rev 821) @@ -0,0 +1,55 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +from migrate.versioning.api import db_version, upgrade, version, version_control +from migrate.versioning.exceptions import DatabaseNotControlledError + +class MigratableDb(object): + """Object bridge for sqlalchemy-migrate API functions.""" + + def __init__(self, repository_path, db_url): + self._repository_path = repository_path + self._db_url = db_url + + def is_versioned(self): + """ Check if the DB has been initiaized with version metadata.""" + try: + self.get_version() + except DatabaseNotControlledError: + return False + return True + + def get_version(self): + """Get the current version of the versioned DB. + + Raises DatabaseNotControlledError if the DB is not initialized.""" + return db_version(self._db_url, self._repository_path) + + def get_upgrade_version(self): + """Get the latest version available in upgrade repository.""" + return version(self._repository_path) + + def version(self, initial_version): + """Initialize the database with migrate metadata. + + Raises DatabaseAlreadyControlledError if the DB is already initialized.""" + version_control(self._db_url, self._repository_path, initial_version) + + def upgrade(self): + """Run all available upgrade scripts for the repository.""" + upgrade(self._db_url, self._repository_path) Added: pytrainer/trunk/test/pytrainer/upgrade/data_test.py =================================================================== --- pytrainer/trunk/test/pytrainer/upgrade/data_test.py (rev 0) +++ pytrainer/trunk/test/pytrainer/upgrade/data_test.py 2011-07-29 09:59:10 UTC (rev 821) @@ -0,0 +1,66 @@ +# -*- coding: iso-8859-1 -*- + +#Copyright (C) Nathan Jones nc...@us... + +#This program is free software; you can redistribute it and/or +#modify it under the terms of the GNU General Public License +#as published by the Free Software Foundation; either version 2 +#of the License, or (at your option) any later version. + +#This program is distributed in the hope that it will be useful, +#but WITHOUT ANY WARRANTY; without even the implied warranty of +#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +#GNU General Public License for more details. + +#You should have received a copy of the GNU General Public License +#along with this program; if not, write to the Free Software +#Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +import unittest +from mock import Mock +from pytrainer.upgrade.data import InstalledData, DataState +from migrate.versioning.exceptions import DatabaseNotControlledError + +class InstalledDataTest(unittest.TestCase): + + def setUp(self): + self._mock_migratable_db = Mock() + self._mock_ddbb = Mock() + self._mock_profile = Mock() + self._installed_data = InstalledData(self._mock_migratable_db, self._mock_ddbb, self._mock_profile) + + def test_get_version_should_return_migrate_version_when_available(self): + self._mock_migratable_db.get_version.return_value = 1 + self.assertEquals(1, self._installed_data.get_version()) + + def test_get_version_should_return_legacy_version_when_available(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_profile.getValue.return_value = 2 + self.assertEquals(2, self._installed_data.get_version()) + + def test_get_version_should_return_negative_one_when_no_existing_version(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_profile.getValue.return_value = None + self.assertEquals(-1, self._installed_data.get_version()) + + def test_get_state_should_return_current_when_data_version_equals_repository_version(self): + self._mock_migratable_db.get_version.return_value = 1 + self._mock_migratable_db.get_upgrade_version.return_value = 1 + self.assertEquals(DataState.CURRENT, self._installed_data.get_state()) + + def test_get_state_should_return_fresh_when_data_version_unavailable(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_profile.getValue.return_value = None + self.assertEquals(DataState.FRESH, self._installed_data.get_state()) + + + def test_get_state_should_return_stale_when_data_version_less_than_repository_version(self): + self._mock_migratable_db.get_version.return_value = 1 + self._mock_migratable_db.get_upgrade_version.return_value = 2 + self.assertEquals(DataState.STALE, self._installed_data.get_state()) + + + def test_get_state_should_return_legacy_when_data_version_from_profile(self): + self._mock_migratable_db.is_versioned.return_value = False + self._mock_profile.getValue.return_value = 1 + self.assertEquals(DataState.LEGACY, self._installed_data.get_state()) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-27 12:39:57
|
Revision: 820 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=820&view=rev Author: ncjones Date: 2011-07-27 12:39:50 +0000 (Wed, 27 Jul 2011) Log Message: ----------- Move migrate repository to avoid import errors. ticket:132 Added Paths: ----------- pytrainer/trunk/pytrainer/upgrade/ pytrainer/trunk/pytrainer/upgrade/README pytrainer/trunk/pytrainer/upgrade/__init__.py pytrainer/trunk/pytrainer/upgrade/migrate.cfg pytrainer/trunk/pytrainer/upgrade/versions/ pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql pytrainer/trunk/pytrainer/upgrade/versions/__init__.py Removed Paths: ------------- pytrainer/trunk/pytrainer/migrate/README pytrainer/trunk/pytrainer/migrate/__init__.py pytrainer/trunk/pytrainer/migrate/migrate.cfg pytrainer/trunk/pytrainer/migrate/versions/001_mysql_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/001_sqlite_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/002_mysql_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/002_sqlite_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/003_default_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/004_default_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/005_mysql_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/005_sqlite_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/006_default_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/007_mysql_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/007_sqlite_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/008_mysql_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/008_sqlite_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/010_default_upgrade.sql pytrainer/trunk/pytrainer/migrate/versions/__init__.py Deleted: pytrainer/trunk/pytrainer/migrate/README =================================================================== --- pytrainer/trunk/pytrainer/migrate/README 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/README 2011-07-27 12:39:50 UTC (rev 820) @@ -1,4 +0,0 @@ -This is a database migration repository. - -More information at -http://code.google.com/p/sqlalchemy-migrate/ Deleted: pytrainer/trunk/pytrainer/migrate/__init__.py =================================================================== --- pytrainer/trunk/pytrainer/migrate/__init__.py 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/__init__.py 2011-07-27 12:39:50 UTC (rev 820) @@ -1 +0,0 @@ -# template repository default module Deleted: pytrainer/trunk/pytrainer/migrate/migrate.cfg =================================================================== --- pytrainer/trunk/pytrainer/migrate/migrate.cfg 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/migrate.cfg 2011-07-27 12:39:50 UTC (rev 820) @@ -1,20 +0,0 @@ -[db_settings] -# Used to identify which repository this database is versioned under. -# You can use the name of your project. -repository_id=pytrainer - -# The name of the database table used to track the schema version. -# This name shouldn't already be used by your project. -# If this is changed once a database is under version control, you'll need to -# change the table name in each database too. -version_table=migrate_version - -# When committing a change script, Migrate will attempt to generate the -# sql for all supported databases; normally, if one of them fails - probably -# because you don't have that database installed - it is ignored and the -# commit continues, perhaps ending successfully. -# Databases in this list MUST compile successfully during a commit, or the -# entire commit will fail. List the databases your application will actually -# be using to ensure your updates to that database work properly. -# This must be a list; example: ['postgres','sqlite'] -required_dbs=[] Deleted: pytrainer/trunk/pytrainer/migrate/versions/001_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/001_mysql_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/001_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,41 +0,0 @@ --- initial schema as of version 1.7.0 - -create table sports ( - id_sports integer primary key auto_increment, - name varchar(100), - weight float, - met float -); - -create table records ( - id_record integer primary key auto_increment, - date date, - sport integer, - distance float, - time varchar(200), - beats float, - average float, - calories int, - comments text, - gpslog varchar(200), - title varchar(200), - upositive float, - unegative float, - maxspeed float, - maxpace float, - pace float, - maxbeats float, - date_time_local varchar(20), - date_time_utc varchar(20) -); - -create table waypoints ( - id_waypoint integer primary key auto_increment, - lat float, - lon float, - ele float, - comment varchar(240), - time date, - name varchar(200), - sym varchar(200) -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/001_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/001_sqlite_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/001_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,41 +0,0 @@ --- initial schema as of version 1.7.0 - -create table sports ( - id_sports integer primary key autoincrement, - name varchar(100), - weight float, - met float -); - -create table records ( - id_record integer primary key autoincrement, - date date, - sport integer, - distance float, - time varchar(200), - beats float, - average float, - calories int, - comments text, - gpslog varchar(200), - title varchar(200), - upositive float, - unegative float, - maxspeed float, - maxpace float, - pace float, - maxbeats float, - date_time_local varchar(20), - date_time_utc varchar(20) -); - -create table waypoints ( - id_waypoint integer primary key autoincrement, - lat float, - lon float, - ele float, - comment varchar(240), - time date, - name varchar(200), - sym varchar(200) -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/002_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/002_mysql_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/002_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,12 +0,0 @@ --- laps added in version 1.7.1 -create table laps ( - id_lap integer primary key auto_increment, - record integer, - elapsed_time varchar(20), - distance float, - start_lat float, - start_lon float, - end_lat float, - end_lon float, - calories integer -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/002_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/002_sqlite_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/002_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,12 +0,0 @@ --- laps added in version 1.7.1 -create table laps ( - id_lap integer primary key autoincrement, - record integer, - elapsed_time varchar(20), - distance float, - start_lat float, - start_lon float, - end_lat float, - end_lon float, - calories integer -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/003_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/003_default_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/003_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,2 +0,0 @@ --- lap number added in version 1.7.1 -alter table laps add lap_number integer; \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/004_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/004_default_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/004_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,2 +0,0 @@ --- sport max pace added in version 1.7.2 -alter table sports add max_pace integer; \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/005_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/005_mysql_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/005_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,9 +0,0 @@ --- athlete stats added in version 1.7.2 -create table athletestats ( - id_athletestat integer primary key auto_increment, - date date, - weight float, - bodyfat float, - restinghr integer, - maxhr integer -); \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/005_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/005_sqlite_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/005_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,9 +0,0 @@ --- athlete stats added in version 1.7.2 -create table athletestats ( - id_athletestat integer primary key autoincrement, - date date, - weight float, - bodyfat float, - restinghr integer, - maxhr integer -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/006_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/006_default_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/006_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,2 +0,0 @@ --- record duration added in version 1.7.2 -alter table records add duration integer; \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/007_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/007_mysql_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/007_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,4 +0,0 @@ --- record date_time data type changed in version 1.7.2 -alter table records - modify date_time_local varchar(40), - modify date_time_utc varchar(40); \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/007_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/007_sqlite_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/007_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1 +0,0 @@ --- data type change does not affect sqlite schema \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/008_mysql_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/008_mysql_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/008_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,16 +0,0 @@ --- equipment management added in version 1.8.0 - -create table equipment ( - id integer primary key auto_increment , - description varchar(200), - active boolean, - life_expectancy int, - prior_usage int, - notes text -); - -create table record_equipment ( - id integer primary key auto_increment, - record_id int, - equipment_id int -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/008_sqlite_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/008_sqlite_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/008_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,16 +0,0 @@ --- equipment management added in version 1.8.0 - -create table equipment ( - id integer primary key autoincrement , - description varchar(200), - active boolean, - life_expectancy int, - prior_usage int, - notes text -); - -create table record_equipment ( - id integer primary key autoincrement, - record_id int, - equipment_id int -); Deleted: pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,7 +0,0 @@ --- lap info added in version 1.9.0 -alter table laps add intensity varchar(7); -alter table laps add laptrigger(9); -alter table laps add max_speed float; -alter table laps add avg_hr int; -alter table laps add max_hr int; -alter table laps add comments text; \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/010_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/010_default_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/010_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -1,2 +0,0 @@ --- sport color added in version 1.9.0 -alter table sports add color char(6); \ No newline at end of file Deleted: pytrainer/trunk/pytrainer/migrate/versions/__init__.py =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/__init__.py 2011-07-27 12:34:35 UTC (rev 819) +++ pytrainer/trunk/pytrainer/migrate/versions/__init__.py 2011-07-27 12:39:50 UTC (rev 820) @@ -1 +0,0 @@ -# template repository default versions module Copied: pytrainer/trunk/pytrainer/upgrade/README (from rev 819, pytrainer/trunk/pytrainer/migrate/README) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/README (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/README 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,4 @@ +This is a database migration repository. + +More information at +http://code.google.com/p/sqlalchemy-migrate/ Copied: pytrainer/trunk/pytrainer/upgrade/__init__.py (from rev 819, pytrainer/trunk/pytrainer/migrate/__init__.py) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/__init__.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/__init__.py 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1 @@ +# template repository default module Copied: pytrainer/trunk/pytrainer/upgrade/migrate.cfg (from rev 819, pytrainer/trunk/pytrainer/migrate/migrate.cfg) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/migrate.cfg (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/migrate.cfg 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,20 @@ +[db_settings] +# Used to identify which repository this database is versioned under. +# You can use the name of your project. +repository_id=pytrainer + +# The name of the database table used to track the schema version. +# This name shouldn't already be used by your project. +# If this is changed once a database is under version control, you'll need to +# change the table name in each database too. +version_table=migrate_version + +# When committing a change script, Migrate will attempt to generate the +# sql for all supported databases; normally, if one of them fails - probably +# because you don't have that database installed - it is ignored and the +# commit continues, perhaps ending successfully. +# Databases in this list MUST compile successfully during a commit, or the +# entire commit will fail. List the databases your application will actually +# be using to ensure your updates to that database work properly. +# This must be a list; example: ['postgres','sqlite'] +required_dbs=[] Copied: pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/001_mysql_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/001_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,41 @@ +-- initial schema as of version 1.7.0 + +create table sports ( + id_sports integer primary key auto_increment, + name varchar(100), + weight float, + met float +); + +create table records ( + id_record integer primary key auto_increment, + date date, + sport integer, + distance float, + time varchar(200), + beats float, + average float, + calories int, + comments text, + gpslog varchar(200), + title varchar(200), + upositive float, + unegative float, + maxspeed float, + maxpace float, + pace float, + maxbeats float, + date_time_local varchar(20), + date_time_utc varchar(20) +); + +create table waypoints ( + id_waypoint integer primary key auto_increment, + lat float, + lon float, + ele float, + comment varchar(240), + time date, + name varchar(200), + sym varchar(200) +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/001_sqlite_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/001_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,41 @@ +-- initial schema as of version 1.7.0 + +create table sports ( + id_sports integer primary key autoincrement, + name varchar(100), + weight float, + met float +); + +create table records ( + id_record integer primary key autoincrement, + date date, + sport integer, + distance float, + time varchar(200), + beats float, + average float, + calories int, + comments text, + gpslog varchar(200), + title varchar(200), + upositive float, + unegative float, + maxspeed float, + maxpace float, + pace float, + maxbeats float, + date_time_local varchar(20), + date_time_utc varchar(20) +); + +create table waypoints ( + id_waypoint integer primary key autoincrement, + lat float, + lon float, + ele float, + comment varchar(240), + time date, + name varchar(200), + sym varchar(200) +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/002_mysql_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/002_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,12 @@ +-- laps added in version 1.7.1 +create table laps ( + id_lap integer primary key auto_increment, + record integer, + elapsed_time varchar(20), + distance float, + start_lat float, + start_lon float, + end_lat float, + end_lon float, + calories integer +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/002_sqlite_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/002_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,12 @@ +-- laps added in version 1.7.1 +create table laps ( + id_lap integer primary key autoincrement, + record integer, + elapsed_time varchar(20), + distance float, + start_lat float, + start_lon float, + end_lat float, + end_lon float, + calories integer +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/003_default_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/003_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,2 @@ +-- lap number added in version 1.7.1 +alter table laps add lap_number integer; \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/004_default_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/004_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,2 @@ +-- sport max pace added in version 1.7.2 +alter table sports add max_pace integer; \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/005_mysql_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/005_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,9 @@ +-- athlete stats added in version 1.7.2 +create table athletestats ( + id_athletestat integer primary key auto_increment, + date date, + weight float, + bodyfat float, + restinghr integer, + maxhr integer +); \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/005_sqlite_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/005_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,9 @@ +-- athlete stats added in version 1.7.2 +create table athletestats ( + id_athletestat integer primary key autoincrement, + date date, + weight float, + bodyfat float, + restinghr integer, + maxhr integer +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/006_default_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/006_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,2 @@ +-- record duration added in version 1.7.2 +alter table records add duration integer; \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/007_mysql_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/007_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,4 @@ +-- record date_time data type changed in version 1.7.2 +alter table records + modify date_time_local varchar(40), + modify date_time_utc varchar(40); \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/007_sqlite_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/007_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1 @@ +-- data type change does not affect sqlite schema \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/008_mysql_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/008_mysql_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,16 @@ +-- equipment management added in version 1.8.0 + +create table equipment ( + id integer primary key auto_increment , + description varchar(200), + active boolean, + life_expectancy int, + prior_usage int, + notes text +); + +create table record_equipment ( + id integer primary key auto_increment, + record_id int, + equipment_id int +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/008_sqlite_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/008_sqlite_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,16 @@ +-- equipment management added in version 1.8.0 + +create table equipment ( + id integer primary key autoincrement , + description varchar(200), + active boolean, + life_expectancy int, + prior_usage int, + notes text +); + +create table record_equipment ( + id integer primary key autoincrement, + record_id int, + equipment_id int +); Copied: pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/009_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,7 @@ +-- lap info added in version 1.9.0 +alter table laps add intensity varchar(7); +alter table laps add laptrigger(9); +alter table laps add max_speed float; +alter table laps add avg_hr int; +alter table laps add max_hr int; +alter table laps add comments text; \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/010_default_upgrade.sql) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/010_default_upgrade.sql 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1,2 @@ +-- sport color added in version 1.9.0 +alter table sports add color char(6); \ No newline at end of file Copied: pytrainer/trunk/pytrainer/upgrade/versions/__init__.py (from rev 819, pytrainer/trunk/pytrainer/migrate/versions/__init__.py) =================================================================== --- pytrainer/trunk/pytrainer/upgrade/versions/__init__.py (rev 0) +++ pytrainer/trunk/pytrainer/upgrade/versions/__init__.py 2011-07-27 12:39:50 UTC (rev 820) @@ -0,0 +1 @@ +# template repository default versions module This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <nc...@us...> - 2011-07-27 12:34:41
|
Revision: 819 http://pytrainer.svn.sourceforge.net/pytrainer/?rev=819&view=rev Author: ncjones Date: 2011-07-27 12:34:35 +0000 (Wed, 27 Jul 2011) Log Message: ----------- Fix upgrade script. ticket:130 Modified Paths: -------------- pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql Modified: pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql =================================================================== --- pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql 2011-07-23 00:08:48 UTC (rev 818) +++ pytrainer/trunk/pytrainer/migrate/versions/009_default_upgrade.sql 2011-07-27 12:34:35 UTC (rev 819) @@ -1,6 +1,6 @@ -- lap info added in version 1.9.0 alter table laps add intensity varchar(7); -alter table laps add trigger(9); +alter table laps add laptrigger(9); alter table laps add max_speed float; alter table laps add avg_hr int; alter table laps add max_hr int; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |