func (db *Database) AddGroupHolder(gh *GroupHolder) (int, error) {
	var user interface{}
	var channel interface{}
	if gh.User != "" {
		user = gh.User
	} else {
		user = nil
	}
	if gh.Channel != "" {
		channel = gh.Channel
	} else {
		channel = nil
	}
	row := db.db.QueryRow(`
		SELECT melodious.insert_group_holder($1, $2, $3);
	`, gh.Group, user, channel)
	var id int
	err := row.Scan(&id)
	if err != nil {
		return -1, err
	}
	return id, nil
}
AddGroupHolder - adds a group holder
package main
import (
	"crypto/sha256"
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"time"
	"github.com/apex/log"
	"github.com/lib/pq"
)
type Database struct {
	mel *Melodious
	db  *sql.DB
}
func (db *Database) GetUsersList() ([]*User, error) {
	rows, err := db.db.Query(`
		SELECT id, username, owner FROM melodious.accounts WHERE banned=false;
	`)
	if err != nil {
		return []*User{}, err
	}
	users := []*User{}
	for rows.Next() {
		user := &User{}
		err := rows.Scan(&(user.ID), &(user.Username), &(user.Owner))
		if err != nil {
			return []*User{}, err
		}
		users = append(users, user)
	}
	return users, nil
}
func (db *Database) HasUsers() (bool, error) {
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts LIMIT 1;
	`)
	var id int
	err := row.Scan(&id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, err
}
func (db *Database) RegisterUser(name string, passhash string, ip string) error {
	return db.RegisterUserOwner(name, passhash, false, ip)
}
func (db *Database) RegisterUserOwner(name string, passhash string, owner bool, ip string) error {
	sum := sha256.Sum256([]byte(passhash))
	sumstr := fmt.Sprintf("%x", sum[:32])
	_, err := db.db.Exec(`
		INSERT INTO melodious.accounts (username, passhash, owner) VALUES ($1, $2, $3);
	`, name, sumstr, owner)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) DeleteUser(name string) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.accounts WHERE username=$1;
	`, name)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) DeleteUserID(id int) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.accounts WHERE id=$1;
	`, id)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) GetUserID(name string) (int, error) {
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE username=$1 LIMIT 1;
	`, name)
	var id int
	err := row.Scan(&id)
	if err == sql.ErrNoRows {
		return -1, errors.New("no such user")
	} else if err != nil {
		return -1, err
	}
	return 0, err
}
func (db *Database) UserExists(name string) (bool, error) {
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE username=$1 LIMIT 1;
	`, name)
	var id int  
	err := row.Scan(&id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}
func (db *Database) UserExistsID(id int) (bool, error) {
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE id=$1 LIMIT 1;
	`, id)
	var _id int  
	err := row.Scan(&_id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}
func (db *Database) CheckUserPassword(name string, passhash string) (bool, error) {
	sum := sha256.Sum256([]byte(passhash))
	sumstr := fmt.Sprintf("%x", sum[:32])
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE username=$1 AND passhash=$2 LIMIT 1;
	`, name, sumstr)
	var id int  
	err := row.Scan(&id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}
func (db *Database) CheckUserPasswordID(id int, passhash string) (bool, error) {
	sum := sha256.Sum256([]byte(passhash))
	sumstr := fmt.Sprintf("%x", sum[:32])
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE id=$1 AND passhash=$2 LIMIT 1;
	`, id, sumstr)
	var _id int  
	err := row.Scan(&_id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}
