Merge lp:~mandel/desktopcouch/record_id into lp:desktopcouch

Proposed by Manuel de la Peña
Status: Superseded
Proposed branch: lp:~mandel/desktopcouch/record_id
Merge into: lp:desktopcouch
Diff against target: 66 lines (+25/-3)
2 files modified
desktopcouch/records/record.py (+24/-1)
desktopcouch/records/server_base.py (+1/-2)
To merge this branch: bzr merge lp:~mandel/desktopcouch/record_id
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Chad Miller (community) Approve
Review via email: mp+15424@code.launchpad.net

This proposal has been superseded by a proposal from 2009-12-07.

Commit message

Moved record_id to be a property rather than an attribute in order to be able to give a consistent behavior

To post a comment you must log in.
Revision history for this message
Manuel de la Peña (mandel) wrote :

This branch ensures that the record_id is set whenever the +id key is present in the data pass to create a new record.

Revision history for this message
Manuel de la Peña (mandel) wrote :

Ensured that when creating a record with a dict that contains the key '_id' its vlaue is used for record_id

Revision history for this message
Chad Miller (cmiller) wrote :

Let's not use "warnings" module. Instead, import logging and "logging.warn(...)", usually.

In this case, though, I would be just as happy with an assertion.

if '_id' in data:
   if record_id is not None:
       assert data['_id'] == record_id
       ...

Maybe drop the "record_id" member and make record_id a @property like record_type. Maybe we can drop all "_id" from code except for the getter.

Do we need a setter property also?

review: Needs Fixing
Revision history for this message
Chad Miller (cmiller) wrote :

> if '_id' in data:

if data.get('_id', None) is not None: # safer. Explicit {'_id':None} would fail.

Revision history for this message
Manuel de la Peña (mandel) wrote :

> Let's not use "warnings" module. Instead, import logging and
> "logging.warn(...)", usually.
>
> In this case, though, I would be just as happy with an assertion.
>
> if '_id' in data:
> if record_id is not None:
> assert data['_id'] == record_id
> ...
>
> Maybe drop the "record_id" member and make record_id a @property like
> record_type. Maybe we can drop all "_id" from code except for the getter.
>
> Do we need a setter property also?

I agree with the comments, the new implementation uses an assertion. I have implemented the record_id as a property with a getter and a setter. The setter is needed to pass all current tests.

Revision history for this message
Chad Miller (cmiller) wrote :

13 + if '_id' in data and record_id is not None:
14 + assert data['_id'] == record_id
15 + elif record_id is not None:
16 + self._data['_id'] = record_id

This would be cleaner with two levels of "if".

if record_id is not None: # Explicit setting, so try to use it.
   if data.get('_id', None) is not None: # Overwrite _id if it is None.
      self._data['_id'] = record_id
   else: # _id already set. Verify that the explicit value agrees.
      assert self._data['_id'] == record_id, "record_id doesn't match value in data."

Note the data.get() and the second parameter to assert .

Revision history for this message
Manuel de la Peña (mandel) wrote :

> 13 + if '_id' in data and record_id is not None:
> 14 + assert data['_id'] == record_id
> 15 + elif record_id is not None:
> 16 + self._data['_id'] = record_id
>
>
> This would be cleaner with two levels of "if".
>
> if record_id is not None: # Explicit setting, so try to use it.
> if data.get('_id', None) is not None: # Overwrite _id if it is None.
> self._data['_id'] = record_id
> else: # _id already set. Verify that the explicit value agrees.
> assert self._data['_id'] == record_id, "record_id doesn't match value in
> data."
>
>
>
> Note the data.get() and the second parameter to assert .

What if the record_id is not None and the data['_id']is indeed None? we could try to put in the db {'_id':None} which will raise an exception.

We would have to do yet another check.

Revision history for this message
Manuel de la Peña (mandel) wrote :

