diff options
| author | 2021-03-02 18:26:30 +0100 | |
|---|---|---|
| committer | 2021-03-02 18:26:30 +0100 | |
| commit | d8e8d44d4778bfd3f9e63488edc696e004edfb15 (patch) | |
| tree | f5783e994de7abf968866e904741e112c124864e /internal/db | |
| parent | Messing around a bit (diff) | |
| download | gotosocial-d8e8d44d4778bfd3f9e63488edc696e004edfb15.tar.xz | |
start implementing db interface
Diffstat (limited to 'internal/db')
| -rw-r--r-- | internal/db/const.go | 36 | ||||
| -rw-r--r-- | internal/db/postgres.go | 181 | ||||
| -rw-r--r-- | internal/db/service.go | 67 | 
3 files changed, 284 insertions, 0 deletions
| diff --git a/internal/db/const.go b/internal/db/const.go new file mode 100644 index 000000000..ab0a5c03f --- /dev/null +++ b/internal/db/const.go @@ -0,0 +1,36 @@ +/* +   GoToSocial +   Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU Affero General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Affero General Public License for more details. + +   You should have received a copy of the GNU Affero General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +package db + +import "regexp" + +const ( +	// general db defaults + +	// default database to use in whatever db implementation we have +	defaultDatabase string = "gotosocial" + +	// implementation-specific defaults + +	// widely-recognised default postgres port +	postgresDefaultPort int = 5432 +) + +var ipv4Regex = regexp.MustCompile(`^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`) +var hostnameRegex = regexp.MustCompile(`^(?:[a-z0-9]+(?:-[a-z0-9]+)*\.)+[a-z]{2,}$`) diff --git a/internal/db/postgres.go b/internal/db/postgres.go new file mode 100644 index 000000000..67d0bb4e9 --- /dev/null +++ b/internal/db/postgres.go @@ -0,0 +1,181 @@ +/* +   GoToSocial +   Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU Affero General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Affero General Public License for more details. + +   You should have received a copy of the GNU Affero General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +package db + +import ( +	"context" +	"errors" +	"fmt" +	"net/url" + +	"github.com/go-fed/activity/streams/vocab" +	"github.com/go-pg/pg" +) + +type postgresService struct { +	config *Config +	conn   *pg.DB +	ready  bool +} + +// newPostgresService returns a postgresService derived from the provided config, which implements the go-fed DB interface. +// Under the hood, it uses https://github.com/go-pg/pg to create and maintain a database connection. +func newPostgresService(config *Config) (*postgresService, error) { +	opts, err := derivePGOptions(config) +	if err != nil { +		return nil, fmt.Errorf("could not create postgres service: %s", err) +	} +	conn := pg.Connect(opts) +	return &postgresService{ +		config, +		conn, +		false, +	}, nil + +} + +/* +	HANDY STUFF +*/ + +// derivePGOptions takes an application config and returns either a ready-to-use *pg.Options +// with sensible defaults, or an error if it's not satisfied by the provided config. +func derivePGOptions(config *Config) (*pg.Options, error) { +	if config.Type != dbTypePostgres { +		return nil, fmt.Errorf("expected db type of %s but got %s", dbTypePostgres, config.Type) +	} + +	// use sensible default port +	var port int = config.Port +	if port == 0 { +		port = postgresDefaultPort +	} + +	// validate address +	address := config.Address +	if address == "" { +		return nil, errors.New("address not provided") +	} +	if !hostnameRegex.MatchString(address) && !ipv4Regex.MatchString(address) { +		return nil, fmt.Errorf("address %s was neither an ipv4 address nor a valid hostname", address) +	} + +	options := &pg.Options{ +		Addr:     fmt.Sprintf("%s:%d", config.Address, config.Port), +		User:     config.User, +		Password: config.Password, +		Database: config.Database, +		OnConnect: func(c *pg.Conn) error { +			return nil +		}, +	} + +	return options, nil +} + +/* +   GO-FED DB INTERFACE-IMPLEMENTING FUNCTIONS +*/ +func (ps *postgresService) Lock(c context.Context, id *url.URL) error { +	return nil +} + +func (ps *postgresService) Unlock(c context.Context, id *url.URL) error { +	return nil +} + +func (ps *postgresService) InboxContains(c context.Context, inbox *url.URL, id *url.URL) (bool, error) { +	return false, nil +} + +func (ps *postgresService) GetInbox(c context.Context, inboxIRI *url.URL) (inbox vocab.ActivityStreamsOrderedCollectionPage, err error) { +	return nil, nil +} + +func (ps *postgresService) SetInbox(c context.Context, inbox vocab.ActivityStreamsOrderedCollectionPage) error { +	return nil +} + +func (ps *postgresService) Owns(c context.Context, id *url.URL) (owns bool, err error) { +	return false, nil +} + +func (ps *postgresService) ActorForOutbox(c context.Context, outboxIRI *url.URL) (actorIRI *url.URL, err error) { +	return nil, nil +} + +func (ps *postgresService) ActorForInbox(c context.Context, inboxIRI *url.URL) (actorIRI *url.URL, err error) { +	return nil, nil +} + +func (ps *postgresService) OutboxForInbox(c context.Context, inboxIRI *url.URL) (outboxIRI *url.URL, err error) { +	return nil, nil +} + +func (ps *postgresService) Exists(c context.Context, id *url.URL) (exists bool, err error) { +	return false, nil +} + +func (ps *postgresService) Get(c context.Context, id *url.URL) (value vocab.Type, err error) { +	return nil, nil +} + +func (ps *postgresService) Create(c context.Context, asType vocab.Type) error { +	return nil +} + +func (ps *postgresService) Update(c context.Context, asType vocab.Type) error { +	return nil +} + +func (ps *postgresService) Delete(c context.Context, id *url.URL) error { +	return nil +} + +func (ps *postgresService) GetOutbox(c context.Context, outboxIRI *url.URL) (inbox vocab.ActivityStreamsOrderedCollectionPage, err error) { +	return nil, nil +} + +func (ps *postgresService) SetOutbox(c context.Context, outbox vocab.ActivityStreamsOrderedCollectionPage) error { +	return nil +} + +func (ps *postgresService) NewID(c context.Context, t vocab.Type) (id *url.URL, err error) { +	return nil, nil +} + +func (ps *postgresService) Followers(c context.Context, actorIRI *url.URL) (followers vocab.ActivityStreamsCollection, err error) { +	return nil, nil +} + +func (ps *postgresService) Following(c context.Context, actorIRI *url.URL) (followers vocab.ActivityStreamsCollection, err error) { +	return nil, nil +} + +func (ps *postgresService) Liked(c context.Context, actorIRI *url.URL) (followers vocab.ActivityStreamsCollection, err error) { +	return nil, nil +} + +/* +	EXTRA FUNCTIONS +*/ + +func (ps *postgresService) Ready() bool { +	return false +} diff --git a/internal/db/service.go b/internal/db/service.go new file mode 100644 index 000000000..6163b3c69 --- /dev/null +++ b/internal/db/service.go @@ -0,0 +1,67 @@ +/* +   GoToSocial +   Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + +   This program is free software: you can redistribute it and/or modify +   it under the terms of the GNU Affero General Public License as published by +   the Free Software Foundation, either version 3 of the License, or +   (at your option) any later version. + +   This program is distributed in the hope that it will be useful, +   but WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +   GNU Affero General Public License for more details. + +   You should have received a copy of the GNU Affero General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +package db + +import ( +	"fmt" +	"strings" + +	"github.com/go-fed/activity/pub" +) + +const dbTypePostgres string = "POSTGRES" + +// Service provides methods for interacting with an underlying database (for now, just postgres). +// The function mapping lines up with the Database interface described in go-fed. +// See here: https://github.com/go-fed/activity/blob/master/pub/database.go +type Service interface { +	/* +		GO-FED DATABASE FUNCTIONS +	*/ +	pub.Database + +	/* +		ANY ADDITIONAL DESIRED FUNCTIONS +	*/ + +	// Ready indicates whether the database is ready to handle queries and whatnot. +	Ready() bool +} + +// Config provides configuration options for the database connection +type Config struct { +	Type            string +	Address         string +	Port            int +	User            string +	Password        string +	Database        string +	ApplicationName string +} + +// NewService returns a new database service that satisfies the Service interface and, by extension, +// the go-fed database interface described here: https://github.com/go-fed/activity/blob/master/pub/database.go +func NewService(config *Config) (Service, error) { +	switch strings.ToUpper(config.Type) { +	case dbTypePostgres: +		return newPostgresService(config) +	default: +		return nil, fmt.Errorf("database type %s not supported", config.Type) +	} +} | 
