- coded_id = cPickle.dumps(doc['_id'])
- self.database.connection._insert(self.database.db_name, table_id, {'id': coded_id})
- for f in doc:
- if f == '_id':
- continue
- if not f in fields:
- self._create_field(f)
- table_f = '%s$%s' % (self.table_name, f)
- values = {
- 'id': coded_id,
- 'value': cPickle.dumps(doc[f]),
- }
- if type(doc[f]) in (int, float):
- values['number'] = doc[f]
- self.database.connection._insert(self.database.db_name, table_f, values)
+ self.database.connection.savepoint("insert_document")
+ try:
+ for f in doc:
+ if not f in fields:
+ self._create_field(f)
+ table_f = '%s$%s' % (self.table_name, f)
+ self._insert_field(doc_id, table_f, f, doc[f])
+ self.database.connection.commit_savepoint("insert_document")
+ except:
+ self.database.connection.rollback_savepoint("insert_document")
+ raise
+
+ def _insert_field(self, doc_id, field_table, field_name, field_value):
+ values = {
+ 'id': doc_id,
+ 'name': field_name,
+ 'value': self.database.connection.serializer.dumps(field_value),
+ }
+ if type(field_value) in (int, float):
+ values['number'] = field_value
+
+ self.database.connection._insert(self.database.db_name, field_table, values)
+
+ if type(field_value) in (list, tuple) and not '.' in field_name:
+ for i in xrange(len(field_value)):
+ self._insert_field(doc_id, field_table, "%s..%s" % (field_name, i), field_value[i])
+ elif type(field_value) is dict:
+ for k, v in field_value.iteritems():
+ self._insert_field(doc_id, field_table, "%s.%s" % (field_name, k), v)