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

Proposed by Manuel de la Peña
Status: Superseded
Proposed branch: lp://qastaging/~mandel/desktopcouch/record_id
Merge into: lp://qastaging/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://qastaging/~mandel/desktopcouch/record_id
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Chad Miller (community) Approve
Review via email: mp+15424@code.qastaging.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

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