public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (_readOnly)
            {
                throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.Forbidden, TAG,
                                                 "Attempting to write to a readonly database");
            }

            if (!StringEx.IsNullOrWhiteSpace(nullColumnHack))
            {
                throw new InvalidOperationException("Don't use nullColumnHack");
            }

            Log.To.TaskScheduling.V(TAG, "Scheduling InsertWithOnConflict");
            var t = Factory.StartNew(() =>
            {
                Log.To.TaskScheduling.V(TAG, "Running InsertWithOnConflict");
                var lastInsertedId = -1L;
                var command        = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

                try {
                    LastErrorCode = command.step();
                    command.Dispose();
                    if (LastErrorCode == raw.SQLITE_ERROR)
                    {
                        throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
                                                         raw.sqlite3_errmsg(_writeConnection));
                    }

                    int changes = _writeConnection.changes();
                    if (changes > 0)
                    {
                        lastInsertedId = _writeConnection.last_insert_rowid();
                    }

                    if (lastInsertedId == -1L)
                    {
                        if (conflictResolutionStrategy != ConflictResolutionStrategy.Ignore)
                        {
                            throw Misc.CreateExceptionAndLog(Log.To.Database, StatusCode.DbError, TAG,
                                                             "Error inserting {0} using {1}", initialValues, command);
                        }
                    }
                    else
                    {
                        Log.To.Database.V(TAG, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                    }
                }
                catch (CouchbaseLiteException) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    Log.To.Database.E(TAG, "Error inserting into table {0}, rethrowing...", table);
                    throw;
                } catch (Exception ex) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    throw Misc.CreateExceptionAndLog(Log.To.Database, ex, StatusCode.DbError, TAG,
                                                     "Error inserting into table {0}", table);
                }

                return(lastInsertedId);
            });

            var r = t.ConfigureAwait(false).GetAwaiter().GetResult();

            if (t.Exception != null)
            {
                throw t.Exception;
            }

            return(r);
        }
Beispiel #2
0
        public long InsertWithOnConflict(String table, String nullColumnHack, ContentValues initialValues, ConflictResolutionStrategy conflictResolutionStrategy)
        {
            if (_readOnly)
            {
                throw new CouchbaseLiteException("Attempting to write to a readonly database", StatusCode.Forbidden);
            }

            if (!StringEx.IsNullOrWhiteSpace(nullColumnHack))
            {
                var e = new InvalidOperationException("{0} does not support the 'nullColumnHack'.".Fmt(TAG));
                Log.E(TAG, "Unsupported use of nullColumnHack", e);
                throw e;
            }

            var t = Factory.StartNew(() =>
            {
                var lastInsertedId = -1L;
                var command        = GetInsertCommand(table, initialValues, conflictResolutionStrategy);

                try
                {
                    LastErrorCode = command.step();
                    command.Dispose();
                    if (LastErrorCode == SQLiteResult.ERROR)
                    {
                        throw new CouchbaseLiteException(raw.sqlite3_errmsg(_writeConnection), StatusCode.DbError);
                    }

                    int changes = _writeConnection.changes();
                    if (changes > 0)
                    {
                        lastInsertedId = _writeConnection.last_insert_rowid();
                    }

                    if (lastInsertedId == -1L)
                    {
                        if (conflictResolutionStrategy != ConflictResolutionStrategy.Ignore)
                        {
                            Log.E(TAG, "Error inserting " + initialValues + " using " + command);
                            throw new CouchbaseLiteException("Error inserting " + initialValues + " using " + command, StatusCode.DbError);
                        }
                    }
                    else
                    {
                        Log.V(TAG, "Inserting row {0} into {1} with values {2}", lastInsertedId, table, initialValues);
                    }
                }
                catch (CouchbaseLiteException) {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    Log.E(TAG, "Error inserting into table " + table);
                    throw;
                }
                catch (Exception ex)
                {
                    LastErrorCode = raw.sqlite3_errcode(_writeConnection);
                    throw new CouchbaseLiteException("Error inserting into table " + table, ex)
                    {
                        Code = StatusCode.DbError
                    };
                }
                return(lastInsertedId);
            });

            var r = t.ConfigureAwait(false).GetAwaiter().GetResult();

            if (t.Exception != null)
            {
                throw t.Exception;
            }

            return(r);
        }