1
0
mirror of https://github.com/mainflux/mainflux.git synced 2025-04-28 13:48:49 +08:00
Nick Neisen 66487eda42 MF-788 - Remove date and minimize copyright comments (#876)
* Update copyright comment for go files

Signed-off-by: nwneisen <nwneisen@gmail.com>

* Update copyright in assortment of file types

Signed-off-by: nwneisen <nwneisen@gmail.com>

* Remove missed copyright date

Signed-off-by: nwneisen <nwneisen@gmail.com>
2019-10-07 16:14:47 +02:00

148 lines
3.7 KiB
Go

// Copyright (c) Mainflux
// SPDX-License-Identifier: Apache-2.0
package postgres
import (
"errors"
"fmt"
"github.com/jmoiron/sqlx" // required for DB access
"github.com/mainflux/mainflux"
"github.com/mainflux/mainflux/readers"
)
const errInvalid = "invalid_text_representation"
var errInvalidMessage = errors.New("invalid message representation")
var _ readers.MessageRepository = (*postgresRepository)(nil)
type postgresRepository struct {
db *sqlx.DB
}
// New returns new PostgreSQL writer.
func New(db *sqlx.DB) readers.MessageRepository {
return &postgresRepository{
db: db,
}
}
func (tr postgresRepository) ReadAll(chanID string, offset, limit uint64, query map[string]string) (readers.MessagesPage, error) {
q := fmt.Sprintf(`SELECT * FROM messages
WHERE %s ORDER BY time DESC
LIMIT :limit OFFSET :offset;`, fmtCondition(chanID, query))
params := map[string]interface{}{
"channel": chanID,
"limit": limit,
"offset": offset,
"subtopic": query["subtopic"],
"publisher": query["publisher"],
"name": query["name"],
"protocol": query["protocol"],
}
rows, err := tr.db.NamedQuery(q, params)
if err != nil {
return readers.MessagesPage{}, err
}
defer rows.Close()
page := readers.MessagesPage{
Offset: offset,
Limit: limit,
Messages: []mainflux.Message{},
}
for rows.Next() {
dbm := dbMessage{Channel: chanID}
if err := rows.StructScan(&dbm); err != nil {
return readers.MessagesPage{}, err
}
msg, err := toMessage(dbm)
if err != nil {
return readers.MessagesPage{}, err
}
page.Messages = append(page.Messages, msg)
}
q = `SELECT COUNT(*) FROM messages WHERE channel = $1;`
qParams := []interface{}{chanID}
if query["subtopic"] != "" {
q = `SELECT COUNT(*) FROM messages WHERE channel = $1 AND subtopic = $2;`
qParams = append(qParams, query["subtopic"])
}
if err := tr.db.QueryRow(q, qParams...).Scan(&page.Total); err != nil {
return readers.MessagesPage{}, err
}
return page, nil
}
func fmtCondition(chanID string, query map[string]string) string {
condition := `channel = :channel`
for name := range query {
switch name {
case
"subtopic",
"publisher",
"name",
"protocol":
condition = fmt.Sprintf(`%s AND %s = :%s`, condition, name, name)
}
}
return condition
}
type dbMessage struct {
ID string `db:"id"`
Channel string `db:"channel"`
Subtopic string `db:"subtopic"`
Publisher string `db:"publisher"`
Protocol string `db:"protocol"`
Name string `db:"name"`
Unit string `db:"unit"`
FloatValue *float64 `db:"value"`
StringValue *string `db:"string_value"`
BoolValue *bool `db:"bool_value"`
DataValue *string `db:"data_value"`
ValueSum *float64 `db:"value_sum"`
Time float64 `db:"time"`
UpdateTime float64 `db:"update_time"`
Link string `db:"link"`
}
func toMessage(dbm dbMessage) (mainflux.Message, error) {
msg := mainflux.Message{
Channel: dbm.Channel,
Subtopic: dbm.Subtopic,
Publisher: dbm.Publisher,
Protocol: dbm.Protocol,
Name: dbm.Name,
Unit: dbm.Unit,
Time: dbm.Time,
UpdateTime: dbm.UpdateTime,
Link: dbm.Link,
}
switch {
case dbm.FloatValue != nil:
msg.Value = &mainflux.Message_FloatValue{FloatValue: *dbm.FloatValue}
case dbm.StringValue != nil:
msg.Value = &mainflux.Message_StringValue{StringValue: *dbm.StringValue}
case dbm.BoolValue != nil:
msg.Value = &mainflux.Message_BoolValue{BoolValue: *dbm.BoolValue}
case dbm.DataValue != nil:
msg.Value = &mainflux.Message_DataValue{DataValue: *dbm.DataValue}
case dbm.ValueSum != nil:
msg.ValueSum = &mainflux.SumValue{Value: *dbm.ValueSum}
}
return msg, nil
}