model

package module
v0.0.0-...-eeb7143 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 20, 2016 License: MIT Imports: 7 Imported by: 1

README

model

GoDoc Build Status Coverage Status

Описание формата данных и хранилища

Documentation

Overview

+build generate

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBadObjectId = errors.New("bad object id")
	ErrNotFound    = mgo.ErrNotFound
)
View Source
var (
	CollectionUsers   = "users"
	CollectionDevices = "devices"
	CollectionEvents  = "events"
	CollectionPlaces  = "places"
)

Названия коллекций в хранилище.

View Source
var ErrBadPlaceData = errors.New("circle or polygon is require in place")

ErrBadPlaceData возвращается, если ни полигон, ни окружность не заданы в описании места.

Functions

This section is empty.

Types

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB описывает хранилище данных и работу с ним.

func InitDB

func InitDB(session *mgo.Session, dbName string) *DB

InitDB инициализирует описание соединения с хранилищем и возвращает его.

func (*DB) Close

func (db *DB) Close()

Close закрывает сессию соединения с MongoDB.

type Device

type Device struct {
	// глобальный уникальный идентификатор устройства
	ID string `bson:"_id" json:"id"`
	// уникальный идентификатор группы
	GroupID string `bson:"group,omitempty" json:"group,omitempty"`
	// отображаемое имя
	Name string `bson:"name,omitempty" json:"name,omitempty"`
	// идентификатор типа устройства
	Type string `bson:"type,omitempty" json:"type,omitempty"`
	// хеш пароля для авторизации
	Password Password `bson:"password,omitempty" json:"-"`
}

Device описывает информацию об устройстве.

Каждое устройство имеет свой глобальный уникальный идентификатор, который не может повторяться. Плюс, устройство в каждый момент времени может быть привязано только к одной группе пользователей. Это позволяет устройству менять группу, блокируя доступ к старым данным, которые были собраны для другой группы.

Устройству может быть назначен его тип. Это поле используется внутри сервиса для идентификации поддерживаемых устройством возможностей, формата данных и команд.

func (*Device) String

func (d *Device) String() string

String возвращает строку с отображаемым именем устройства. Если для данного устройства определено имя, то возвращается именно оно. В противном случае возвращается уникальный идентификатор устройства.

type Devices

type Devices DB // для обращения к данным об устройствах

func (*Devices) Create

func (db *Devices) Create(groupId string, device *Device) (err error)

Create создает описание нового устройства, одновременно привязывая его к указанной группе.

func (*Devices) Delete

func (db *Devices) Delete(groupId, id string) (err error)

Delete удаляет описание устройства.

func (*Devices) Get

func (db *Devices) Get(groupId, id string) (device *Device, err error)

Get возвращает информацию о устройстве с указанным идентификатором, которое привязано к указанной группе.

func (*Devices) List

func (db *Devices) List(groupID string) (devices []*Device, err error)

List возвращает список всех устройств, которые зарегистрированы для данной группы пользователей.

func (*Devices) Login

func (db *Devices) Login(id string) (device *Device, err error)

Login возвращает авторизационную информацию об устройстве

func (*Devices) Update

func (db *Devices) Update(groupId string, device *Device) (err error)

Update обновляет описание устройства и привязывает его к указанной группе.

type Event

type Event struct {
	// уникальный идентификатор записи
	ID bson.ObjectId `bson:"_id" json:"id"`
	// уникальный идентификатор устройства
	DeviceID string `bson:"device" json:"device"`
	// уникальный идентификатор группы
	GroupID string `bson:"group,omitempty" json:"group,omitempty"`

	// временная метка
	Time time.Time `bson:"time" json:"time"`
	// тип события: Arrive, Leave, Travel, Check-in, Happen
	Type string `bson:"type,omitempty" json:"type,omitempty"`
	// координаты точки
	Location *geo.Point `bson:"location,omitempty" json:"location,omitempty"`
	// погрешность координат в метрах
	Accuracy float64 `bson:"accuracy,omitempty" json:"accuracy,omitempty"`
	// идентификатор места
	PlaceID string `bson:"place,omitempty" json:"place,omitempty"`
	// уровень заряда устройства на тот момент
	Power uint8 `bson:"power,omitempty" json:"power,omitempty"`

	// иконка в виде эмодзи
	Emoji rune `bson:"emoji,omitempty" json:"emoji,omitempty"`
	// текстовый комментарий к событию
	Comment string `bson:"comment,omitempty" json:"comment,omitempty"`
	// дополнительная именованная информация
	Data map[string]interface{} `bson:"data,omitempty,inline" json:"data,omitempty"`
}

