2020-06-04 02:40:13 +00:00
|
|
|
package countersql
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Configuration holds the DSN connection string and a resource Semaphore to limit the number of active connections
|
|
|
|
type Configuration struct {
|
|
|
|
DSN string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Connection represents a single connection to the database, however there may be many instances / connections
|
|
|
|
type Connection struct {
|
|
|
|
DB *sql.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
// HasIPVisited returns true only if the IP address is present in the database
|
|
|
|
func (conn Connection) HasIPVisited(ipAddress string) (bool, error) {
|
|
|
|
rows, err := conn.DB.Query(`SELECT id FROM visit WHERE ip_address = ? LIMIT 1;`, ipAddress)
|
|
|
|
if err != nil {
|
|
|
|
return false, fmt.Errorf("SELECT query failed: %v", err)
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
if !rows.Next() {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetUniqueVisits counts the number of entires in the visits table, representing one unique source IP address per row
|
|
|
|
func (conn Connection) GetUniqueVisits() (int, error) {
|
|
|
|
rows, err := conn.DB.Query(`SELECT COUNT(*) FROM visit`)
|
|
|
|
if err != nil {
|
|
|
|
return 0, fmt.Errorf("SELECT query failed: %v", err)
|
|
|
|
}
|
|
|
|
defer rows.Close()
|
|
|
|
|
|
|
|
if !rows.Next() {
|
|
|
|
return 0, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var uniqueVists int
|
|
|
|
if err := rows.Scan(&uniqueVists); err != nil {
|
|
|
|
return 0, fmt.Errorf("failed to scan database row: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return uniqueVists, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// IncrementVisitor accepts an IP address and updates the row matching that IP address
|
|
|
|
// It does not check if the row matching the IP address supplied exists or not
|
|
|
|
func (conn Connection) IncrementVisitor(ipAddress string) error {
|
|
|
|
_, err := conn.DB.Exec(`UPDATE visit SET visits = visits + 1, last_visited = NOW() WHERE ip_address = ?`, ipAddress)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("UPDATE query failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// AddVisitor accepts an IP address and inserts a new row into the database as this represents a new unique visitor
|
|
|
|
func (conn Connection) AddVisitor(ipAddress string) error {
|
|
|
|
_, err := conn.DB.Exec(`INSERT INTO visit (ip_address, visits, last_visited) VALUES (?, '0', NOW())`, ipAddress)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("INSERT query failed: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Connect will open a TCP connection to the database with the given DSN configuration
|
|
|
|
func (conf Configuration) Connect() (*Connection, error) {
|
|
|
|
conn := &Connection{}
|
|
|
|
var err error
|
2020-06-21 02:24:51 +00:00
|
|
|
|
2020-06-04 02:40:13 +00:00
|
|
|
conn.DB, err = sql.Open("mysql", conf.DSN)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open db: %v", err)
|
|
|
|
}
|
2020-06-21 02:24:51 +00:00
|
|
|
|
2020-06-04 02:40:13 +00:00
|
|
|
return conn, nil
|
|
|
|
}
|