mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 10:57:07 +00:00
Compare commits
53 Commits
334-add-4d
...
a8ff7f3b52
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8ff7f3b52 | ||
|
|
15b62ff581 | ||
|
|
ade86be556 | ||
|
|
53594416a7 | ||
|
|
ff4b4a9c90 | ||
|
|
5842940d3b | ||
|
|
df6f1b2d32 | ||
|
|
c39afc1f3c | ||
|
|
a68000eac6 | ||
|
|
87aa78af00 | ||
|
|
3b9061aeae | ||
|
|
57dae4c755 | ||
|
|
b1344bebd8 | ||
|
|
3e91ccba8d | ||
|
|
fa0be9c0b7 | ||
|
|
dcbf5496f6 | ||
|
|
8007f46e37 | ||
|
|
4a7683cfd0 | ||
|
|
565a9d7e01 | ||
|
|
b07244c823 | ||
|
|
c909edc41f | ||
|
|
41ef511123 | ||
|
|
4196e9760b | ||
|
|
6b6f5ab511 | ||
|
|
7d8c78648d | ||
|
|
faf7e9c98f | ||
|
|
abf2709705 | ||
|
|
f5dfafd85a | ||
|
|
cf8b0937d9 | ||
|
|
d737f5d676 | ||
|
|
5fe19da586 | ||
|
|
0af0cf4b42 | ||
|
|
ccb8205d26 | ||
|
|
9b3fffdcfc | ||
|
|
dea1e9ee0d | ||
|
|
d45ec767ec | ||
|
|
67520ffc48 | ||
|
|
22a296ba26 | ||
|
|
f89435d80f | ||
|
|
a3f1dd490c | ||
|
|
2fcfcb4f84 | ||
|
|
b60db7e7ef | ||
|
|
4bb087fff7 | ||
|
|
15af5effc3 | ||
|
|
b5c6d04e62 | ||
|
|
571c5a8bca | ||
|
|
c45982829c | ||
|
|
f3958b37b7 | ||
|
|
58374adc68 | ||
|
|
32aea8a5ed | ||
|
|
023b65285f | ||
|
|
a320962669 | ||
|
|
0c0067b8d9 |
@@ -1,7 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Maximum runtime in seconds before killing an overdue instance (e.g., 10 minutes)
|
||||
MAX_RUNTIME_SECONDS=$((15 * 60))
|
||||
|
||||
DOUGAL_ROOT=${DOUGAL_ROOT:-$(dirname "$0")/..}
|
||||
|
||||
@@ -82,9 +80,8 @@ function run () {
|
||||
# DESCRIPTION=""
|
||||
SERVICE="deferred_imports"
|
||||
|
||||
# Disable GitLab alerts. They're just not very practical
|
||||
# $BINDIR/send_alert.py -t "$TITLE" -s "$SERVICE" -l "critical" \
|
||||
# -O "$(cat $STDOUTLOG)" -E "$(cat $STDERRLOG)"
|
||||
$BINDIR/send_alert.py -t "$TITLE" -s "$SERVICE" -l "critical" \
|
||||
-O "$(cat $STDOUTLOG)" -E "$(cat $STDERRLOG)"
|
||||
|
||||
exit 2
|
||||
}
|
||||
@@ -100,37 +97,14 @@ function cleanup () {
|
||||
}
|
||||
|
||||
if [[ -f $LOCKFILE ]]; then
|
||||
PID=$(cat "$LOCKFILE")
|
||||
if kill -0 "$PID" 2>/dev/null; then # Check if process is running
|
||||
# Get elapsed time in D-HH:MM:SS format and convert to seconds
|
||||
ELAPSED_STR=$(ps -p "$PID" -o etime= | tr -d '[:space:]')
|
||||
if [ -n "$ELAPSED_STR" ]; then
|
||||
# Convert D-HH:MM:SS to seconds
|
||||
ELAPSED_SECONDS=$(echo "$ELAPSED_STR" | awk -F'[-:]' '{
|
||||
seconds = 0
|
||||
if (NF == 4) { seconds += $1 * 86400 } # Days
|
||||
if (NF >= 3) { seconds += $NF-2 * 3600 } # Hours
|
||||
if (NF >= 2) { seconds += $NF-1 * 60 } # Minutes
|
||||
seconds += $NF # Seconds
|
||||
print seconds
|
||||
}')
|
||||
if [ "$ELAPSED_SECONDS" -gt "$MAX_RUNTIME_SECONDS" ]; then
|
||||
# Kill the overdue process (SIGTERM; use -9 for SIGKILL if needed)
|
||||
kill "$PID" 2>/dev/null
|
||||
print_warning $(printf "Killed overdue process (%d) that ran for %s (%d seconds)" "$PID" "$ELAPSED_STR" "$ELAPSED_SECONDS")
|
||||
rm "$LOCKFILE"
|
||||
else
|
||||
print_warning $(printf "Previous process is still running (%d) for %s (%d seconds)" "$PID" "$ELAPSED_STR" "$ELAPSED_SECONDS")
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
print_warning $(printf "Could not retrieve elapsed time for process (%d)" "$PID")
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
rm "$LOCKFILE"
|
||||
print_warning $(printf "Previous process (%d) not found. Must have died unexpectedly" "$PID")
|
||||
fi
|
||||
PID=$(cat "$LOCKFILE")
|
||||
if pgrep -F "$LOCKFILE"; then
|
||||
print_warning $(printf "The previous process is still running (%d)" $PID)
|
||||
exit 1
|
||||
else
|
||||
rm "$LOCKFILE"
|
||||
print_warning $(printf "Previous process (%d) not found. Must have died unexpectedly" $PID)
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "$$" > "$LOCKFILE" || {
|
||||
|
||||
@@ -2,32 +2,8 @@
|
||||
|
||||
const cmp = require('../lib/www/server/lib/comparisons');
|
||||
|
||||
async function purgeComparisons () {
|
||||
const groups = await cmp.groups();
|
||||
const comparisons = await cmp.getGroup();
|
||||
|
||||
const pids = new Set(Object.values(groups).flat().map( p => p.pid ));
|
||||
const comparison_pids = new Set(comparisons.map( c => [ c.baseline_pid, c.monitor_pid ] ).flat());
|
||||
|
||||
for (const pid of comparison_pids) {
|
||||
if (!pids.has(pid)) {
|
||||
console.log(`${pid} no longer par of a group. Deleting comparisons`);
|
||||
|
||||
staleComps = comparisons.filter( c => c.baseline_pid == pid || c.monitor_pid == pid );
|
||||
for (c of staleComps) {
|
||||
console.log(`Deleting comparison ${c.baseline_pid} → ${c.monitor_pid}`);
|
||||
await cmp.remove(c.baseline_pid, c.monitor_pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function main () {
|
||||
|
||||
console.log("Looking for unreferenced comparisons to purge");
|
||||
await purgeComparisons();
|
||||
|
||||
console.log("Retrieving project groups");
|
||||
const groups = await cmp.groups();
|
||||
|
||||
@@ -36,7 +12,7 @@ async function main () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
console.log(`Found ${Object.keys(groups)?.length} groups: ${Object.keys(groups).join(", ")}`);
|
||||
console.log(`Found ${groups.length} groups: ${Object.keys(groups).join(", ")}`);
|
||||
|
||||
for (const groupName of Object.keys(groups)) {
|
||||
const projects = groups[groupName];
|
||||
@@ -45,11 +21,6 @@ async function main () {
|
||||
|
||||
const comparisons = await cmp.getGroup(groupName);
|
||||
|
||||
if (!comparisons || !comparisons.length) {
|
||||
console.log(`No comparisons found for ${groupName}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if there are any projects that have been modified since last comparison
|
||||
// or if there are any pairs that are no longer part of the group
|
||||
|
||||
|
||||
@@ -39,8 +39,7 @@ export default {
|
||||
default:
|
||||
return {
|
||||
editable: false,
|
||||
displaylogo: false,
|
||||
responsive: true
|
||||
displaylogo: false
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -49,8 +48,7 @@ export default {
|
||||
const base = {
|
||||
font: {
|
||||
color: this.$vuetify.theme.isDark ? "#fff" : undefined
|
||||
},
|
||||
autosize: true
|
||||
}
|
||||
};
|
||||
|
||||
switch (this.facet) {
|
||||
@@ -276,25 +274,18 @@ export default {
|
||||
replot () {
|
||||
if (this.plotted) {
|
||||
const ref = this.$refs.graph;
|
||||
if (ref && ref.clientWidth > 0 && ref.clientHeight > 0) {
|
||||
Plotly.relayout(ref, {
|
||||
width: ref.clientWidth,
|
||||
height: ref.clientHeight
|
||||
});
|
||||
}
|
||||
Plotly.relayout(ref, {
|
||||
width: ref.clientWidth,
|
||||
height: ref.clientHeight
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$nextTick( () => {
|
||||
if (this.items?.length) {
|
||||
this.plot();
|
||||
}
|
||||
this.resizeObserver = new ResizeObserver(this.replot)
|
||||
this.resizeObserver.observe(this.$refs.graph);
|
||||
});
|
||||
this.resizeObserver = new ResizeObserver(this.replot)
|
||||
this.resizeObserver.observe(this.$refs.graph);
|
||||
},
|
||||
|
||||
beforeDestroy () {
|
||||
|
||||
@@ -36,8 +36,7 @@ export default {
|
||||
config () {
|
||||
return {
|
||||
editable: false,
|
||||
displaylogo: false,
|
||||
responsive: true
|
||||
displaylogo: false
|
||||
};
|
||||
},
|
||||
|
||||
@@ -54,8 +53,7 @@ export default {
|
||||
title: "Time (s)"
|
||||
},
|
||||
plot_bgcolor:"rgba(0,0,0,0)",
|
||||
paper_bgcolor:"rgba(0,0,0,0)",
|
||||
autosize: true
|
||||
paper_bgcolor:"rgba(0,0,0,0)"
|
||||
};
|
||||
},
|
||||
|
||||
@@ -156,12 +154,10 @@ export default {
|
||||
replot () {
|
||||
if (this.plotted) {
|
||||
const ref = this.$refs.graph;
|
||||
if (ref && ref.clientWidth > 0 && ref.clientHeight > 0) {
|
||||
Plotly.relayout(ref, {
|
||||
width: ref.clientWidth,
|
||||
height: ref.clientHeight
|
||||
});
|
||||
}
|
||||
Plotly.relayout(ref, {
|
||||
width: ref.clientWidth,
|
||||
height: ref.clientHeight
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -194,13 +190,8 @@ export default {
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$nextTick( () => {
|
||||
if (this.items?.length) {
|
||||
this.plot();
|
||||
}
|
||||
this.resizeObserver = new ResizeObserver(this.replot)
|
||||
this.resizeObserver.observe(this.$refs.graph);
|
||||
});
|
||||
this.resizeObserver = new ResizeObserver(this.replot)
|
||||
this.resizeObserver.observe(this.$refs.graph);
|
||||
},
|
||||
|
||||
beforeDestroy () {
|
||||
|
||||
@@ -158,7 +158,6 @@ Vue.use(VueRouter)
|
||||
component: SequenceList
|
||||
},
|
||||
{
|
||||
name: "shotlog",
|
||||
path: "sequences/:sequence",
|
||||
component: SequenceSummary
|
||||
},
|
||||
|
||||
@@ -36,7 +36,7 @@ async function refreshEvents ({commit, dispatch, state, rootState}, [modifiedAft
|
||||
|
||||
/** Return a subset of events from state.events
|
||||
*/
|
||||
async function getEvents ({commit, dispatch, state}, [projectId, {sequence, date0, date1, sortBy, sortDesc, itemsPerPage, page, text, label, excludeLabels}]) {
|
||||
async function getEvents ({commit, dispatch, state}, [projectId, {sequence, date0, date1, sortBy, sortDesc, itemsPerPage, page, text, label}]) {
|
||||
let filteredEvents = [...state.events];
|
||||
|
||||
if (sortBy) {
|
||||
@@ -114,10 +114,6 @@ async function getEvents ({commit, dispatch, state}, [projectId, {sequence, date
|
||||
filteredEvents = filteredEvents.filter( event => event.labels?.includes(label) );
|
||||
}
|
||||
|
||||
if (excludeLabels) {
|
||||
filteredEvents = filteredEvents.filter( event => !excludeLabels?.some( label => event.labels?.includes(label) ) );
|
||||
}
|
||||
|
||||
const count = filteredEvents.length;
|
||||
|
||||
if (itemsPerPage && itemsPerPage > 0) {
|
||||
|
||||
@@ -5,22 +5,6 @@
|
||||
<v-card-title>
|
||||
<v-toolbar flat>
|
||||
<v-toolbar-title>
|
||||
<template v-if="$route.params.sequence">
|
||||
<v-btn icon small
|
||||
:disabled="sequenceIndex >= (sequences.length - 1)"
|
||||
:to="{name: 'logBySequence', params: { sequence: (sequences[sequences.length-1]||{}).sequence }}"
|
||||
title="Go to the first sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-double-left</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small
|
||||
:disabled="sequenceIndex >= (sequences.length - 1)"
|
||||
:to="{name: 'logBySequence', params: { sequence: (sequences[sequenceIndex+1]||{}).sequence }}"
|
||||
title="Go to the previous sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-left</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<span class="d-none d-lg-inline">
|
||||
{{
|
||||
$route.params.sequence
|
||||
@@ -47,38 +31,18 @@
|
||||
: ""
|
||||
}}
|
||||
</span>
|
||||
|
||||
<template v-if="$route.params.sequence">
|
||||
<v-btn icon small
|
||||
:disabled="sequenceIndex==0"
|
||||
:to="{name: 'logBySequence', params: { sequence: (sequences[sequenceIndex-1]||{}).sequence }}"
|
||||
title="Go to the next sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-right</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small class="mr-1"
|
||||
:disabled="sequenceIndex==0"
|
||||
:to="{name: 'logBySequence', params: { sequence: (sequences[0]||{}).sequence }}"
|
||||
title="Go to the last sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-double-right</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
<a v-if="$route.params.sequence"
|
||||
class="mr-3"
|
||||
:href="`/projects/${$route.params.project}/sequences/${$route.params.sequence}`"
|
||||
title="View the shotlog for this sequence"
|
||||
>
|
||||
<v-icon
|
||||
right
|
||||
color="teal"
|
||||
>mdi-format-list-numbered</v-icon>
|
||||
</a>
|
||||
|
||||
</v-toolbar-title>
|
||||
|
||||
|
||||
<a v-if="$route.params.sequence"
|
||||
class="mr-3"
|
||||
:href="`/projects/${$route.params.project}/sequences/${$route.params.sequence}`"
|
||||
title="View the shotlog for this sequence"
|
||||
>
|
||||
<v-icon
|
||||
right
|
||||
color="teal"
|
||||
>mdi-format-list-numbered</v-icon>
|
||||
</a>
|
||||
|
||||
<dougal-event-edit v-if="$parent.writeaccess()"
|
||||
v-model="eventDialog"
|
||||
@@ -530,6 +494,17 @@ export default {
|
||||
rows () {
|
||||
const rows = {};
|
||||
this.items
|
||||
.filter(i => {
|
||||
return !this.$route.params.sequence || (this.$route.params.sequence == i.sequence)
|
||||
})
|
||||
.filter(i => {
|
||||
for (const label of this.filterableLabels) {
|
||||
if (!this.shownLabels.includes(label) && i.labels.includes(label)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.forEach(i => {
|
||||
const key = (i.sequence && i.point) ? (i.sequence+"@"+i.point) : i.tstamp;
|
||||
if (!rows[key]) {
|
||||
@@ -560,10 +535,6 @@ export default {
|
||||
.sort( (a, b) => b[1]-a[1] );
|
||||
},
|
||||
|
||||
filteredLabels () {
|
||||
return this.filterableLabels.filter( label => !this.shownLabels.includes(label) );
|
||||
},
|
||||
|
||||
presetRemarks () {
|
||||
return this.projectConfiguration?.events?.presetRemarks ?? [];
|
||||
},
|
||||
@@ -576,17 +547,7 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
sequenceIndex () {
|
||||
if ("sequence" in this.$route.params) {
|
||||
const index = this.sequences.findIndex( i => i.sequence == this.$route.params.sequence );
|
||||
if (index != -1) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
// return undefined
|
||||
},
|
||||
|
||||
...mapGetters(['user', 'eventsLoading', 'online', 'sequence', 'sequences', 'line', 'point', 'position', 'timestamp', 'lineName', 'events', 'labels', 'userLabels', 'projectConfiguration']),
|
||||
...mapGetters(['user', 'eventsLoading', 'online', 'sequence', 'line', 'point', 'position', 'timestamp', 'lineName', 'events', 'labels', 'userLabels', 'projectConfiguration']),
|
||||
...mapState({projectSchema: state => state.project.projectSchema})
|
||||
|
||||
},
|
||||
@@ -594,7 +555,6 @@ export default {
|
||||
watch: {
|
||||
options: {
|
||||
async handler () {
|
||||
this.savePrefs(),
|
||||
await this.fetchEvents();
|
||||
},
|
||||
deep: true
|
||||
@@ -613,19 +573,12 @@ export default {
|
||||
},
|
||||
|
||||
filter (newVal, oldVal) {
|
||||
this.savePrefs();
|
||||
if (newVal?.toLowerCase() != oldVal?.toLowerCase()) {
|
||||
this.fetchEvents();
|
||||
}
|
||||
},
|
||||
|
||||
labelSearch () {
|
||||
this.savePrefs();
|
||||
this.fetchEvents();
|
||||
},
|
||||
|
||||
filteredLabels () {
|
||||
this.savePrefs()
|
||||
this.fetchEvents();
|
||||
},
|
||||
|
||||
@@ -634,7 +587,7 @@ export default {
|
||||
},
|
||||
|
||||
user (newVal, oldVal) {
|
||||
this.loadPrefs();
|
||||
this.itemsPerPage = Number(localStorage.getItem(`dougal/prefs/${this.user?.name}/${this.$route.params.project}/${this.$options.name}/items-per-page`)) || 25;
|
||||
}
|
||||
|
||||
},
|
||||
@@ -685,10 +638,8 @@ export default {
|
||||
|
||||
async fetchEvents (opts = {}) {
|
||||
const options = {
|
||||
sequence: this.$route.params.sequence,
|
||||
text: this.filter,
|
||||
label: this.labelSearch,
|
||||
excludeLabels: this.filteredLabels,
|
||||
...this.options
|
||||
};
|
||||
const res = await this.getEvents([this.$route.params.project, options]);
|
||||
@@ -926,36 +877,10 @@ export default {
|
||||
*/
|
||||
},
|
||||
|
||||
getPrefsKey () {
|
||||
return `dougal/prefs/${this.user?.name}/${this.$route.params.project}/Log/v1`;
|
||||
},
|
||||
|
||||
savePrefs () {
|
||||
const prefs = {
|
||||
shownLabels: this.shownLabels,
|
||||
labelSearch: this.labelSearch,
|
||||
filter: this.filter,
|
||||
options: this.options
|
||||
};
|
||||
localStorage.setItem(this.getPrefsKey(), JSON.stringify(prefs));
|
||||
},
|
||||
|
||||
loadPrefs () {
|
||||
const stored = localStorage.getItem(this.getPrefsKey());
|
||||
if (stored) {
|
||||
const prefs = JSON.parse(stored);
|
||||
if (prefs.shownLabels !== undefined) this.shownLabels = prefs.shownLabels;
|
||||
if (prefs.labelSearch !== undefined) this.labelSearch = prefs.labelSearch;
|
||||
if (prefs.filter !== undefined) this.filter = prefs.filter;
|
||||
if (prefs.options !== undefined) this.options = prefs.options;
|
||||
}
|
||||
},
|
||||
|
||||
...mapActions(["api", "showSnack", "refreshEvents", "getEvents"])
|
||||
},
|
||||
|
||||
async mounted () {
|
||||
this.loadPrefs();
|
||||
this.fetchEvents();
|
||||
|
||||
window.addEventListener('keyup', this.handleKeyboardEvent);
|
||||
|
||||
@@ -6,42 +6,8 @@
|
||||
<v-progress-linear indeterminate v-if="loading"></v-progress-linear>
|
||||
<v-toolbar flat>
|
||||
<v-toolbar-title>
|
||||
<template v-if="$route.params.sequence">
|
||||
<v-btn icon small
|
||||
:disabled="sequenceIndex >= (sequences.length - 1)"
|
||||
:to="{name: 'shotlog', params: { sequence: (sequences[sequences.length-1]||{}).sequence }}"
|
||||
title="Go to the first sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-double-left</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small
|
||||
:disabled="sequenceIndex >= (sequences.length - 1)"
|
||||
:to="{name: 'shotlog', params: { sequence: (sequences[sequenceIndex+1]||{}).sequence }}"
|
||||
title="Go to the previous sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-left</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
|
||||
Sequence {{sequenceNumber}}
|
||||
<small :class="statusColour" v-if="sequence">({{sequence.status}})</small>
|
||||
|
||||
<template v-if="$route.params.sequence">
|
||||
<v-btn icon small
|
||||
:disabled="sequenceIndex==0"
|
||||
:to="{name: 'shotlog', params: { sequence: (sequences[sequenceIndex-1]||{}).sequence }}"
|
||||
title="Go to the next sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-right</v-icon>
|
||||
</v-btn>
|
||||
<v-btn icon small class="mr-1"
|
||||
:disabled="sequenceIndex==0"
|
||||
:to="{name: 'shotlog', params: { sequence: (sequences[0]||{}).sequence }}"
|
||||
title="Go to the last sequence"
|
||||
>
|
||||
<v-icon dense>mdi-chevron-double-right</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-toolbar-title>
|
||||
|
||||
<a v-if="$route.params.sequence"
|
||||
@@ -386,16 +352,6 @@ export default {
|
||||
return this.sequences.find(i => i.sequence == this.sequenceNumber);
|
||||
},
|
||||
|
||||
sequenceIndex () {
|
||||
if ("sequence" in this.$route.params) {
|
||||
const index = this.sequences.findIndex( i => i.sequence == this.$route.params.sequence );
|
||||
if (index != -1) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
// return undefined
|
||||
},
|
||||
|
||||
remarks () {
|
||||
return this.sequence?.remarks || "Nil.";
|
||||
},
|
||||
|
||||
@@ -330,80 +330,44 @@ async function saveGroup (group, opts = {}) {
|
||||
|
||||
async function getGroup (groupName, opts = {}) {
|
||||
|
||||
const group = (await groups())?.[groupName]?.map( i => i.pid)?.sort();
|
||||
|
||||
if (!group?.length) return;
|
||||
|
||||
const client = await pool.connect();
|
||||
|
||||
try {
|
||||
|
||||
if (groupName) {
|
||||
const pairs = combinations(group, 2);
|
||||
const flatValues = pairs.flat();
|
||||
const placeholders = [];
|
||||
for (let i = 0; i < pairs.length; i++) {
|
||||
placeholders.push(`($${i * 2 + 1}, $${i * 2 + 2})`);
|
||||
}
|
||||
const inClause = placeholders.join(',');
|
||||
const selectFields = opts.returnData ? 'data, meta' : 'meta';
|
||||
|
||||
const group = (await groups())?.[groupName]?.map( i => i.pid)?.sort();
|
||||
const text = `
|
||||
SELECT baseline_pid, monitor_pid, ${selectFields}
|
||||
FROM comparisons.comparisons
|
||||
WHERE type = 'geometric_difference'
|
||||
AND (baseline_pid, monitor_pid) IN (VALUES ${inClause})
|
||||
ORDER BY baseline_pid, monitor_pid
|
||||
`;
|
||||
|
||||
if (!group?.length || group?.length < 2) return;
|
||||
|
||||
|
||||
const pairs = combinations(group, 2);
|
||||
const flatValues = pairs.flat();
|
||||
const placeholders = [];
|
||||
for (let i = 0; i < pairs.length; i++) {
|
||||
placeholders.push(`($${i * 2 + 1}, $${i * 2 + 2})`);
|
||||
}
|
||||
const inClause = placeholders.join(',');
|
||||
const selectFields = opts.returnData ? 'data, meta' : 'meta';
|
||||
|
||||
const text = `
|
||||
SELECT baseline_pid, monitor_pid, ${selectFields}
|
||||
FROM comparisons.comparisons
|
||||
WHERE type = 'geometric_difference'
|
||||
AND (baseline_pid, monitor_pid) IN (VALUES ${inClause})
|
||||
ORDER BY baseline_pid, monitor_pid
|
||||
`;
|
||||
|
||||
if (!placeholders) {
|
||||
console.log("No pairs found in group");
|
||||
return [];
|
||||
}
|
||||
|
||||
const res = await client.query(text, flatValues);
|
||||
if (!res.rows.length) {
|
||||
console.log("Comparison not found in database");
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts.returnData) {
|
||||
return res.rows.map( row => ({
|
||||
...row,
|
||||
data: DougalBinaryBundle.clone(row.data),
|
||||
}));
|
||||
} else {
|
||||
return res.rows;
|
||||
}
|
||||
const res = await client.query(text, flatValues);
|
||||
if (!res.rows.length) {
|
||||
console.log("Comparison not found in database");
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts.returnData) {
|
||||
return res.rows.map( row => ({
|
||||
...row,
|
||||
data: DougalBinaryBundle.clone(row.data),
|
||||
}));
|
||||
} else {
|
||||
|
||||
const selectFields = opts.returnData ? 'data, meta' : 'meta';
|
||||
|
||||
const text = `
|
||||
SELECT baseline_pid, monitor_pid, ${selectFields}
|
||||
FROM comparisons.comparisons
|
||||
WHERE type = 'geometric_difference'
|
||||
ORDER BY baseline_pid, monitor_pid
|
||||
`;
|
||||
|
||||
const res = await client.query(text);
|
||||
if (!res.rows.length) {
|
||||
console.log("Comparison not found in database");
|
||||
return;
|
||||
}
|
||||
|
||||
if (opts.returnData) {
|
||||
return res.rows.map( row => ({
|
||||
...row,
|
||||
data: DougalBinaryBundle.clone(row.data),
|
||||
}));
|
||||
} else {
|
||||
return res.rows;
|
||||
}
|
||||
|
||||
return res.rows;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
|
||||
Reference in New Issue
Block a user