Event обычно описывает место, время и событие, которое в нем случилось.

Каждое событие получает свой уникальный идентификатор, назначаемый непосредственно системой. Кроме того, событие привязано к конкретному идентификатору устройства и группе пользователей. Группа пользователей здесь представлена отдельным свойством, не смотря на то, что ее можно достаточно легко получить и из связи с устройством. Это сделано намеренно, чтобы в тех случаях, когда устройство меняет владельца (группу), старые данные о событиях не становились автоматически доступны новым пользователям.

Каждое событие в обязательном порядке характеризуется временем, когда оно произошло. Если при создании описания события время было опущено, то будет автоматически добавлено текущее время сервера.

Тип события задает один из предопределенных типов события. Если не указано, то считается, что тип события не определен.

Каждое событие обычно характеризуется координатами географической точки, в которой оно случилось и дополнительным параметром, указывающим возможный радиус погрешности вычисления данной точки.

Дополнительно, каждое событие может иметь свое описание в текстовом виде и иконку, характеризующую его в некотором визуальном виде. Но с последним обычно тяжело: кто и сколько таких иконок нарисует? Поэтому было принято решения вместо иконки использовать пиктограмму из стандартного набора эмодзи.

И, наконец, последний элемент: именованные поля с произвольным содержимым, позволяющим описать любую дополнительную информацию. В частности, думаю, значения датчиков и сенсоров хорошо и удобно сохранять именно в таком виде. Плюс, всегда можно добавить что-то дополнительно практически в любом удобном формате. Главное, чтобы приложение знало, что потом с этим делать.

type Events

type Events DB // для обращения к данным о событиях

func (*Events) Create

func (db *Events) Create(groupId, deviceId string, events ...*Event) (err error)

Create добавляет в хранилище описание новых событий с привязкой к устройству.

func (*Events) Delete

func (db *Events) Delete(groupId, deviceId, id string) (err error)

Delete удаляет описание события из хранилища.

func (*Events) Devices

func (db *Events) Devices(groupID string) (deviceIds []string, err error)

Devices возвращает список идентификаторов устройств, данные о которых есть в коллекции событий для данной группы пользователей.

func (*Events) Get

func (db *Events) Get(groupId, deviceId, id string) (event *Event, err error)

Get возвращает описание события с указанным идентификатором для конкретного устройства из хранилища.

func (*Events) List

func (db *Events) List(groupID, deviceId string) (events []*Event, err error)

List возвращает список всех событий, зарегистрированных для указанного устройства.

func (*Events) Update

func (db *Events) Update(groupId, deviceId string, event *Event) (err error)

Update обновляет описание события в хранилище.

type Password

type Password []byte

Password описывает тип для пароля, хранящегося в виде хеш с использованием алгоритма bcrypt.

func NewPassword

func NewPassword(password string) Password

NewPassword возвращает пароль в виде хеш.

func (Password) Compare

func (p Password) Compare(password string) bool

Compare сравнивает сохраненный в виде хеш пароль с указанным в параметре и возвращает true, если указанный пароль с очень большой степенью вероятности и является оригинальным паролем.

type Place

type Place struct {
	// уникальный идентификатор описания места
	ID string `bson:"_id,omitempty" json:"id"`
	// уникальный идентификатор группы
	GroupID string `bson:"group,omitempty" json:"group,omitempty"`
	// отображаемое имя
	Name string `bson:"name,omitempty" json:"name,omitempty"`
	// географическое описание места как круга
	Circle *geo.Circle `bson:"circle,omitempty" json:"circle,omitempty"`
	// географическое описание места в виде полигона
	Polygon *geo.Polygon `bson:"polygon,omitempty" json:"polygon,omitempty"`
	// описание в формате GeoJSON для поиска
	Geo interface{} `bson:"geo" json:"-"`
}

