Skip to content

Commit

Permalink
support multi-line query
Browse files Browse the repository at this point in the history
show server name on the result
  • Loading branch information
Kenneth Choe committed May 7, 2020
1 parent b63975a commit 3a31510
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 49 deletions.
10 changes: 10 additions & 0 deletions src/SqlCrawler.Backend/Tabularizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,17 @@ namespace SqlCrawler.Backend
{
public class Tabularizer
{
private readonly SqlCredentialReader _reader;

public Tabularizer(SqlCredentialReader reader)
{
_reader = reader;
}

public IEnumerable<dynamic> Process(IEnumerable<ResultRecord> records)
{
var servers = _reader.Read();

foreach (var record in records)
{
dynamic result = new ExpandoObject();
Expand All @@ -32,6 +41,7 @@ public IEnumerable<dynamic> Process(IEnumerable<ResultRecord> records)
}

result.ServerId = record.ServerId;
result.ServerName = servers.SingleOrDefault(x => x.ServerId == record.ServerId)?.ServerName;
yield return result;
}
}
Expand Down
26 changes: 24 additions & 2 deletions src/SqlCrawler.Tests/TabularizerTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Autofac;
using Newtonsoft.Json;
using NUnit.Framework;
using SqlCrawler.Backend;
Expand All @@ -24,11 +25,32 @@ public void Process()
}
};

var svc = new Tabularizer();
var svc = TestBootstrapper.Scope.Resolve<Tabularizer>();

var result = svc.Process(records);
Console.WriteLine(JsonConvert.SerializeObject(result));
var kv = (IDictionary<string, object>) result.Single();
CollectionAssert.AreEquivalent(new [] { "ServerId", "DateTime"}, kv.Keys);
CollectionAssert.AreEquivalent(new [] { "ServerId", "ServerName", "DateTime"}, kv.Keys);
}

[Test]
public void DataContainsMultipleRecords()
{
var records = new List<ResultRecord>
{
new ResultRecord
{
ServerId = "a",
SessionRowId = 1,
DataJson = "[{\"DateTime\":\"2020-05-03T13:38:28.467\"}, {\"DateTime\":\"2020-05-04T13:38:28.467\"}]"
}
};

var svc = TestBootstrapper.Scope.Resolve<Tabularizer>();
var result = svc.Process(records);
Console.WriteLine(JsonConvert.SerializeObject(result));
var kv = (IDictionary<string, object>)result.Single();
CollectionAssert.AreEquivalent(new[] { "ServerId", "ServerName", "Rows" }, kv.Keys);
}
}
}
98 changes: 98 additions & 0 deletions src/vue/src/components/DynamicColumnTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
<template>
<v-data-table
:headers="headers"
:options.sync="options"
:loading="loading || running"
:items="results"
:items-per-page="-1"
item-key="ServerId"
show-expand
:hide-default-footer="true"
>
<template v-slot:item.data-table-expand="{ item, isExpanded, expand }">
<v-icon
@click="expand(true)"
v-if="item.Error && !isExpanded"
color="error"
>mdi-alert-circle</v-icon
>
<v-icon
@click="expand(false)"
v-if="item.Error && isExpanded"
color="error"
>mdi-alert-circle-outline</v-icon
>
</template>
<template v-slot:expanded-item="{ headers, item }">
<error-info :headers="headers" :item="item" />
</template>
<template v-slot:item.Rows="{ value }">
<v-card class="ma-4">
<dynamic-column-table
v-if="value && value.length"
:results="value"
:initial-headers="[]"
/>
</v-card>
</template>
<template v-slot:progress>
<v-progress-linear :indeterminate="loading" :value="loadingProgress" />
</template>
</v-data-table>
</template>

<script>
import ErrorInfo from "../components/ErrorInfo.vue";
export default {
name: "dynamic-column-table",
components: {
ErrorInfo
},
props: {
results: {
type: Array,
required: true
},
initialHeaders: {
type: Array,
required: true
},
loadingProgress: {
type: Number,
required: false,
default: 0
},
loading: {
type: Boolean,
required: false,
default: false
},
running: {
type: Boolean,
required: false,
default: false
}
},
data: () => ({
loading: false,
running: false,
options: {}
}),
computed: {
headers() {
const result = this.initialHeaders;
if (this.results.length > 0) {
for (let i = 0; i < this.results.length; i++) {
Object.keys(this.results[i]).forEach(c => {
if (c === "Error") return;
if (result.findIndex(x => x.text === c) >= 0) return;
result.push({ text: c, value: c });
});
}
}
return result;
}
}
};
</script>
File renamed without changes.
59 changes: 12 additions & 47 deletions src/vue/src/views/PollByQuery.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,49 +45,28 @@
<v-btn text @click="hasError = false">Close </v-btn>
</v-snackbar>
<br />
<v-data-table
:headers="headers"
:options.sync="options"
:loading="loading || running"
:items="results"
:items-per-page="-1"
item-key="ServerId"
show-expand
:hide-default-footer="true"
>
<template v-slot:item.data-table-expand="{ item, isExpanded, expand }">
<v-icon
@click="expand(true)"
v-if="item.Error && !isExpanded"
color="error"
>mdi-alert-circle</v-icon
>
<v-icon
@click="expand(false)"
v-if="item.Error && isExpanded"
color="error"
>mdi-alert-circle-outline</v-icon
>
</template>
<template v-slot:expanded-item="{ headers, item }">
<error-info :headers="headers" :item="item" />
</template>
<template v-slot:progress>
<v-progress-linear :indeterminate="loading" :value="queryProgress" />
</template>
</v-data-table>
<dynamic-column-table
:loading="loading"
:running="running"
:loading-progress="queryProgress"
:results="results"
:initialHeaders="[
{ text: 'ServerId', value: 'ServerId' },
{ text: 'ServerName', value: 'ServerName' }
]"
/>
</div>
</template>

<script>
import { mapState, mapActions } from "vuex";
import axios from "axios";
import ErrorInfo from "./ErrorInfo.vue";
import DynamicColumnTable from "../components/DynamicColumnTable.vue";
import { toLocalString } from "./formatter";
export default {
components: {
ErrorInfo
DynamicColumnTable
},
props: {
queryName: {
Expand All @@ -98,7 +77,6 @@ export default {
data: () => ({
loading: false,
running: false,
options: {},
hasError: false,
errorMessage: "",
showErrorInfo: false,
Expand All @@ -107,19 +85,6 @@ export default {
}),
computed: {
...mapState(["results", "queries", "queryProgress"]),
headers() {
const result = [{ text: "ServerId", value: "ServerId" }];
if (this.results.length > 0) {
for (let i = 0; i < this.results.length; i++) {
Object.keys(this.results[i]).forEach(c => {
if (c === "Error") return;
if (result.findIndex(x => x.text === c) >= 0) return;
result.push({ text: c, value: c });
});
}
}
return result;
},
queryBody() {
const query = this.queries.filter(x => x.name === this.queryName);
return query.length ? query[0].query : "";
Expand Down

0 comments on commit 3a31510

Please sign in to comment.