func (d *ServiceDB) LoadAuthRealmsByType(realmType string) (realms []types.AuthRealm, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		realms, err = selectRealmsByTypeTxn(txn, realmType)
		return err
	})
	return
}
LoadAuthRealmsByType loads all auth realms with the given type from the database.
The realms are ordered based on their realm ID.
Returns an empty list if there are no realms with that type.
package database
import (
	"database/sql"
	"encoding/json"
	"fmt"
	"time"
	"github.com/matrix-org/go-neb/api"
	"github.com/matrix-org/go-neb/types"
	"maunium.net/go/mautrix/id"
)
type ServiceDB struct {
	db      *sql.DB
	dialect string
}
var globalServiceDB Storer
func SetServiceDB(db Storer) {
	globalServiceDB = db
}
func GetServiceDB() Storer {
	return globalServiceDB
}
func Open(databaseType, databaseURL string) (serviceDB *ServiceDB, err error) {
	db, err := sql.Open(databaseType, databaseURL)
	if err != nil {
		return
	}
	if _, err = db.Exec(schemaSQL); err != nil {
		return
	}
	if databaseType == "sqlite3" {
		db.SetMaxOpenConns(1)
	}
	serviceDB = &ServiceDB{db: db, dialect: databaseType}
	return
}
func (d *ServiceDB) StoreMatrixClientConfig(config api.ClientConfig) (oldConfig api.ClientConfig, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		oldConfig, err = selectMatrixClientConfigTxn(txn, config.UserID)
		now := time.Now()
		if err == nil {
			return updateMatrixClientConfigTxn(txn, now, config)
		} else if err == sql.ErrNoRows {
			return insertMatrixClientConfigTxn(txn, now, config)
		} else {
			return err
		}
	})
	return
}
func (d *ServiceDB) LoadMatrixClientConfigs() (configs []api.ClientConfig, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		configs, err = selectMatrixClientConfigsTxn(txn)
		return err
	})
	return
}
func (d *ServiceDB) LoadMatrixClientConfig(userID id.UserID) (config api.ClientConfig, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		config, err = selectMatrixClientConfigTxn(txn, userID)
		return err
	})
	return
}
func (d *ServiceDB) UpdateNextBatch(userID id.UserID, nextBatch string) (err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		return updateNextBatchTxn(txn, userID, nextBatch)
	})
	return
}
func (d *ServiceDB) LoadNextBatch(userID id.UserID) (nextBatch string, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		nextBatch, err = selectNextBatchTxn(txn, userID)
		return err
	})
	return
}
func (d *ServiceDB) LoadService(serviceID string) (service types.Service, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		service, err = selectServiceTxn(txn, serviceID)
		return err
	})
	return
}
func (d *ServiceDB) DeleteService(serviceID string) (err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		return deleteServiceTxn(txn, serviceID)
	})
	return
}
func (d *ServiceDB) LoadServicesForUser(serviceUserID id.UserID) (services []types.Service, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		services, err = selectServicesForUserTxn(txn, serviceUserID)
		if err != nil {
			return err
		}
		return nil
	})
	return
}
func (d *ServiceDB) LoadServicesByType(serviceType string) (services []types.Service, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		services, err = selectServicesByTypeTxn(txn, serviceType)
		if err != nil {
			return err
		}
		return nil
	})
	return
}
func (d *ServiceDB) StoreService(service types.Service) (oldService types.Service, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		oldService, err = selectServiceTxn(txn, service.ServiceID())
		if err == sql.ErrNoRows {
			return insertServiceTxn(txn, time.Now(), service)
		} else if err != nil {
			return err
		} else {
			return updateServiceTxn(txn, time.Now(), service)
		}
	})
	return
}
func (d *ServiceDB) LoadAuthRealm(realmID string) (realm types.AuthRealm, err error) {
	err = runTransaction(d.db, func(txn *sql.Tx) error {
		realm, err = selectRealmTxn(txn, realmID)
		return err
	})
	return
}