> > 13 + if '_id' in data and record_id is not None:
> > 14 + assert data['_id'] == record_id
> > 15 + elif record_id is not None:
> > 16 + self._data['_id'] = record_id
> >
> >
> > This would be cleaner with two levels of "if".
> >
> > if record_id is not None: # Explicit setting, so try to use it.
> > if data.get('_id', None) is not None: # Overwrite _id if it is None.
> > self._data['_id'] = record_id
> > else: # _id already set. Verify that the explicit value agrees.
> > assert self._data['_id'] == record_id, "record_id doesn't match value
> in
> > data."
> >
> >
> >
> > Note the data.get() and the second parameter to assert .
>
> What if the record_id is not None and the data['_id']is indeed None? we could
> try to put in the db {'_id':None} which will raise an exception.
>
> We would have to do yet another check.
Sorry, I just realized what you meant... override _id. Stupid Manuel!

Revision history for this message
Chad Miller (cmiller) wrote :

Looks good to me. Thank you.

review: Approve
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

Looks good.

review: Approve
Revision history for this message
Manuel de la Peña (mandel) wrote :

Major screw up from my part. The committed patch is wrong (major screw up from my port, I should have added a test!!!)

The if statement should be:

if record_id is not None: # Explicit setting, so try to use it.
   if data.get('_id', None) is None: # Overwrite _id if it is None.
      self._data['_id'] = record_id
   else: # _id already set. Verify that the explicit value agrees.
      assert self._data['_id'] == record_id, "record_id doesn't match value in data."

Otherwise we will always raise an exception since None is never equal to record_id!!

I have made the changes in the same lp branch with an addition of a test case to ensure that next time this does not happen.

Sorry for the screw up!

Manuel

lp:~mandel/desktopcouch/record_id updated
114. By Manuel de la Peña

Removed the use of an assertion. Used assertRaise in test.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'desktopcouch/records/record.py'
2--- desktopcouch/records/record.py 2009-08-05 11:18:46 +0000
3+++ desktopcouch/records/record.py 2009-11-30 16:39:11 +0000
4@@ -247,9 +247,19 @@
5 record_type = data['record_type']
6 else:
7 raise NoRecordTypeSpecified
8+
9 super(Record, self).__init__(data)
10 self._data['record_type'] = record_type
11- self.record_id = record_id
12+
13+ if record_id is not None:
14+ # Explicit setting, so try to use it.
15+ if data.get('_id', None) is not None:
16+ # Overwrite _id if it is None.
17+ self._data['_id'] = record_id
18+ else:
19+ # _id already set. Verify that the explicit value agrees.
20+ assert self._data['_id'] == record_id, "record_id doesn't match value in data."
21+
22
23 def __getitem__(self, key):
24 if is_internal(key):
25@@ -288,6 +298,18 @@
26 return [
27 key for key in super(Record, self).keys() if not is_internal(key)]
28
29+ def _get_record_id(self):
30+ """Gets the record id."""
31+ if '_id' in self._data:
32+ return self._data['_id']
33+ return None
34+
35+ def _set_record_id(self, value):
36+ """Sets the record id."""
37+ self._data['_id'] = value
38+
39+ record_id = property(_get_record_id, _set_record_id)
40+
41 @property
42 def application_annotations(self):
43 """Get the section with application specific data."""
44@@ -297,3 +319,4 @@
45 def record_type(self):
46 """Get the record type."""
47 return self._data.setdefault('record_type', None)
48+
49
50=== modified file 'desktopcouch/records/server_base.py'
51--- desktopcouch/records/server_base.py 2009-11-23 17:29:05 +0000
52+++ desktopcouch/records/server_base.py 2009-11-30 16:39:11 +0000
53@@ -149,12 +149,11 @@
54 return None
55 data.update(couch_record)
56 record = self.record_factory(data=data)
57- record.record_id = record_id
58 return record
59
60 def put_record(self, record):
61 """Put a record in back end storage."""
62- record_id = record.record_id or record._data.get('_id', '')
63+ record_id = record.record_id
64 record_data = record._data
65 if record_id:
66 self.db[record_id] = record_data

Subscribers

People subscribed via source and target branches