Exemple #1
0
 public static bool IsUniqueConstraintViolation(this SqliteException exception)
 {
     return(exception.SqliteErrorCode == 19);
 }
Exemple #2
0
 private static bool IsExceptionUnqiueOrDuplicateIssue(SqliteException sqlException)
 {
     return(sqlException.SqliteErrorCode == SqliteDuplicateKeyError ||
            sqlException.SqliteErrorCode == SqliteUniqueKeyError);
 }
Exemple #3
0
        // 获得册记录信息和书目摘要信息
        // parameters:
        //      style   风格。network 表示只从网络获取册记录;否则优先从本地获取,本地没有再从网络获取册记录。无论如何,书目摘要都是尽量从本地获取
        // .Value
        //      0   没有找到
        //      1   找到
        public static async Task <GetEntityDataResult> GetEntityDataAsync(string pii,
                                                                          string style)
        {
            bool network = StringUtil.IsInList("network", style);

            try
            {
                using (var releaser = await _channelLimit.EnterAsync())
                    using (BiblioCacheContext context = new BiblioCacheContext())
                    {
                        if (_cacheDbCreated == false)
                        {
                            context.Database.EnsureCreated();
                            _cacheDbCreated = true;
                        }

                        LibraryChannel channel     = App.CurrentApp.GetChannel();
                        TimeSpan       old_timeout = channel.Timeout;
                        channel.Timeout = TimeSpan.FromSeconds(10);
                        try
                        {
                            GetEntityDataResult result = null;
                            List <NormalResult> errors = new List <NormalResult>();

                            EntityItem entity_record = null;

                            // ***
                            // 第一步:获取册记录

                            if (network == false)
                            {
                                // 先尝试从本地实体库中获得记录
                                entity_record = context.Entities.Where(o => o.PII == pii).FirstOrDefault();
                                // EntityItem entity_record = null;   // testing
                            }

                            if (entity_record != null)
                            {
                                result = new GetEntityDataResult
                                {
                                    Value       = 1,
                                    ItemXml     = entity_record.Xml,
                                    ItemRecPath = entity_record.RecPath,
                                    Title       = "",
                                }
                            }
                            ;
                            else
                            {
                                // 再尝试从 dp2library 服务器获取
                                // TODO: ItemXml 和 BiblioSummary 可以考虑在本地缓存一段时间
                                int nRedoCount = 0;
REDO_GETITEMINFO:
                                long lRet = channel.GetItemInfo(null,
                                                                "item",
                                                                pii,
                                                                "",
                                                                "xml",
                                                                out string item_xml,
                                                                out string item_recpath,
                                                                out byte[] timestamp,
                                                                "",
                                                                out _,
                                                                out _,
                                                                out string strError);
                                if (lRet == -1)
                                {
                                    if ((channel.ErrorCode == ErrorCode.RequestError ||
                                         channel.ErrorCode == ErrorCode.RequestTimeOut) &&
                                        nRedoCount < 2)
                                    {
                                        nRedoCount++;
                                        goto REDO_GETITEMINFO;
                                    }
                                    // TODO: 这里不着急返回,还需要尝试获得书目摘要
                                    errors.Add(new NormalResult
                                    {
                                        Value     = -1,
                                        ErrorInfo = strError,
                                        ErrorCode = channel.ErrorCode.ToString()
                                    });

                                    /*
                                     * return new GetEntityDataResult
                                     * {
                                     *  Value = -1,
                                     *  ErrorInfo = strError,
                                     *  ErrorCode = channel.ErrorCode.ToString()
                                     * };
                                     */
                                }
                                else
                                {
                                    result = new GetEntityDataResult
                                    {
                                        Value       = 1,
                                        ItemXml     = item_xml,
                                        ItemRecPath = item_recpath,
                                        Title       = "",
                                    };

                                    // 保存到本地数据库
                                    await AddOrUpdateAsync(context, new EntityItem
                                    {
                                        PII       = pii,
                                        Xml       = item_xml,
                                        RecPath   = item_recpath,
                                        Timestamp = timestamp,
                                    });

#if NO
                                    context.Entities.Add(new EntityItem
                                    {
                                        PII       = pii,
                                        Xml       = item_xml,
                                        RecPath   = item_recpath,
                                        Timestamp = timestamp,
                                    });
                                    try
                                    {
                                        await context.SaveChangesAsync();
                                    }
                                    catch (Exception ex)
                                    {
                                        SqliteException sqlite_exception = ex.InnerException as SqliteException;
                                        if (sqlite_exception != null && sqlite_exception.SqliteErrorCode == 19)
                                        {
                                            // PII 发生重复了
                                        }
                                        else
                                        {
                                            throw ex;
                                        }
                                    }
#endif
                                }
                            }

                            // ***
                            /// 第二步:获取书目摘要

                            // 先尝试从本地书目库中获取书目摘要

                            var item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault();
                            if (item != null &&
                                string.IsNullOrEmpty(item.BiblioSummary) == false)
                            {
                                if (result == null)
                                {
                                    result = new GetEntityDataResult();
                                }

                                result.Title = item.BiblioSummary;
                            }
                            else
                            {
                                // 从 dp2library 服务器获取书目摘要
                                int nRedoCount = 0;
REDO_GETBIBLIOSUMMARY:
                                long lRet = channel.GetBiblioSummary(
                                    null,
                                    pii,
                                    "", // strConfirmItemRecPath,
                                    null,
                                    out _,
                                    out string strSummary,
                                    out string strError);
                                if (lRet == -1)
                                {
                                    if ((channel.ErrorCode == ErrorCode.RequestError ||
                                         channel.ErrorCode == ErrorCode.RequestTimeOut) &&
                                        nRedoCount < 2)
                                    {
                                        nRedoCount++;
                                        goto REDO_GETBIBLIOSUMMARY;
                                    }

                                    errors.Add(new NormalResult
                                    {
                                        Value     = -1,
                                        ErrorInfo = strError,
                                        ErrorCode = channel.ErrorCode.ToString()
                                    });

                                    /*
                                     * return new GetEntityDataResult
                                     * {
                                     *  Value = -1,
                                     *  ErrorInfo = strError,
                                     *  ErrorCode = channel.ErrorCode.ToString(),
                                     * };
                                     */
                                }
                                else
                                {
                                    strSummary = strSummary?.Replace(". -- ", "\r\n"); // .Replace("/", "\r\n");

                                    if (result == null)
                                    {
                                        result = new GetEntityDataResult();
                                    }

                                    result.Title = strSummary;

                                    // 存入数据库备用
                                    if (lRet == 1 && string.IsNullOrEmpty(strSummary) == false)
                                    {
                                        try
                                        {
                                            var exist_item = context.BiblioSummaries.Where(o => o.PII == pii).FirstOrDefault();

                                            if (exist_item != null)
                                            {
                                                if (exist_item.BiblioSummary != strSummary)
                                                {
                                                    exist_item.BiblioSummary = strSummary;
                                                    context.BiblioSummaries.Update(exist_item);
                                                }
                                            }
                                            else
                                            {
                                                context.BiblioSummaries.Add(new BiblioSummaryItem
                                                {
                                                    PII           = pii,
                                                    BiblioSummary = strSummary
                                                });
                                            }
                                            await context.SaveChangesAsync();
                                        }
                                        catch (Exception ex)
                                        {
                                            WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 中保存 summary 时(PII 为 '{pii}')出现异常:{ExceptionUtil.GetDebugText(ex)}");
                                        }
                                    }
                                }

                                /*
                                 * return new GetEntityDataResult
                                 * {
                                 *  Value = (int)lRet,
                                 *  ItemXml = item_xml,
                                 *  ItemRecPath = item_recpath,
                                 *  Title = strSummary,
                                 *  ErrorInfo = strError,
                                 *  ErrorCode = channel.ErrorCode.ToString()
                                 * };
                                 */
                            }

                            // 完全成功
                            if (result != null && errors.Count == 0)
                            {
                                return(result);
                            }
                            if (result == null)
                            {
                                return new GetEntityDataResult
                                       {
                                           Value     = errors[0].Value,
                                           ErrorInfo = errors[0].ErrorInfo,
                                           ErrorCode = errors[0].ErrorCode
                                       }
                            }
                            ;
                            result.ErrorInfo = errors[0].ErrorInfo;
                            result.ErrorCode = errors[0].ErrorCode;
                            return(result);
                        }
                        finally
                        {
                            channel.Timeout = old_timeout;
                            App.CurrentApp.ReturnChannel(channel);
                        }
                    }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"GetEntityDataAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");

                return(new GetEntityDataResult
                {
                    Value = -1,
                    ErrorInfo = $"GetEntityDataAsync() 出现异常: {ex.Message}",
                    ErrorCode = ex.GetType().ToString()
                });
            }
        }
        private void GetColumns(DbConnection connection, DatabaseTable table)
        {
            using var command   = connection.CreateCommand();
            command.CommandText = new StringBuilder()
                                  .AppendLine("SELECT \"name\", \"type\", \"notnull\", \"dflt_value\", \"hidden\"")
                                  .AppendLine("FROM pragma_table_xinfo(@table)")
                                  .AppendLine("WHERE \"hidden\" IN (0, 2, 3)")
                                  .AppendLine("ORDER BY \"cid\";")
                                  .ToString();

            var parameter = command.CreateParameter();

            parameter.ParameterName = "@table";
            parameter.Value         = table.Name;
            command.Parameters.Add(parameter);

            using var reader = command.ExecuteReader();
            while (reader.Read())
            {
                var columnName   = reader.GetString(0);
                var dataType     = reader.GetString(1);
                var notNull      = reader.GetBoolean(2);
                var defaultValue = !reader.IsDBNull(3)
                    ? FilterClrDefaults(dataType, notNull, reader.GetString(3))
                    : null;
                var hidden = reader.GetInt64(4);

                _logger.ColumnFound(table.Name, columnName, dataType, notNull, defaultValue);

                var autoIncrement = 0;
                if (connection is SqliteConnection sqliteConnection &&
                    !(table is DatabaseView))
                {
                    var db = sqliteConnection.Handle;
                    var rc = sqlite3_table_column_metadata(
                        db,
                        connection.Database,
                        table.Name,
                        columnName,
                        out var _,
                        out var _,
                        out var _,
                        out var _,
                        out autoIncrement);
                    SqliteException.ThrowExceptionForRC(rc, db);
                }

                table.Columns.Add(
                    new DatabaseColumn
                {
                    Table           = table,
                    Name            = columnName,
                    StoreType       = dataType,
                    IsNullable      = !notNull,
                    DefaultValueSql = defaultValue,
                    ValueGenerated  = autoIncrement != 0
                            ? ValueGenerated.OnAdd
                            : default(ValueGenerated?),
                    ComputedColumnSql = hidden != 2L && hidden != 3L
                            ? null
                            : string.Empty,
                    IsStored = hidden != 3L
                            ? default(bool?)
                            : true
                });
            }
        }
 public static bool IsBusyOrLocked(this SqliteException ex) =>
 ex.SqliteErrorCode
 is SQLitePCL.raw.SQLITE_BUSY
Exemple #6
0
        static public tgConcurrencyException CheckForConcurrencyException(SqliteException ex)
        {
            tgConcurrencyException ce = null;

            return(ce);
        }
Exemple #7
0
 public CommitFailedException(Database db, int rc) : base(GetMessage(db, rc), rc, rc)
 {
     SqliteException.ThrowExceptionForRC(SQLitePCL.raw.SQLITE_ABORT, db.Connection.Handle);
 }