func (db *Database) IsUserOwner(name string) (bool, error) {
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE username=$1 AND owner=TRUE LIMIT 1;
	`, name)
	var id int  
	err := row.Scan(&id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}
func (db *Database) IsUserOwnerID(id int) (bool, error) {
	row := db.db.QueryRow(`
		SELECT id FROM melodious.accounts WHERE id=$1 AND owner=TRUE LIMIT 1;
	`, id)
	var _id int  
	err := row.Scan(&_id)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return true, nil
}
func (db *Database) SetUserOwner(name string, owner bool) error {
	_, err := db.db.Exec(`
		UPDATE melodious.accounts SET owner=$1 WHERE username=$2;
	`, owner, name)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) SetUserOwnerID(id int, owner bool) error {
	_, err := db.db.Exec(`
		UPDATE melodious.accounts SET owner=$1 WHERE id=$2;
	`, owner, id)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) Ban(username string) error {
	_, err := db.db.Exec(`
		UPDATE melodious.accounts SET banned=true WHERE username=$1;
	`, username)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) BanID(id int) error {
	_, err := db.db.Exec(`
		UPDATE melodious.accounts SET banned=true WHERE id=$1;
	`, id)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) IsUserBanned(username string, ip string) (bool, error) {
	row := db.db.QueryRow(`
		SELECT banned FROM melodious.accounts WHERE username=$1 OR ip=$2;
	`, username, ip)
	var banned bool
	err := row.Scan(&banned)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return banned, nil
}
func (db *Database) IsUserBannedID(id int, ip string) (bool, error) {
	row := db.db.QueryRow(`
		SELECT banned FROM melodious.accounts WHERE id=$1 OR ip=$2;
	`, id, ip)
	var banned bool
	err := row.Scan(&banned)
	if err == sql.ErrNoRows {
		return false, nil
	} else if err != nil {
		return false, err
	}
	return banned, nil
}
func (db *Database) GetAccountCount(ip string) (int, error) {
	row := db.db.QueryRow(`
		SELECT COUNT(*) FROM melodious.accounts WHERE ip=$1;
	`, ip)
	var count int
	err := row.Scan(&count)
	if err != nil {
		return -1, err
	}
	return count, nil
}
func (db *Database) NewChannel(name string, topic string) error {
	_, err := db.db.Exec(`
		INSERT INTO melodious.channels (name, topic) VALUES ($1, $2);
	`, name, topic)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) DeleteChannel(name string) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.channels WHERE name=$1;
	`, name)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) DeleteChannelID(id int) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.channels WHERE id=$1;
	`, id)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) ListChannels() ([]*Channel, error) {
	rows, err := db.db.Query(`
		SELECT id, name, topic FROM melodious.channels;
	`)
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	m := []*Channel{}
	for rows.Next() {
		chnl := &Channel{}
		if err := rows.Scan(&(chnl.ID), &(chnl.Name), &(chnl.Topic)); err != nil {
			return nil, err
		}
		m = append(m, chnl)
	}
	return m, nil
}
func (db *Database) ChannelExists(name string) (bool, error) {
	row := db.db.QueryRow(`
		SELECT EXISTS(SELECT * FROM melodious.channels WHERE name=$1);
	`, name)
	var exists bool
	err := row.Scan(&exists)
	if err != nil {
		return false, err
	}
	return exists, nil
}
func (db *Database) SetChannelTopic(name string, topic string) error {
	_, err := db.db.Exec(`
		UPDATE melodious.channels SET topic=$2 WHERE name=$1;
	`, name, topic)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) DeleteOldMessages(period string) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.messages WHERE dt < (NOW() - $1::INTERVAL);
	`, period)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) PostMessage(chanName string, message string, pings []string, author string) (*ChatMessage, error) {
	row := db.db.QueryRow(`
		INSERT INTO melodious.messages
		(chan_id, message, dt, pings, author_id)
		VALUES (
			(SELECT id FROM melodious.channels WHERE name=$1 LIMIT 1),
			$2,
			NOW(),
			$3,
			(SELECT id FROM melodious.accounts WHERE username=$4 LIMIT 1)
		)
		RETURNING message, pings, id, dt, $4, author_id;
	`, chanName, message, pq.Array(pings), author)
	msg := &ChatMessage{}
	var cpings pq.StringArray
	err := row.Scan(&(msg.Message), &cpings, &(msg.ID), &(msg.Timestamp), &(msg.Author), &(msg.AuthorID))
	if err != nil {
		return nil, err
	}
	msg.Pings = []string(cpings)
	return msg, nil
}
func (db *Database) PostMessageChanID(chanID int, message string, pings []string, author string) error {
	_, err := db.db.Exec(`
		INSERT INTO melodious.messages
		(chan_id, message, dt, pings, author_id)
		VALUES (
			(SELECT id FROM melodious.channels WHERE id=$1 LIMIT 1),
			$2,
			NOW(),
			$3,
			(SELECT id FROM melodious.accounts WHERE username=$4 LIMIT 1)
		);
	`, chanID, message, pq.Array(pings), author)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) DeleteMessage(id int) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.messages WHERE id=$1;
	`, id)
	if err != nil {
		return err
	}
	return nil
}
func (db *Database) GetMessages(chanid int, msgid int, amount int) ([]*ChatMessage, error) {
	rows, err := db.db.Query(`
		SELECT
			m.id,
			m.message,
			m.dt,
			m.pings,
			a.username author,
			m.author_id
		FROM melodious.messages m
		INNER JOIN melodious.accounts a ON m.author_id = a.id
		WHERE m.chan_id=$1 AND m.id<$2
		ORDER BY m.id DESC
		LIMIT $3;
	`, chanid, msgid, amount)
	if err != nil {
		return []*ChatMessage{}, err
	}
	msgs := []*ChatMessage{}
	for rows.Next() {
		msg := &ChatMessage{}
		var pings pq.StringArray
		err := rows.Scan(&(msg.ID), &(msg.Message), &(msg.Timestamp), &pings, &(msg.Author), &(msg.AuthorID))
		if err != nil {
			return []*ChatMessage{}, err
		}
		msg.Pings = []string(pings)
		msgs = append(msgs, msg)
	}
	return msgs, nil
}
func (db *Database) GetMessageDetails(id int) (string, *ChatMessage, error) {
	row := db.db.QueryRow(`
		SELECT
			m.message,
			m.dt,
			m.pings,
			a.username author,
			m.author_id,
			c.name channel
		FROM melodious.messages m
		INNER JOIN melodious.accounts a ON m.author_id = a.id
		INNER JOIN melodious.channels c ON m.chan_id = c.id
		WHERE m.id=$1;
	`, id)
	var pings pq.StringArray
	var channel string
	msg := &ChatMessage{}
	err := row.Scan(&(msg.Message), &(msg.Timestamp), &pings, &(msg.Author), &(msg.AuthorID), &channel)
	if err != nil {
		return "", &ChatMessage{}, err
	}
	msg.Pings = []string(pings)
	msg.ID = id
	return channel, msg, nil
}
func (db *Database) AddGroup(name string) (int, error) {
	row := db.db.QueryRow(`
		INSERT INTO melodious.groups (name)	VALUES ($1) RETURNING id;
	`, name)
	var id int
	err := row.Scan(&id)
	if err != nil {
		return -1, err
	}
	return id, nil
}
func (db *Database) DeleteGroup(name string) error {
	_, err := db.db.Exec(`
		DELETE FROM melodious.groups WHERE name=$1;
	`, name)
	return err
}
func (db *Database) GroupExists(name string) (bool, error) {
	row := db.db.QueryRow(`
		SELECT EXISTS(SELECT * FROM melodious.groups WHERE name=$1);
	`, name)
	var exists bool
	err := row.Scan(&exists)
	if err != nil {
		return false, err
	}
	return exists, nil
}
func (db *Database) GroupExistsID(id int) (bool, error) {
	row := db.db.QueryRow(`
		SELECT EXISTS(SELECT * FROM melodious.groups WHERE id=$1);
	`, id)
	var exists bool
	err := row.Scan(&exists)
	if err != nil {
		return false, err
	}
	return exists, nil
}
func (db *Database) SetFlag(flag *Flag) (int, error) {
	data, err := json.Marshal(flag.Flag)
	if err != nil {
		return -1, err
	}
	row := db.db.QueryRow(`
		SELECT melodious.set_flag($1, $2, $3::JSON);
	`, flag.Group, flag.Name, string(data))
	var id int
	err = row.Scan(&id)
	if err != nil {
		return -1, err
	}
	return id, nil
}
func (db *Database) DeleteFlag(flag *Flag) error {
	_, err := db.db.Exec(`
		CALL melodious.delete_flag($1, $2);
	`, flag.Group, flag.Name)
	return err
}