Place описывает географическое место, задаваемое для группы пользователей. Такое место может быть описано либо в виде круга, задаваемого координатами центральной точки и радиусом в метрах, либо полигоном. Круг имеет более высокий приоритет, поэтому если задано и то, и другое, то используется именно описание круга.

К сожалению, в формате GeoJSON, который использует для описание географических координат в MongoDB, нет возможности описать круг. Поэтому для работы с ним его приходится трансформировать его в некий многоугольник. Получившийся результат сохраняется в поле Geo и индексируется сервером баз данных. В том же случае, если задан полигон, то его описания просто копируется в это поле без каких-либо изменений.

func (*Place) String

func (p *Place) String() string

String возвращает строку с отображаемым именем описания места. Если для данного места задано имя, то возвращается именно оно. В противном случае возвращается его уникальный идентификатор.

type Places

type Places DB // для обращения к данным об описании мест

func (*Places) Create

func (db *Places) Create(groupId string, place *Place) (err error)

Create добавляет в хранилище описание нового места для группы. Указание группы позволяет дополнительно защитить от ошибок переназначения места для другой группы.

func (*Places) Delete

func (db *Places) Delete(groupId, id string) (err error)

Delete удаляет описание места с указанным идентификатором из хранилища. Указание группы позволяет дополнительно защитить от ошибок доступа к чужой информации.

func (*Places) Get

func (db *Places) Get(groupId, id string) (place *Place, err error)

Get возвращает описание места по его идентификатору. Кроме идентификатора места, который является уникальным, необходимо так же указывать идентификатор группы — это позволяет дополнительно ограничить даже случайный доступ пользователей к чужой информации.

func (*Places) List

func (db *Places) List(groupID string) (places []*Place, err error)

List возвращает список всех мест, определенных в хранилище для данной группы пользователей.

func (*Places) Update

func (db *Places) Update(groupId string, place *Place) (err error)

Update обновляет информацию о месте в хранилище. Указание группы позволяет дополнительно защитить от ошибок переназначения места для другой группы.

type User

type User struct {
	// логин пользователя
	Login string `bson:"_id" json:"id"`
	// уникальный идентификатор группы
	GroupID string `bson:"group,omitempty" json:"group,omitempty"`
	// отображаемое имя
	Name string `bson:"name,omitempty" json:"name,omitempty"`
	// хеш пароля пользователя
	Password Password `bson:"password" json:"-"`
}

User описывает информацию о пользователе.

Логин пользователя является глобальным уникальным идентификатором пользователя и не может повторяться для разных пользователей. Поэтому, скорее всего, удобнее использовать в качестве такого идентификатора e-mail, что избавит от головной боли с уникальностью. Или любой другой идентификатор, который будет действительно глобально уникальным.

Пользователи объединяются в группы, которые разделяют общие ресурсы: имеют доступ к трекам устройств той же группы, общие описания мест и так далее. Пользователь может состоять только в одной группе, но может ее сменить. Идентификатор группы генерируется непосредственно сервером.

Пароль пользователя не хранится в системе, а вместо этого хранится хеш от него: этого вполне достаточно, чтобы иметь возможность проверить правильность введенного пароля, но не позволит его восстановить в исходном виде. В качестве алгоритма хеширования выбран bcrypt (Provos and Mazières's bcrypt adaptive hashing algorithm).

type Users

type Users DB // для обращения к данным о зарегистрированных пользователях

func (*Users) Create

func (db *Users) Create(user *User) (err error)

Create создает нового пользователя по его описанию. Поле Login должно быть уникальным, в противном случае возвращается ошибка.

func (*Users) Delete

func (db *Users) Delete(login string) (err error)

Delete удаляет пользователя с указанным логином из хранилища.

func (*Users) List

func (db *Users) List(groupID string) (users []User, err error)

List возвращает список всех пользователей, зарегистрированных в указанной группе.

func (*Users) Login

func (db *Users) Login(userID string) (user *User, err error)

Login возвращает информацию о пользователе по его логину.

func (*Users) Update

func (db *Users) Update(user User) (err error)

Update обновляет информацию о пользователе в хранилище.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL