def save(self, values=None, after=None, before=None, **context):
<EOL>if after is not None:<EOL><INDENT>callback = orb.events.Callback(self.save, values=values, **context)<EOL>after.addCallback(orb.events.PostSaveEvent, callback, record=after, once=True)<EOL>return callback<EOL><DEDENT>elif before is not None:<EOL><INDENT>callback = orb.events.Callback(self.save, values=values, **context)<EOL>after.addCallback(orb.events.PreSaveEvent, callback, record=after, once=True)<EOL>return callback<EOL><DEDENT>if values is not None:<EOL><INDENT>self.update(values, **context)<EOL><DEDENT>context = self.context(**context)<EOL>new_record = not self.isRecord()<EOL>changes = self.changes(columns=context.columns)<EOL>event = orb.events.PreSaveEvent(record=self, context=context, newRecord=new_record, changes=changes)<EOL>if self.processEvent(event):<EOL><INDENT>self.onPreSave(event)<EOL><DEDENT>if event.preventDefault:<EOL><INDENT>return event.result<EOL><DEDENT>if not (self.isModified() and self.validate()):<EOL><INDENT>return False<EOL><DEDENT>conn = context.db.connection()<EOL>if not self.isRecord():<EOL><INDENT>records, _ = conn.insert([self], context)<EOL>if records:<EOL><INDENT>event = orb.events.LoadEvent(record=self, data=records[<NUM_LIT:0>])<EOL>self._load(event)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>conn.update([self], context)<EOL><DEDENT>cols = [self.schema().column(c).name() for c in context.columns or []]<EOL>with WriteLocker(self.__dataLock):<EOL><INDENT>for col_name, (_, value) in self.__values.items():<EOL><INDENT>if not cols or col_name in cols:<EOL><INDENT>self.__values[col_name] = (value, value)<EOL><DEDENT><DEDENT><DEDENT>event = orb.events.PostSaveEvent(record=self, context=context, newRecord=new_record, changes=changes)<EOL>if self.processEvent(event):<EOL><INDENT>self.onPostSave(event)<EOL><DEDENT>return True<EOL>
Commits the current change set information to the database,
or inserts this object as a new record into the database.
This method will only update the database if the record
has any local changes to it, otherwise, no commit will
take place.  If the dryRun flag is set, then the SQL
will be logged but not executed.

:param values: None or dictionary of values to update before save
:param after: <orb.Model> || None (optional)
              if provided, this save call will be delayed
              until after the given record has been saved,
              triggering a PostSaveEvent callback
:param before: <orb.Model> || None (optional)
              if provided, this save call will be delayed
              until before the given record is about to be
              saved, triggering a PreSaveEvent callback


:note       From version 0.6.0 on, this method now accepts a mutable
            keyword dictionary of values.  You can supply any member
            value for either the <orb.LookupOptions> or
            <orb.Context>, 'options' for
            an instance of the <orb.Context>

:return     <bool> success