Changeset 10

Show
Ignore:
Timestamp:
08/05/05 22:36:30 (7 years ago)
Author:
mj
Message:

Move to using sets of keys instead of fixed-lenght composite keys. This both simplifies interfaces and also increases flexibility greatly. Now log entries can be enhanced with arbitrary tags much like image databases let you tag images.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/src/chronolog/interfaces.py

    r8 r10  
    1616 
    1717from zope.interface import Interface 
    18 from zope.schema import Text, TextLine, Date, Timedelta, Tuple, Int 
    19  
    20 class ITimeLogSubKey(Interface): 
    21     """A sub-key to a timelog entry 
    22  
    23     Every ITimeLogEntry is stored keyed on a tuple of items adaptable to 
    24     ITimeLogEntry. Identifiers (the id field) need only be unique for the 
    25     position in the tuple they are used in; e.g. key[0].id == 'foo' and 
    26     key[1].id == 'foo' but key[0] and key[1] can be totally different sub-keys. 
    27  
    28     """ 
     18from zope.interface.common.mapping import IEnumerableMapping 
     19from zope.schema import Text, TextLine, Date, Timedelta, Set, Int 
     20 
     21class ITimeLogKey(Interface): 
     22    """A key for a timelog entry 
     23 
     24    Every ITimeLogEntry is stored keyed on a set of ITimeLogKey. Keys are  
     25    unique for a given prefix and id; the prefix denotes the source from 
     26    which they where obtained. 
     27 
     28    """ 
     29    prefix = TextLine( 
     30        title=u'Prefix', 
     31        description=u'The source identifier of the key.', 
     32        readonly=True, 
     33        required=True) 
     34     
    2935    id = TextLine( 
    3036        title=u'Id', 
    31         description=u'''The unique identifier of the sub-key for the position  
    32                         in the key.''', 
     37        description=u'The unique identifier of the key.', 
    3338        required=True) 
    3439 
    3540    description = Text( 
    3641        title=u'Description', 
    37         description=u'A detailed description of the sub-key.', 
     42        description=u'A detailed description of the key.', 
    3843        required=False) 
    3944     
    4045    title = TextLine( 
    4146        title=u'Title', 
    42         description=u'The title of the sub-key; usually displayed in the UI.', 
    43         required=False) 
    44  
    45  
    46 class TimeLogSubKeyLookupError(LookupError): 
    47     """A sub-key could not be found for a given id""" 
    48  
    49  
    50 class ITimeLogSubKeySource(Interface): 
    51     """A source of sub-keys for a key position 
    52      
    53     For any given key position only one source can be used, but a source can 
    54     be re-used for multiple key positions. 
    55      
    56     """ 
    57     def getSubKey(id): 
    58         """Return the `ITimeLogSubKey` with the given id 
     47        description=u'The title of the key; usually displayed in the UI.', 
     48        required=False) 
     49 
     50 
     51class TimeLogKeyLookupError(LookupError): 
     52    """A key could not be found for a given id""" 
     53 
     54 
     55class ITimeLogKeySource(Interface): 
     56    """A source of keys 
     57     
     58    For any given key prefix only one source can be used. 
     59     
     60    """ 
     61    prefix = TextLine( 
     62        title=u'Prefix', 
     63        description=u'The source identifier of the key.', 
     64        required=True) 
     65     
     66    def getKey(id): 
     67        """Return the `ITimeLogKey` with the given id 
    5968         
    60         A ``TimeLogSubKeyLookupError`` is raised when no sub-key with the given 
    61         id exists. 
     69        A ``TimeLogKeyLookupError`` is raised when no key with the given id  
     70        exists. 
    6271         
    6372        """ 
    64     def listSubKeys(): 
    65         """Return an iterable of all sub-keys""" 
    66  
    67  
    68 class ITimeLogKeySource(Interface): 
    69     """A source of ITimeLogSubKeySources""" 
    70     keyLength = Int( 
    71         title=u'Key Length', 
    72         description=u'''Number of sub-key sources provided.''', 
    73         required=True, 
    74         readonly=True) 
    75  
    76     def getSubKeySource(position): 
    77         """Return an `ITimeLogSubKeySource` for a given key position 
    78  
    79         Raises an ``IndexError`` when no source exists at that position 
    80          
    81         """ 
     73    def listKeys(): 
     74        """Return an iterable of all keys in this source""" 
     75 
     76 
     77class ITimeLogKeySourcesCollection(IEnumerableMapping): 
     78    """A collection of ITimeLogKeySources 
     79 
     80    ITimeLogKeySources are keyed on their prefixes. 
     81     
     82    """ 
    8283 
    8384 
     
    8687 
    8788    Timelog entries are a record of an amount of time worked on a certain date 
    88     optionally with comments. An entry is uniquely identified by its key and 
     89    optionally with comments. An entry is uniquely identified by its keys and 
    8990    date. 
    9091 
     
    9394 
    9495    """ 
    95     key = Tuple( 
    96         title=u'Key', 
    97         description=u'''A set of sub-keys describing the entry against which 
    98                         time is logged. The sub-keys must be adaptable to 
    99                         ITimeLogSubKey''', 
     96    keys = Set( 
     97        title=u'Keys', 
     98        description=u'''A set of keys describing the entry against which 
     99                        time is logged.''', 
    100100        required=True) 
    101101             
     
    122122 
    123123    """ 
    124     keyLength = Int( 
    125         title=u'Key Length', 
    126         description=u'''Number of sub-keys in a ITimeLogEntry key stored in 
    127                         store.''', 
    128         required=True, 
    129         readonly=True, 
    130         min=1) 
    131  
    132124    def recordTime(*entries): 
    133125        """Stores a set of ITimeLogEntries 
     
    137129 
    138130        Record the time log entries; any previously recorded entries with the 
    139         same key and date are replaced. Any entry with the duration set to None 
    140         can be discarded from the store completely. 
    141  
    142         Only entries whose keys have keyLength sub-keys are accepted. 
    143  
    144         """ 
    145  
    146     def queryKeys(partial_key, start_date=None, end_date=None): 
     131        same keys and date are replaced. Any entry with the duration set to  
     132        None can be discarded from the store completely. 
     133 
     134        """ 
     135 
     136    def queryKeys(keys, start_date=None, end_date=None): 
    147137        """Queries for key completions 
    148138 
    149         partial_key 
    150             A ITimeLogStore.keyLength length tuple of Nones and  
    151             ITimeLogSubKeys. 
     139        keys 
     140            A set of ITimeLogKeys. 
    152141 
    153142        start_date 
     
    157146            Optionally limit the search to entries before or on the given date. 
    158147 
    159         Returns a sequence of complete keys that have been used to log time 
    160         against, expanded from the given ITimeLogSubKeys. So (A, None, None) 
    161         could return ((A, B, C), (A, B, D)), while (None, None, D) would only 
    162         return ((A, B, D),) 
    163  
    164         """ 
    165  
    166     def queryDateRange(partial_key): 
     148        Returns a sequence of key sets that have been used to log time 
     149        against, expanded from the given ITimeLogKeys. So the set (A) 
     150        could return ((A, B, C), (A, B, D)), while (D) would onl return  
     151        ((A, B, D),) 
     152 
     153        """ 
     154 
     155    def queryDateRange(keys): 
    167156        """Get the first and last date for which there are log entries matching 
    168157 
    169         partial_key 
    170             A ITimeLogStore.keyLength length tuple of Nones and  
    171             ITimeLogSubKeys. 
     158        key 
     159            A set of ITimeLogKeys. 
    172160 
    173161        Returns a (datetime.date, datetime.date) tuple specifing the range of 
    174         dates there are log entries found. 
    175  
    176         """ 
    177  
    178     def iterateDayTotals(partial_key, start_date=None): 
    179         """Iterate over totalled log information matching the partial key`  
    180  
    181         partial_key 
    182             A ITimeLogStore.keyLength length tuple of Nones and  
    183             ITimeLogSubKeys.` 
     162        dates there are log entries found that used all of the given keys. So 
     163        querying for (A, B) returns the first and last date that any time was 
     164        logged against both those keys. Logs against either (A) or (B) are not 
     165        eligable, but a log entry against (A, B, C) is. 
     166 
     167        """ 
     168 
     169    def iterateDayTotals(keys, start_date=None): 
     170        """Iterate over totalled log information matching all the keys`  
     171 
     172        keys 
     173            A set of ITimeLogKeys.` 
    184174 
    185175        start_date 
    186176            An optional date at which to start iterating 
    187177 
    188         Iterates over each date starting at start_date or the first date there 
    189         are log entries matching the partial key and totals the log entries 
    190         matching the partial key. Each iteration a ITimeLogEntry is returned 
     178        Iterates over each date starting at start_date and totals the log  
     179        entries matching the keys. Each iteration a ITimeLogEntry is returned 
    191180        with the duration set to the total for that day or None if no time was 
    192181        logged. Never terminates. 
     
    194183        """ 
    195184 
    196     def queryTotal(partial_key, start_date=None, end_date=None): 
     185    def queryTotal(keys, start_date=None, end_date=None): 
    197186        """Get the sum of time logged 
    198187 
    199         partial_key 
    200             A ITimeLogStore.keyLength length tuple of Nones and  
    201             ITimeLogSubKeys. 
     188        keys 
     189            A set of ITimeLogKeys. 
    202190 
    203191        start_date 
     
    207195            Optionally limit the entries before or on the given date. 
    208196 
    209         Returns the total duration of the entries matching the partial key and 
     197        Returns the total duration of the entries matching the keys and 
    210198        limited by the start_date and end_date. 
    211199 
     
    216204    """A timesheet 
    217205 
    218     A timesheet is a view on a ITimeLogStore for a given time period and 
    219     partial key. 
     206    A timesheet is a view on a ITimeLogStore for a given time period and keys. 
    220207 
    221208    """ 
     
    230217        required=True) 
    231218 
    232     viewKey = Tuple( 
     219    viewKey = Set( 
    233220        title=u'View Key', 
    234         description=u'The partial key defining the view on the underlying ' 
     221        description=u'The keys defining the view on the underlying ' 
    235222                    u'ITimeLogStore.', 
    236223        required=True) 
    237