in Arriba/Arriba.Communication/Server/Application/ArribaImportApplication.cs [145:235]
private async Task<IResponse> JSONArrayAppendAsync(IRequestContext ctx, Route route)
{
var content = ctx.Request.Headers["Content-Type"];
if (String.IsNullOrEmpty(content) || !String.Equals(content, "application/json", StringComparison.OrdinalIgnoreCase))
{
return ArribaResponse.BadRequest("Content-Type of {0} was not expected", content);
}
else if (!ctx.Request.HasBody)
{
return ArribaResponse.BadRequest("Empty request body");
}
var tableName = GetAndValidateTableName(route);
var table = this.Database[tableName];
if (table == null)
{
return ArribaResponse.BadRequest("Table {0} is not loaded or does not exist", tableName);
}
var rows = await ctx.Request.ReadBodyAsync<List<Dictionary<string, object>>>();
var detail = new
{
RequestSize = ctx.Request.Headers["Content-Length"],
RowCount = rows.Count
};
using (ctx.Monitor(MonitorEventLevel.Information, "Import.JsonObjectArray", type: "Table", identity: tableName, detail: detail))
{
// Read column names from JSON
var columnDetails = new Dictionary<string, ColumnDetails>();
foreach (var row in rows)
{
foreach (var property in row)
{
if (property.Value != null && !columnDetails.ContainsKey(property.Key))
{
var colDetail = new ColumnDetails(property.Key);
columnDetails.Add(property.Key, colDetail);
}
}
}
var columns = columnDetails.Values.ToArray();
// Insert the data in batches
var block = new DataBlock(columns, BatchSize);
for (int batchOffset = 0; batchOffset < rows.Count; batchOffset += BatchSize)
{
int rowsLeft = rows.Count - batchOffset;
int rowsInBatch = BatchSize;
if (rowsLeft < BatchSize)
{
block = new DataBlock(columns, rowsLeft);
rowsInBatch = rowsLeft;
}
for (int blockRowIndex = 0; blockRowIndex < rowsInBatch; ++blockRowIndex)
{
int sourceRowIndex = blockRowIndex + batchOffset;
for (int columnIndex = 0; columnIndex < columns.Length; columnIndex++)
{
object value = null;
if (rows[sourceRowIndex].TryGetValue(columns[columnIndex].Name, out value))
{
block[blockRowIndex, columnIndex] = value;
}
}
}
table.AddOrUpdate(block, new AddOrUpdateOptions() { AddMissingColumns = true });
}
using (ctx.Monitor(MonitorEventLevel.Verbose, "table.save"))
{
table.Save();
}
return ArribaResponse.Created(new ImportResponse
{
TableName = table.Name,
RowCount = rows.Count(),
Columns = columns.Select((cd) => cd.Name).ToArray()
});
}
}