add orderby clause
Some checks failed
Go / build (1.22) (push) Failing after 1m58s
Go / build (1.21) (push) Failing after 2m1s

This commit is contained in:
saji 2024-03-06 10:48:40 -06:00
parent d90d7a0af4
commit 8e314e9303
4 changed files with 137 additions and 90 deletions

10
db.go
View file

@ -141,12 +141,20 @@ type LimitOffsetModifier struct {
Offset int
}
func (l LimitOffsetModifier) ModifyStatement(sb *strings.Builder) error {
func (l *LimitOffsetModifier) ModifyStatement(sb *strings.Builder) error {
clause := fmt.Sprintf(" LIMIT %d OFFSET %d", l.Limit, l.Offset)
sb.WriteString(clause)
return nil
}
type OrderByTimestampModifer struct {
}
func (o *OrderByTimestampModifer) ModifyStatement(sb *strings.Builder) error {
sb.WriteString(" ORDER BY ts DESC")
return nil
}
// BusEventFilter is a filter for bus events.
type BusEventFilter struct {
Names []string

View file

@ -264,12 +264,14 @@ func apiV1GetValues(db *TelemDb) http.HandlerFunc {
// override the bus event filter name option
bef.Names = []string{name}
var order = &OrderByTimestampModifer{}
var res []Datum
// make the call, skip the limit modifier if it's nil.
if lim == nil {
res, err = db.GetValues(r.Context(), *bef, field)
res, err = db.GetValues(r.Context(), *bef, field, order)
} else {
res, err = db.GetValues(r.Context(), *bef, field, lim)
res, err = db.GetValues(r.Context(), *bef, field, lim, order)
}
if err != nil {
// 500 server error:

View file

@ -68,3 +68,39 @@ Certain features, like socketCAN support, are only enabled on platforms that sup
This is handled automatically; builds will exclude the socketCAN files and
the additional commands and features will not be present in the CLI.
### Lightweight Build
This doesn't include the OpenMCT files, but is simpler to build, and doesn't require Node setup.
You must install Go.
```
$ go build ./cmd/gotelem
```
### Full Build
This includes an integrated OpenMCT build, which automatically connects to the Telemetry server
for historical and live data. You must have both Go and Node.JS installed.
```
$ cd web/
$ npm install
$ npm run build
$ cd ..
$ go build -tags openmct ./cmd/gotelem
```
## Development
During development, it can be useful to have the OpenMCT sources be served separately from Gotelem,
so you don't need to rebuild everything. This case is supported:
```
$ go run ./cmd/gotelem server --db gotelem.db # in one terminal
$ npm run serve # in a separate terminal
```
When using the dev server, webpack will set the Gotelem URL to `localhost:8080`. If you're running
Gotelem using the default settings, this should work out of the box. Making changes to the OpenMCT
plugins will trigger a refresh automatically.

View file

@ -8,36 +8,36 @@ openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.Clock({ enableClockIndicator: true }));
openmct.install(openmct.plugins.Timer());
openmct.install(openmct.plugins.Timelist());
openmct.time.clock('local', {start: -5 * 60 * 1000, end: 0});
openmct.time.clock('local', { start: -5 * 60 * 1000, end: 0 });
openmct.time.timeSystem('utc');
openmct.install(openmct.plugins.Espresso());
openmct.install(
openmct.plugins.Conductor({
menuOptions: [
openmct.install(
openmct.plugins.Conductor({
menuOptions: [
{
name: 'Fixed',
timeSystem: 'utc',
bounds: {
start: Date.now() - 30000000,
end: Date.now()
},
name: 'Fixed',
timeSystem: 'utc',
bounds: {
start: Date.now() - 30000000,
end: Date.now()
},
},
{
name: 'Realtime',
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: -30000000,
end: 30000
},
name: 'Realtime',
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: -30000000,
end: 30000
},
}
]
})
);
]
})
);
@ -61,73 +61,73 @@ function getSchema() {
const objectProvider = {
get: function (id) {
return getSchema().then((schema) => {
if (id.key === "car") {
const comp = schema.packets.map((x) => {
return {
key: x.name,
namespace: "umnsvp"
}
})
return {
identifier: id,
name: "the solar car",
type: 'folder',
location: 'ROOT',
composition: comp
}
}
var pkt = schema.packets.find((x) => x.name === id.key)
if (pkt) {
// if the key matches one of the packet names,
// we know it's a field.
const comp = pkt.data.map((field) => {
return {
// we have to do this since
// we can't get the packet name otherwise.
key: `${pkt.name}.${field.name}`,
namespace: "umnsvp"
}
})
return {
identifier: id,
name: pkt.name,
type: 'folder',
composition: comp
}
}
// at this point it's definitely a field aka umnsvp-datum
var [pktName, fieldName] = id.key.split('.')
return {
identifier: id,
name: fieldName,
type: 'umnsvp-datum',
telemetry: {
values: [
{
key: "value",
source: "val",
name: "Value",
"format": "float",
hints: {
range: 1
}
},
{
key: "utc",
source: "ts",
name: "Timestamp",
format: "utc",
hints: {
domain: 1
}
return getSchema().then((schema) => {
if (id.key === "car") {
const comp = schema.packets.map((x) => {
return {
key: x.name,
namespace: "umnsvp"
}
]
})
return {
identifier: id,
name: "the solar car",
type: 'folder',
location: 'ROOT',
composition: comp
}
}
}
var pkt = schema.packets.find((x) => x.name === id.key)
if (pkt) {
// if the key matches one of the packet names,
// we know it's a field.
const comp = pkt.data.map((field) => {
return {
// we have to do this since
// we can't get the packet name otherwise.
key: `${pkt.name}.${field.name}`,
namespace: "umnsvp"
}
})
return {
identifier: id,
name: pkt.name,
type: 'folder',
composition: comp
}
}
// at this point it's definitely a field aka umnsvp-datum
var [pktName, fieldName] = id.key.split('.')
return {
identifier: id,
name: fieldName,
type: 'umnsvp-datum',
telemetry: {
values: [
{
key: "value",
source: "val",
name: "Value",
"format": "float",
hints: {
range: 1
}
},
{
key: "utc",
source: "ts",
name: "Timestamp",
format: "utc",
hints: {
domain: 1
}
})
}
]
}
}
})
}
}
@ -141,7 +141,8 @@ const TelemHistoryProvider = {
var params = new URLSearchParams({
start: new Date(opt.start).toISOString(),
end: new Date(opt.end).toISOString(),
})
})
console.log((opt.end - opt.start)/opt.size)
return fetch(url + params).then((resp) => {
return resp.json()
})