Subjects get a key name to enforce uniqueness.

This commit is contained in:
Ian Gulliver
2014-05-28 13:51:42 -07:00
parent be27a86b72
commit 9736c15faa
2 changed files with 22 additions and 15 deletions

View File

@@ -14,7 +14,9 @@
# limitations under the License. # limitations under the License.
import json import json
import hashlib
import logging import logging
import struct
from google.appengine.api import channel from google.appengine.api import channel
from google.appengine.ext import db from google.appengine.ext import db
@@ -110,32 +112,37 @@ class Subject(db.Model):
next_message_id = db.IntegerProperty(required=True, default=1) next_message_id = db.IntegerProperty(required=True, default=1)
@classmethod
def _UpdateHashWithString(cls, hashobj, string):
string = string.encode('utf8')
hashobj.update(struct.pack('!i', len(string)))
hashobj.update(string)
@classmethod
def _KeyName(cls, subject):
hashobj = hashlib.sha256()
cls._UpdateHashWithString(hashobj, subject['name'])
cls._UpdateHashWithString(hashobj, subject.get('readable_only_by', ''))
cls._UpdateHashWithString(hashobj, subject.get('writable_only_by', ''))
return hashobj.hexdigest()
@classmethod @classmethod
def FindOrCreate(cls, subject): def FindOrCreate(cls, subject):
if 'readable_only_by' in subject: if 'readable_only_by' in subject:
readable_only_by = Profile.get(subject['readable_only_by']) readable_only_by = db.Key(subject['readable_only_by'])
else: else:
readable_only_by = None readable_only_by = None
if 'writable_only_by' in subject: if 'writable_only_by' in subject:
writable_only_by = Profile.get(subject['writable_only_by']) writable_only_by = db.Key(subject['writable_only_by'])
else: else:
writable_only_by = None writable_only_by = None
subjects = ( return cls.get_or_insert(
cls.all() cls._KeyName(subject),
.filter('name =', subject['name'])
.filter('readable_only_by =', readable_only_by)
.filter('writable_only_by =', writable_only_by)
.fetch(1))
if subjects:
return subjects[0]
subject = cls(
name=subject['name'], name=subject['name'],
readable_only_by=readable_only_by, readable_only_by=readable_only_by,
writable_only_by=writable_only_by) writable_only_by=writable_only_by)
subject.put()
return subject
@db.transactional() @db.transactional()
def GetRecentMessages(self, num_messages): def GetRecentMessages(self, num_messages):

View File

@@ -479,7 +479,7 @@ asyncTest('Repin', function() {
}); });
asyncTest('Duplicate subject', function() { asyncTest('Duplicate subject', function() {
expect(8); expect(4);
var subject = randstring(); var subject = randstring();
var message1 = randstring(); var message1 = randstring();
@@ -498,7 +498,7 @@ asyncTest('Duplicate subject', function() {
if (e['message'] == message1) { if (e['message'] == message1) {
equal(message1, e['message'], 'message1 matches'); equal(message1, e['message'], 'message1 matches');
} else { } else {
equal(message2, e['message'], 'message1 matches'); equal(message2, e['message'], 'message2 matches');
} }
if (++messages == 2) { if (++messages == 2) {
cosmo.shutdown(); cosmo.shutdown();