/// <summary> /// 创建数据库和表 /// </summary> /// <param name="conn">数据库连接</param> /// <param name="sqlStatements">SQL 语句</param> protected virtual void EnsureDatabaseAndTableCreated(IDbConnection conn, SqlStatements sqlStatements) { if (!string.IsNullOrWhiteSpace(sqlStatements.CreateDatabaseSql)) { conn.Execute(sqlStatements.CreateDatabaseSql); } conn.Execute(sqlStatements.CreateTableSql); }
/// <summary> /// 生成 SQL 语句 /// </summary> /// <param name="tableMetadata">表元数据</param> /// <returns></returns> protected override SqlStatements GenerateSqlStatements(TableMetadata tableMetadata) { var sqlStatements = new SqlStatements { InsertSql = GenerateInsertSql(tableMetadata, false), InsertIgnoreDuplicateSql = GenerateInsertSql(tableMetadata, true), InsertAndUpdateSql = GenerateInsertAndUpdateSql(tableMetadata), UpdateSql = GenerateUpdateSql(tableMetadata), CreateTableSql = GenerateCreateTableSql(tableMetadata), CreateDatabaseSql = GenerateCreateDatabaseSql(tableMetadata), DatabaseSql = string.IsNullOrWhiteSpace(tableMetadata.Schema.Database) ? "" : $"{Escape}{GetNameSql(tableMetadata.Schema.Database)}{Escape}" }; return(sqlStatements); }
/// <summary> /// 创建数据库和表 /// </summary> /// <param name="conn">数据库连接</param> /// <param name="sqlStatements">SQL 语句</param> protected override void EnsureDatabaseAndTableCreated(IDbConnection conn, SqlStatements sqlStatements) { if (!string.IsNullOrWhiteSpace(sqlStatements.CreateDatabaseSql)) { try { conn.Execute(sqlStatements.CreateDatabaseSql); conn.Execute(sqlStatements.CreateDatabaseSql); } catch (Exception e) { if (e.Message != $"42P04: database {sqlStatements.DatabaseSql} already exists") { throw; } } } conn.Execute(sqlStatements.CreateTableSql); }
protected override async Task <DataFlowResult> Store(DataFlowContext context) { IDbConnection conn = TryCreateDbConnection(context); using (conn) { foreach (var item in context.GetParseData()) { var tableMetadata = (TableMetadata)context[item.Key]; SqlStatements sqlStatements = GetSqlStatements(tableMetadata); if (_executedCache.TryAdd(sqlStatements.CreateTableSql, new object())) { EnsureDatabaseAndTableCreated(conn, sqlStatements); } for (int i = 0; i < RetryTimes; ++i) { IDbTransaction transaction = null; try { if (UseTransaction) { transaction = conn.BeginTransaction(); } var list = item.Value; switch (StorageType) { case StorageType.Insert: { await conn.ExecuteAsync(sqlStatements.InsertSql, list, transaction); break; } case StorageType.InsertIgnoreDuplicate: { await conn.ExecuteAsync(sqlStatements.InsertIgnoreDuplicateSql, list, transaction); break; } case StorageType.Update: { if (string.IsNullOrWhiteSpace(sqlStatements.UpdateSql)) { throw new SpiderException("未能生成更新 SQL"); } await conn.ExecuteAsync(sqlStatements.UpdateSql, list, transaction); break; } case StorageType.InsertAndUpdate: { await conn.ExecuteAsync(sqlStatements.InsertAndUpdateSql, list, transaction); break; } } transaction?.Commit(); break; } catch (Exception ex) { Logger?.LogError($"尝试插入数据失败: {ex}"); // 网络异常需要重试,并且不需要 Rollback var endOfStreamException = ex.InnerException as EndOfStreamException; if (endOfStreamException == null) { try { transaction?.Rollback(); } catch (Exception e) { Logger?.LogError($"数据库回滚失败: {e}"); } break; } } finally { transaction?.Dispose(); } } } } return(DataFlowResult.Success); }