async Task <(string[] files, long rows, ByteSize size)> CopyInto(ILoggedConnection <IDbConnection> db, string table, StageTableCfg t) { var startTime = await db.ExecuteScalar <string>("current time", "select current_timestamp()::string"); var(stage, path) = t.StoreType switch { DataStoreType.Db => (Cfg.Stage, StorageCfg.DbPath), DataStoreType.Private => (Cfg.Private, null), _ => throw new InvalidOperationException($"No warehouse stage for store type {t.StoreType}") }; var sql = $"copy into {table} from @{new[] {stage, path}.Concat(t.Dir.Tokens).NotNull().Join(" / ")}/ file_format=(type=json)"; await db.Execute("copy into", sql); // sf should return this info form copy_into (its in their UI, but not in .net or jdbc drivers) // the int that is return is the # of rows form the first file loaded. So we go get this ourselves var copyResults = await db.Query <(string fileName, long rows, long size)>("copy results", "select file_name, row_count, file_size " + $"from table(information_schema.copy_history(table_name=>'{table}', start_time=>'{startTime}'::timestamp_ltz))"); var res = (copyResults.Select(r => r.fileName).ToArray(), copyResults.Sum(r => r.rows), copyResults.Sum(r => r.size).Bytes()); return(res); } }
public static async Task <DateTime?> LatestTimestamp(this StageTableCfg t, ILoggedConnection <IDbConnection> db) => await db.ExecuteScalar <DateTime?>("latest timestamp", $"select max(v:{t.TsCol ?? "Updated"}::timestamp_ntz) from {t.Table}");