mirror of
https://github.com/lus/pasty.git
synced 2023-08-10 21:13:09 +03:00
Implement SQL storage driver
This commit is contained in:
parent
f97531e765
commit
bf96209d99
@ -41,3 +41,12 @@ Every single one of them has its own configuration variables:
|
||||
| `STORAGE_MONGODB_CONNECTION_STRING` | `mongodb://pasty:pasty@example.host/pasty` | `string` | Defines the connection string to use for the MongoDB connection |
|
||||
| `STORAGE_MONGODB_DATABASE` | `pasty` | `string` | Defines the name of the database to use |
|
||||
| `STORAGE_MONGODB_COLLECTION` | `pastes` | `string` | Defines the name of the collection to use |
|
||||
|
||||
---
|
||||
|
||||
### SQL (`sql`)
|
||||
| Environment Variable | Default Value | Type | Description |
|
||||
|----------------------|---------------|----------|-------------------------------------------------------------------------------------|
|
||||
| `STORAGE_SQL_DRIVER` | `sqlite3` | `string` | Defines the driver to use for the SQL connection (`sqlite3`, `postgres` or `mysql`) |
|
||||
| `STORAGE_SQL_DSN` | `./db` | `string` | Defines the DSN to use for the SQL connection |
|
||||
| `STORAGE_SQL_TABLE` | `pasty` | `string` | Defines the table name to use for the SQL connection |
|
3
go.mod
3
go.mod
@ -5,8 +5,11 @@ go 1.15
|
||||
require (
|
||||
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b
|
||||
github.com/fasthttp/router v1.2.4
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/klauspost/compress v1.10.11 // indirect
|
||||
github.com/lib/pq v1.8.0
|
||||
github.com/mattn/go-sqlite3 v1.14.2
|
||||
github.com/minio/minio-go/v7 v7.0.5
|
||||
github.com/ulule/limiter/v3 v3.5.0
|
||||
github.com/valyala/fasthttp v1.16.0
|
||||
|
9
go.sum
9
go.sum
@ -1,8 +1,10 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
|
||||
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b h1:rcCpjI1OMGtBY8nnBvExeM1pXNoaM35zqmXBGpgJR2o=
|
||||
github.com/alexedwards/argon2id v0.0.0-20200802152012-2464efd3196b/go.mod h1:GFtu6vaWaRJV5EvSFaVqgq/3Iq95xyYElBV/aupGzUo=
|
||||
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
github.com/aws/aws-sdk-go v1.29.15 h1:0ms/213murpsujhsnxnNKNeVouW60aJqSd992Ks3mxs=
|
||||
github.com/aws/aws-sdk-go v1.29.15/go.mod h1:1KvfttTE3SPKMpo8g2c6jL3ZKfXtFvKscTgahTma5Xg=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -18,6 +20,7 @@ github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTM
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-redis/redis/v7 v7.2.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@ -89,9 +92,13 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/lib/pq v1.8.0 h1:9xohqzkUwzR4Ga4ivdTcawVS89YSDVxXMa3xJX3cGzg=
|
||||
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
|
||||
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.14.2 h1:A2EQLwjYf/hfYaM20FVjs1UewCTTFR7RmjEHkLjldIA=
|
||||
github.com/mattn/go-sqlite3 v1.14.2/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
|
||||
github.com/minio/md5-simd v1.1.0 h1:QPfiOqlZH+Cj9teu0t9b1nTBfPbyTl16Of5MeuShdK4=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/minio-go/v7 v7.0.5 h1:I2NIJ2ojwJqD/YByemC1M59e1b4FW9kS7NlOar7HPV4=
|
||||
@ -168,12 +175,14 @@ golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
|
@ -47,6 +47,8 @@ func GetDriver(storageType string) (Driver, error) {
|
||||
return new(S3Driver), nil
|
||||
case "mongodb":
|
||||
return new(MongoDBDriver), nil
|
||||
case "sql":
|
||||
return new(SQLDriver), nil
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid storage type '%s'", storageType)
|
||||
}
|
||||
|
@ -63,6 +63,9 @@ func (driver *S3Driver) Get(id string) (*pastes.Paste, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if object == nil {
|
||||
return nil, nil
|
||||
}
|
||||
data, err := ioutil.ReadAll(object)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
108
internal/storage/sql_driver.go
Normal file
108
internal/storage/sql_driver.go
Normal file
@ -0,0 +1,108 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"github.com/Lukaesebrot/pasty/internal/env"
|
||||
"github.com/Lukaesebrot/pasty/internal/pastes"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "github.com/lib/pq"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
// SQLDriver represents the SQL storage driver
|
||||
type SQLDriver struct {
|
||||
database *sql.DB
|
||||
table string
|
||||
}
|
||||
|
||||
// Initialize initializes the SQL storage driver
|
||||
func (driver *SQLDriver) Initialize() error {
|
||||
// Parse the DSN and create a database object
|
||||
db, err := sql.Open(env.Get("STORAGE_SQL_DRIVER", "sqlite3"), env.Get("STORAGE_SQL_DSN", "./db"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Ping the database
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Migrate the database
|
||||
table := env.Get("STORAGE_SQL_TABLE", "pasty")
|
||||
_, err = db.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS ? (
|
||||
id varchar NOT NULL PRIMARY KEY,
|
||||
content varchar NOT NULL,
|
||||
suggestedSyntaxType varchar NOT NULL,
|
||||
deletionToken varchar NOT NULL
|
||||
);
|
||||
`, table)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the database object and table name of the SQL driver
|
||||
driver.database = db
|
||||
driver.table = table
|
||||
return nil
|
||||
}
|
||||
|
||||
// Terminate terminates the SQL storage driver
|
||||
func (driver *SQLDriver) Terminate() error {
|
||||
return driver.database.Close()
|
||||
}
|
||||
|
||||
// ListIDs returns a list of all existing paste IDs
|
||||
func (driver *SQLDriver) ListIDs() ([]string, error) {
|
||||
// Execute a SELECT query to retrieve all the paste IDs
|
||||
rows, err := driver.database.Query("SELECT id FROM ?", driver.table)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
// Scan the rows into a slice of IDs and return it
|
||||
var ids []string
|
||||
err = rows.Scan(&ids)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// Get loads a paste
|
||||
func (driver *SQLDriver) Get(id string) (*pastes.Paste, error) {
|
||||
// Execute a SELECT query to retrieve the paste
|
||||
row := driver.database.QueryRow("SELECT * FROM ? WHERE id = ?", driver.table, id)
|
||||
err := row.Err()
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Scan the row into a paste and return it
|
||||
paste := new(pastes.Paste)
|
||||
err = row.Scan(&paste)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return paste, nil
|
||||
}
|
||||
|
||||
// Save saves a paste
|
||||
func (driver *SQLDriver) Save(paste *pastes.Paste) error {
|
||||
// Execute an INSERT statement to create the paste
|
||||
_, err := driver.database.Exec("INSERT INTO ? (?, ?, ?, ?)", driver.table, paste.ID, paste.Content, paste.SuggestedSyntaxType, paste.DeletionToken)
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete deletes a paste
|
||||
func (driver *SQLDriver) Delete(id string) error {
|
||||
// Execute a DELETE statement to delete the paste
|
||||
_, err := driver.database.Exec("DELETE FROM ? WHERE id = ?", driver.table, id)
|
||||
return err
|
||||
}
|
Loading…
Reference in New Issue
Block a user