(Pinned)Notices
Notices are pages that admins can fill with their content to describe and customize the room. Pinned notices are common notices that each room has. Like a description and privacy policy. * update models * simple crud test for basic notices * edit and save notices as admin
This commit is contained in:
parent
3c921cef80
commit
e5a07fd8bc
|
@ -47,6 +47,26 @@ type AllowListService interface {
|
|||
// AliasService manages alias handle registration and lookup
|
||||
type AliasService interface{}
|
||||
|
||||
// PinnedNoticesService allows an admin to assign Notices to specific placeholder pages.
|
||||
// TODO: better name then _fixed_
|
||||
// like updates, privacy policy, code of conduct
|
||||
// TODO: enum these
|
||||
type PinnedNoticesService interface {
|
||||
// Set assigns a fixed page name to an page ID and a language to allow for multiple translated versions of the same page.
|
||||
Set(name PinnedNoticeName, id int64, lang string) error
|
||||
}
|
||||
|
||||
type NoticesService interface {
|
||||
// GetByID returns the page for that ID or an error
|
||||
GetByID(context.Context, int64) (Notice, error)
|
||||
|
||||
// Save updates the passed page or creates it if it's ID is zero
|
||||
Save(context.Context, *Notice) error
|
||||
|
||||
// RemoveID removes the page for that ID.
|
||||
RemoveID(context.Context, int64) error
|
||||
}
|
||||
|
||||
// for tests we use generated mocks from these interfaces created with https://github.com/maxbrunsfeld/counterfeiter
|
||||
|
||||
//go:generate counterfeiter -o mockdb/auth.go . AuthWithSSBService
|
||||
|
@ -56,3 +76,7 @@ type AliasService interface{}
|
|||
//go:generate counterfeiter -o mockdb/allow.go . AllowListService
|
||||
|
||||
//go:generate counterfeiter -o mockdb/alias.go . AliasService
|
||||
|
||||
//go:generate counterfeiter -o mockdb/fixed_pages.go . PinnedNoticesService
|
||||
|
||||
//go:generate counterfeiter -o mockdb/pages.go . NoticesService
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package mockdb
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
)
|
||||
|
||||
type FakePinnedNoticesService struct {
|
||||
SetStub func(admindb.PinnedNoticeName, int64, string) error
|
||||
setMutex sync.RWMutex
|
||||
setArgsForCall []struct {
|
||||
arg1 admindb.PinnedNoticeName
|
||||
arg2 int64
|
||||
arg3 string
|
||||
}
|
||||
setReturns struct {
|
||||
result1 error
|
||||
}
|
||||
setReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) Set(arg1 admindb.PinnedNoticeName, arg2 int64, arg3 string) error {
|
||||
fake.setMutex.Lock()
|
||||
ret, specificReturn := fake.setReturnsOnCall[len(fake.setArgsForCall)]
|
||||
fake.setArgsForCall = append(fake.setArgsForCall, struct {
|
||||
arg1 admindb.PinnedNoticeName
|
||||
arg2 int64
|
||||
arg3 string
|
||||
}{arg1, arg2, arg3})
|
||||
stub := fake.SetStub
|
||||
fakeReturns := fake.setReturns
|
||||
fake.recordInvocation("Set", []interface{}{arg1, arg2, arg3})
|
||||
fake.setMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2, arg3)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetCallCount() int {
|
||||
fake.setMutex.RLock()
|
||||
defer fake.setMutex.RUnlock()
|
||||
return len(fake.setArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetCalls(stub func(admindb.PinnedNoticeName, int64, string) error) {
|
||||
fake.setMutex.Lock()
|
||||
defer fake.setMutex.Unlock()
|
||||
fake.SetStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetArgsForCall(i int) (admindb.PinnedNoticeName, int64, string) {
|
||||
fake.setMutex.RLock()
|
||||
defer fake.setMutex.RUnlock()
|
||||
argsForCall := fake.setArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetReturns(result1 error) {
|
||||
fake.setMutex.Lock()
|
||||
defer fake.setMutex.Unlock()
|
||||
fake.SetStub = nil
|
||||
fake.setReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetReturnsOnCall(i int, result1 error) {
|
||||
fake.setMutex.Lock()
|
||||
defer fake.setMutex.Unlock()
|
||||
fake.SetStub = nil
|
||||
if fake.setReturnsOnCall == nil {
|
||||
fake.setReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.setReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.setMutex.RLock()
|
||||
defer fake.setMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ admindb.PinnedNoticesService = new(FakePinnedNoticesService)
|
|
@ -0,0 +1,276 @@
|
|||
// Code generated by counterfeiter. DO NOT EDIT.
|
||||
package mockdb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
)
|
||||
|
||||
type FakeNoticesService struct {
|
||||
GetByIDStub func(context.Context, int64) (admindb.Notice, error)
|
||||
getByIDMutex sync.RWMutex
|
||||
getByIDArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 int64
|
||||
}
|
||||
getByIDReturns struct {
|
||||
result1 admindb.Notice
|
||||
result2 error
|
||||
}
|
||||
getByIDReturnsOnCall map[int]struct {
|
||||
result1 admindb.Notice
|
||||
result2 error
|
||||
}
|
||||
RemoveIDStub func(context.Context, int64) error
|
||||
removeIDMutex sync.RWMutex
|
||||
removeIDArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 int64
|
||||
}
|
||||
removeIDReturns struct {
|
||||
result1 error
|
||||
}
|
||||
removeIDReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
SaveStub func(context.Context, admindb.Notice) (int64, error)
|
||||
saveMutex sync.RWMutex
|
||||
saveArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 admindb.Notice
|
||||
}
|
||||
saveReturns struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
}
|
||||
saveReturnsOnCall map[int]struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) GetByID(arg1 context.Context, arg2 int64) (admindb.Notice, error) {
|
||||
fake.getByIDMutex.Lock()
|
||||
ret, specificReturn := fake.getByIDReturnsOnCall[len(fake.getByIDArgsForCall)]
|
||||
fake.getByIDArgsForCall = append(fake.getByIDArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 int64
|
||||
}{arg1, arg2})
|
||||
stub := fake.GetByIDStub
|
||||
fakeReturns := fake.getByIDReturns
|
||||
fake.recordInvocation("GetByID", []interface{}{arg1, arg2})
|
||||
fake.getByIDMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) GetByIDCallCount() int {
|
||||
fake.getByIDMutex.RLock()
|
||||
defer fake.getByIDMutex.RUnlock()
|
||||
return len(fake.getByIDArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) GetByIDCalls(stub func(context.Context, int64) (admindb.Notice, error)) {
|
||||
fake.getByIDMutex.Lock()
|
||||
defer fake.getByIDMutex.Unlock()
|
||||
fake.GetByIDStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) GetByIDArgsForCall(i int) (context.Context, int64) {
|
||||
fake.getByIDMutex.RLock()
|
||||
defer fake.getByIDMutex.RUnlock()
|
||||
argsForCall := fake.getByIDArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) GetByIDReturns(result1 admindb.Notice, result2 error) {
|
||||
fake.getByIDMutex.Lock()
|
||||
defer fake.getByIDMutex.Unlock()
|
||||
fake.GetByIDStub = nil
|
||||
fake.getByIDReturns = struct {
|
||||
result1 admindb.Notice
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) GetByIDReturnsOnCall(i int, result1 admindb.Notice, result2 error) {
|
||||
fake.getByIDMutex.Lock()
|
||||
defer fake.getByIDMutex.Unlock()
|
||||
fake.GetByIDStub = nil
|
||||
if fake.getByIDReturnsOnCall == nil {
|
||||
fake.getByIDReturnsOnCall = make(map[int]struct {
|
||||
result1 admindb.Notice
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.getByIDReturnsOnCall[i] = struct {
|
||||
result1 admindb.Notice
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) RemoveID(arg1 context.Context, arg2 int64) error {
|
||||
fake.removeIDMutex.Lock()
|
||||
ret, specificReturn := fake.removeIDReturnsOnCall[len(fake.removeIDArgsForCall)]
|
||||
fake.removeIDArgsForCall = append(fake.removeIDArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 int64
|
||||
}{arg1, arg2})
|
||||
stub := fake.RemoveIDStub
|
||||
fakeReturns := fake.removeIDReturns
|
||||
fake.recordInvocation("RemoveID", []interface{}{arg1, arg2})
|
||||
fake.removeIDMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) RemoveIDCallCount() int {
|
||||
fake.removeIDMutex.RLock()
|
||||
defer fake.removeIDMutex.RUnlock()
|
||||
return len(fake.removeIDArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) RemoveIDCalls(stub func(context.Context, int64) error) {
|
||||
fake.removeIDMutex.Lock()
|
||||
defer fake.removeIDMutex.Unlock()
|
||||
fake.RemoveIDStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) RemoveIDArgsForCall(i int) (context.Context, int64) {
|
||||
fake.removeIDMutex.RLock()
|
||||
defer fake.removeIDMutex.RUnlock()
|
||||
argsForCall := fake.removeIDArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) RemoveIDReturns(result1 error) {
|
||||
fake.removeIDMutex.Lock()
|
||||
defer fake.removeIDMutex.Unlock()
|
||||
fake.RemoveIDStub = nil
|
||||
fake.removeIDReturns = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) RemoveIDReturnsOnCall(i int, result1 error) {
|
||||
fake.removeIDMutex.Lock()
|
||||
defer fake.removeIDMutex.Unlock()
|
||||
fake.RemoveIDStub = nil
|
||||
if fake.removeIDReturnsOnCall == nil {
|
||||
fake.removeIDReturnsOnCall = make(map[int]struct {
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.removeIDReturnsOnCall[i] = struct {
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) Save(arg1 context.Context, arg2 admindb.Notice) (int64, error) {
|
||||
fake.saveMutex.Lock()
|
||||
ret, specificReturn := fake.saveReturnsOnCall[len(fake.saveArgsForCall)]
|
||||
fake.saveArgsForCall = append(fake.saveArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 admindb.Notice
|
||||
}{arg1, arg2})
|
||||
stub := fake.SaveStub
|
||||
fakeReturns := fake.saveReturns
|
||||
fake.recordInvocation("Save", []interface{}{arg1, arg2})
|
||||
fake.saveMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveCallCount() int {
|
||||
fake.saveMutex.RLock()
|
||||
defer fake.saveMutex.RUnlock()
|
||||
return len(fake.saveArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveCalls(stub func(context.Context, admindb.Notice) (int64, error)) {
|
||||
fake.saveMutex.Lock()
|
||||
defer fake.saveMutex.Unlock()
|
||||
fake.SaveStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveArgsForCall(i int) (context.Context, admindb.Notice) {
|
||||
fake.saveMutex.RLock()
|
||||
defer fake.saveMutex.RUnlock()
|
||||
argsForCall := fake.saveArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveReturns(result1 int64, result2 error) {
|
||||
fake.saveMutex.Lock()
|
||||
defer fake.saveMutex.Unlock()
|
||||
fake.SaveStub = nil
|
||||
fake.saveReturns = struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveReturnsOnCall(i int, result1 int64, result2 error) {
|
||||
fake.saveMutex.Lock()
|
||||
defer fake.saveMutex.Unlock()
|
||||
fake.SaveStub = nil
|
||||
if fake.saveReturnsOnCall == nil {
|
||||
fake.saveReturnsOnCall = make(map[int]struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.saveReturnsOnCall[i] = struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.getByIDMutex.RLock()
|
||||
defer fake.getByIDMutex.RUnlock()
|
||||
fake.removeIDMutex.RLock()
|
||||
defer fake.removeIDMutex.RUnlock()
|
||||
fake.saveMutex.RLock()
|
||||
defer fake.saveMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
for key, value := range fake.invocations {
|
||||
copiedInvocations[key] = value
|
||||
}
|
||||
return copiedInvocations
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) recordInvocation(key string, args []interface{}) {
|
||||
fake.invocationsMutex.Lock()
|
||||
defer fake.invocationsMutex.Unlock()
|
||||
if fake.invocations == nil {
|
||||
fake.invocations = map[string][][]interface{}{}
|
||||
}
|
||||
if fake.invocations[key] == nil {
|
||||
fake.invocations[key] = [][]interface{}{}
|
||||
}
|
||||
fake.invocations[key] = append(fake.invocations[key], args)
|
||||
}
|
||||
|
||||
var _ admindb.NoticesService = new(FakeNoticesService)
|
|
@ -0,0 +1,44 @@
|
|||
-- +migrate Up
|
||||
CREATE TABLE notices (
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
title text NOT NULL,
|
||||
content text NOT NULL,
|
||||
language text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE pinned_notices (
|
||||
name text NOT NULL,
|
||||
notice_id integer NOT NULL UNIQUE,
|
||||
language text NOT NULL,
|
||||
|
||||
PRIMARY KEY (name, language),
|
||||
|
||||
-- make sure the notices exist
|
||||
FOREIGN KEY ( notice_id ) REFERENCES notices( "id" )
|
||||
);
|
||||
|
||||
INSERT INTO notices (title, content, language) VALUES
|
||||
('Description', 'Basic description of this Room.', 'en-GB'),
|
||||
('News', 'Some recent updates...', 'en-GB'),
|
||||
('Code of conduct', 'We expect each other to ...
|
||||
* be considerate
|
||||
* be respectful
|
||||
* be responsible
|
||||
* be dedicated
|
||||
* be empathetic
|
||||
', 'en-GB'),
|
||||
('Privacy Policy', 'To be updated', 'en-GB'),
|
||||
('Datenschutzrichtlinien', 'Bitte aktualisieren', 'de-DE'),
|
||||
('Beschreibung', 'Allgemeine beschreibung des Raumes.', 'de-DE');
|
||||
|
||||
INSERT INTO pinned_notices (name, notice_id, language) VALUES
|
||||
('NoticeDescription', 1, 'en-GB'),
|
||||
('NoticeNews', 2, 'en-GB'),
|
||||
('NoticeCodeOfConduct', 3, 'en-GB'),
|
||||
('NoticePrivacyPolicy', 4, 'en-GB'),
|
||||
('NoticePrivacyPolicy', 5, 'de-DE'),
|
||||
('NoticeDescription', 6, 'de-DE');
|
||||
|
||||
-- +migrate Down
|
||||
DROP TABLE notices;
|
||||
DROP TABLE pinned_notices;
|
|
@ -4,9 +4,13 @@
|
|||
package models
|
||||
|
||||
var TableNames = struct {
|
||||
AllowList string
|
||||
AuthFallback string
|
||||
AllowList string
|
||||
AuthFallback string
|
||||
Notices string
|
||||
PinnedNotices string
|
||||
}{
|
||||
AllowList: "allow_list",
|
||||
AuthFallback: "auth_fallback",
|
||||
AllowList: "allow_list",
|
||||
AuthFallback: "auth_fallback",
|
||||
Notices: "notices",
|
||||
PinnedNotices: "pinned_notices",
|
||||
}
|
||||
|
|
|
@ -0,0 +1,959 @@
|
|||
// Code generated by SQLBoiler 4.4.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
|
||||
"github.com/volatiletech/strmangle"
|
||||
)
|
||||
|
||||
// Notice is an object representing the database table.
|
||||
type Notice struct {
|
||||
ID int64 `boil:"id" json:"id" toml:"id" yaml:"id"`
|
||||
Title string `boil:"title" json:"title" toml:"title" yaml:"title"`
|
||||
Content string `boil:"content" json:"content" toml:"content" yaml:"content"`
|
||||
Language string `boil:"language" json:"language" toml:"language" yaml:"language"`
|
||||
|
||||
R *noticeR `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
L noticeL `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
var NoticeColumns = struct {
|
||||
ID string
|
||||
Title string
|
||||
Content string
|
||||
Language string
|
||||
}{
|
||||
ID: "id",
|
||||
Title: "title",
|
||||
Content: "content",
|
||||
Language: "language",
|
||||
}
|
||||
|
||||
// Generated where
|
||||
|
||||
var NoticeWhere = struct {
|
||||
ID whereHelperint64
|
||||
Title whereHelperstring
|
||||
Content whereHelperstring
|
||||
Language whereHelperstring
|
||||
}{
|
||||
ID: whereHelperint64{field: "\"notices\".\"id\""},
|
||||
Title: whereHelperstring{field: "\"notices\".\"title\""},
|
||||
Content: whereHelperstring{field: "\"notices\".\"content\""},
|
||||
Language: whereHelperstring{field: "\"notices\".\"language\""},
|
||||
}
|
||||
|
||||
// NoticeRels is where relationship names are stored.
|
||||
var NoticeRels = struct {
|
||||
PinnedNotice string
|
||||
}{
|
||||
PinnedNotice: "PinnedNotice",
|
||||
}
|
||||
|
||||
// noticeR is where relationships are stored.
|
||||
type noticeR struct {
|
||||
PinnedNotice *PinnedNotice `boil:"PinnedNotice" json:"PinnedNotice" toml:"PinnedNotice" yaml:"PinnedNotice"`
|
||||
}
|
||||
|
||||
// NewStruct creates a new relationship struct
|
||||
func (*noticeR) NewStruct() *noticeR {
|
||||
return ¬iceR{}
|
||||
}
|
||||
|
||||
// noticeL is where Load methods for each relationship are stored.
|
||||
type noticeL struct{}
|
||||
|
||||
var (
|
||||
noticeAllColumns = []string{"id", "title", "content", "language"}
|
||||
noticeColumnsWithoutDefault = []string{}
|
||||
noticeColumnsWithDefault = []string{"id", "title", "content", "language"}
|
||||
noticePrimaryKeyColumns = []string{"id"}
|
||||
)
|
||||
|
||||
type (
|
||||
// NoticeSlice is an alias for a slice of pointers to Notice.
|
||||
// This should generally be used opposed to []Notice.
|
||||
NoticeSlice []*Notice
|
||||
// NoticeHook is the signature for custom Notice hook methods
|
||||
NoticeHook func(context.Context, boil.ContextExecutor, *Notice) error
|
||||
|
||||
noticeQuery struct {
|
||||
*queries.Query
|
||||
}
|
||||
)
|
||||
|
||||
// Cache for insert, update and upsert
|
||||
var (
|
||||
noticeType = reflect.TypeOf(&Notice{})
|
||||
noticeMapping = queries.MakeStructMapping(noticeType)
|
||||
noticePrimaryKeyMapping, _ = queries.BindMapping(noticeType, noticeMapping, noticePrimaryKeyColumns)
|
||||
noticeInsertCacheMut sync.RWMutex
|
||||
noticeInsertCache = make(map[string]insertCache)
|
||||
noticeUpdateCacheMut sync.RWMutex
|
||||
noticeUpdateCache = make(map[string]updateCache)
|
||||
noticeUpsertCacheMut sync.RWMutex
|
||||
noticeUpsertCache = make(map[string]insertCache)
|
||||
)
|
||||
|
||||
var (
|
||||
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
||||
_ = time.Second
|
||||
// Force qmhelper dependency for where clause generation (which doesn't
|
||||
// always happen)
|
||||
_ = qmhelper.Where
|
||||
)
|
||||
|
||||
var noticeBeforeInsertHooks []NoticeHook
|
||||
var noticeBeforeUpdateHooks []NoticeHook
|
||||
var noticeBeforeDeleteHooks []NoticeHook
|
||||
var noticeBeforeUpsertHooks []NoticeHook
|
||||
|
||||
var noticeAfterInsertHooks []NoticeHook
|
||||
var noticeAfterSelectHooks []NoticeHook
|
||||
var noticeAfterUpdateHooks []NoticeHook
|
||||
var noticeAfterDeleteHooks []NoticeHook
|
||||
var noticeAfterUpsertHooks []NoticeHook
|
||||
|
||||
// doBeforeInsertHooks executes all "before insert" hooks.
|
||||
func (o *Notice) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeBeforeInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpdateHooks executes all "before Update" hooks.
|
||||
func (o *Notice) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeBeforeUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeDeleteHooks executes all "before Delete" hooks.
|
||||
func (o *Notice) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeBeforeDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpsertHooks executes all "before Upsert" hooks.
|
||||
func (o *Notice) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeBeforeUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterInsertHooks executes all "after Insert" hooks.
|
||||
func (o *Notice) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeAfterInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterSelectHooks executes all "after Select" hooks.
|
||||
func (o *Notice) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeAfterSelectHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpdateHooks executes all "after Update" hooks.
|
||||
func (o *Notice) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeAfterUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterDeleteHooks executes all "after Delete" hooks.
|
||||
func (o *Notice) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeAfterDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpsertHooks executes all "after Upsert" hooks.
|
||||
func (o *Notice) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range noticeAfterUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddNoticeHook registers your hook function for all future operations.
|
||||
func AddNoticeHook(hookPoint boil.HookPoint, noticeHook NoticeHook) {
|
||||
switch hookPoint {
|
||||
case boil.BeforeInsertHook:
|
||||
noticeBeforeInsertHooks = append(noticeBeforeInsertHooks, noticeHook)
|
||||
case boil.BeforeUpdateHook:
|
||||
noticeBeforeUpdateHooks = append(noticeBeforeUpdateHooks, noticeHook)
|
||||
case boil.BeforeDeleteHook:
|
||||
noticeBeforeDeleteHooks = append(noticeBeforeDeleteHooks, noticeHook)
|
||||
case boil.BeforeUpsertHook:
|
||||
noticeBeforeUpsertHooks = append(noticeBeforeUpsertHooks, noticeHook)
|
||||
case boil.AfterInsertHook:
|
||||
noticeAfterInsertHooks = append(noticeAfterInsertHooks, noticeHook)
|
||||
case boil.AfterSelectHook:
|
||||
noticeAfterSelectHooks = append(noticeAfterSelectHooks, noticeHook)
|
||||
case boil.AfterUpdateHook:
|
||||
noticeAfterUpdateHooks = append(noticeAfterUpdateHooks, noticeHook)
|
||||
case boil.AfterDeleteHook:
|
||||
noticeAfterDeleteHooks = append(noticeAfterDeleteHooks, noticeHook)
|
||||
case boil.AfterUpsertHook:
|
||||
noticeAfterUpsertHooks = append(noticeAfterUpsertHooks, noticeHook)
|
||||
}
|
||||
}
|
||||
|
||||
// One returns a single notice record from the query.
|
||||
func (q noticeQuery) One(ctx context.Context, exec boil.ContextExecutor) (*Notice, error) {
|
||||
o := &Notice{}
|
||||
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Bind(ctx, exec, o)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "models: failed to execute a one query for notices")
|
||||
}
|
||||
|
||||
if err := o.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// All returns all Notice records from the query.
|
||||
func (q noticeQuery) All(ctx context.Context, exec boil.ContextExecutor) (NoticeSlice, error) {
|
||||
var o []*Notice
|
||||
|
||||
err := q.Bind(ctx, exec, &o)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "models: failed to assign all query results to Notice slice")
|
||||
}
|
||||
|
||||
if len(noticeAfterSelectHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Count returns the count of all Notice records in the query.
|
||||
func (q noticeQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to count notices rows")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Exists checks if the row exists in the table.
|
||||
func (q noticeQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "models: failed to check if notices exists")
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// PinnedNotice pointed to by the foreign key.
|
||||
func (o *Notice) PinnedNotice(mods ...qm.QueryMod) pinnedNoticeQuery {
|
||||
queryMods := []qm.QueryMod{
|
||||
qm.Where("\"notice_id\" = ?", o.ID),
|
||||
}
|
||||
|
||||
queryMods = append(queryMods, mods...)
|
||||
|
||||
query := PinnedNotices(queryMods...)
|
||||
queries.SetFrom(query.Query, "\"pinned_notices\"")
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
// LoadPinnedNotice allows an eager lookup of values, cached into the
|
||||
// loaded structs of the objects. This is for a 1-1 relationship.
|
||||
func (noticeL) LoadPinnedNotice(ctx context.Context, e boil.ContextExecutor, singular bool, maybeNotice interface{}, mods queries.Applicator) error {
|
||||
var slice []*Notice
|
||||
var object *Notice
|
||||
|
||||
if singular {
|
||||
object = maybeNotice.(*Notice)
|
||||
} else {
|
||||
slice = *maybeNotice.(*[]*Notice)
|
||||
}
|
||||
|
||||
args := make([]interface{}, 0, 1)
|
||||
if singular {
|
||||
if object.R == nil {
|
||||
object.R = ¬iceR{}
|
||||
}
|
||||
args = append(args, object.ID)
|
||||
} else {
|
||||
Outer:
|
||||
for _, obj := range slice {
|
||||
if obj.R == nil {
|
||||
obj.R = ¬iceR{}
|
||||
}
|
||||
|
||||
for _, a := range args {
|
||||
if a == obj.ID {
|
||||
continue Outer
|
||||
}
|
||||
}
|
||||
|
||||
args = append(args, obj.ID)
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
query := NewQuery(
|
||||
qm.From(`pinned_notices`),
|
||||
qm.WhereIn(`pinned_notices.notice_id in ?`, args...),
|
||||
)
|
||||
if mods != nil {
|
||||
mods.Apply(query)
|
||||
}
|
||||
|
||||
results, err := query.QueryContext(ctx, e)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to eager load PinnedNotice")
|
||||
}
|
||||
|
||||
var resultSlice []*PinnedNotice
|
||||
if err = queries.Bind(results, &resultSlice); err != nil {
|
||||
return errors.Wrap(err, "failed to bind eager loaded slice PinnedNotice")
|
||||
}
|
||||
|
||||
if err = results.Close(); err != nil {
|
||||
return errors.Wrap(err, "failed to close results of eager load for pinned_notices")
|
||||
}
|
||||
if err = results.Err(); err != nil {
|
||||
return errors.Wrap(err, "error occurred during iteration of eager loaded relations for pinned_notices")
|
||||
}
|
||||
|
||||
if len(noticeAfterSelectHooks) != 0 {
|
||||
for _, obj := range resultSlice {
|
||||
if err := obj.doAfterSelectHooks(ctx, e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(resultSlice) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if singular {
|
||||
foreign := resultSlice[0]
|
||||
object.R.PinnedNotice = foreign
|
||||
if foreign.R == nil {
|
||||
foreign.R = &pinnedNoticeR{}
|
||||
}
|
||||
foreign.R.Notice = object
|
||||
}
|
||||
|
||||
for _, local := range slice {
|
||||
for _, foreign := range resultSlice {
|
||||
if local.ID == foreign.NoticeID {
|
||||
local.R.PinnedNotice = foreign
|
||||
if foreign.R == nil {
|
||||
foreign.R = &pinnedNoticeR{}
|
||||
}
|
||||
foreign.R.Notice = local
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPinnedNotice of the notice to the related item.
|
||||
// Sets o.R.PinnedNotice to related.
|
||||
// Adds o to related.R.Notice.
|
||||
func (o *Notice) SetPinnedNotice(ctx context.Context, exec boil.ContextExecutor, insert bool, related *PinnedNotice) error {
|
||||
var err error
|
||||
|
||||
if insert {
|
||||
related.NoticeID = o.ID
|
||||
|
||||
if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
|
||||
return errors.Wrap(err, "failed to insert into foreign table")
|
||||
}
|
||||
} else {
|
||||
updateQuery := fmt.Sprintf(
|
||||
"UPDATE \"pinned_notices\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 0, []string{"notice_id"}),
|
||||
strmangle.WhereClause("\"", "\"", 0, pinnedNoticePrimaryKeyColumns),
|
||||
)
|
||||
values := []interface{}{o.ID, related.Name, related.Language}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, updateQuery)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
|
||||
return errors.Wrap(err, "failed to update foreign table")
|
||||
}
|
||||
|
||||
related.NoticeID = o.ID
|
||||
|
||||
}
|
||||
|
||||
if o.R == nil {
|
||||
o.R = ¬iceR{
|
||||
PinnedNotice: related,
|
||||
}
|
||||
} else {
|
||||
o.R.PinnedNotice = related
|
||||
}
|
||||
|
||||
if related.R == nil {
|
||||
related.R = &pinnedNoticeR{
|
||||
Notice: o,
|
||||
}
|
||||
} else {
|
||||
related.R.Notice = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Notices retrieves all the records using an executor.
|
||||
func Notices(mods ...qm.QueryMod) noticeQuery {
|
||||
mods = append(mods, qm.From("\"notices\""))
|
||||
return noticeQuery{NewQuery(mods...)}
|
||||
}
|
||||
|
||||
// FindNotice retrieves a single record by ID with an executor.
|
||||
// If selectCols is empty Find will return all columns.
|
||||
func FindNotice(ctx context.Context, exec boil.ContextExecutor, iD int64, selectCols ...string) (*Notice, error) {
|
||||
noticeObj := &Notice{}
|
||||
|
||||
sel := "*"
|
||||
if len(selectCols) > 0 {
|
||||
sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
|
||||
}
|
||||
query := fmt.Sprintf(
|
||||
"select %s from \"notices\" where \"id\"=?", sel,
|
||||
)
|
||||
|
||||
q := queries.Raw(query, iD)
|
||||
|
||||
err := q.Bind(ctx, exec, noticeObj)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "models: unable to select from notices")
|
||||
}
|
||||
|
||||
return noticeObj, nil
|
||||
}
|
||||
|
||||
// Insert a single record using an executor.
|
||||
// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts.
|
||||
func (o *Notice) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
|
||||
if o == nil {
|
||||
return errors.New("models: no notices provided for insertion")
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nzDefaults := queries.NonZeroDefaultSet(noticeColumnsWithDefault, o)
|
||||
|
||||
key := makeCacheKey(columns, nzDefaults)
|
||||
noticeInsertCacheMut.RLock()
|
||||
cache, cached := noticeInsertCache[key]
|
||||
noticeInsertCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl, returnColumns := columns.InsertColumnSet(
|
||||
noticeAllColumns,
|
||||
noticeColumnsWithDefault,
|
||||
noticeColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
)
|
||||
|
||||
cache.valueMapping, err = queries.BindMapping(noticeType, noticeMapping, wl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.retMapping, err = queries.BindMapping(noticeType, noticeMapping, returnColumns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(wl) != 0 {
|
||||
cache.query = fmt.Sprintf("INSERT INTO \"notices\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1))
|
||||
} else {
|
||||
cache.query = "INSERT INTO \"notices\" %sDEFAULT VALUES%s"
|
||||
}
|
||||
|
||||
var queryOutput, queryReturning string
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
cache.retQuery = fmt.Sprintf("SELECT \"%s\" FROM \"notices\" WHERE %s", strings.Join(returnColumns, "\",\""), strmangle.WhereClause("\"", "\"", 0, noticePrimaryKeyColumns))
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning)
|
||||
}
|
||||
|
||||
value := reflect.Indirect(reflect.ValueOf(o))
|
||||
vals := queries.ValuesFromMapping(value, cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, vals)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, cache.query, vals...)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "models: unable to insert into notices")
|
||||
}
|
||||
|
||||
var lastID int64
|
||||
var identifierCols []interface{}
|
||||
|
||||
if len(cache.retMapping) == 0 {
|
||||
goto CacheNoHooks
|
||||
}
|
||||
|
||||
lastID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
return ErrSyncFail
|
||||
}
|
||||
|
||||
o.ID = int64(lastID)
|
||||
if lastID != 0 && len(cache.retMapping) == 1 && cache.retMapping[0] == noticeMapping["id"] {
|
||||
goto CacheNoHooks
|
||||
}
|
||||
|
||||
identifierCols = []interface{}{
|
||||
o.ID,
|
||||
}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.retQuery)
|
||||
fmt.Fprintln(writer, identifierCols...)
|
||||
}
|
||||
err = exec.QueryRowContext(ctx, cache.retQuery, identifierCols...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "models: unable to populate default values for notices")
|
||||
}
|
||||
|
||||
CacheNoHooks:
|
||||
if !cached {
|
||||
noticeInsertCacheMut.Lock()
|
||||
noticeInsertCache[key] = cache
|
||||
noticeInsertCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return o.doAfterInsertHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// Update uses an executor to update the Notice.
|
||||
// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates.
|
||||
// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records.
|
||||
func (o *Notice) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) {
|
||||
var err error
|
||||
if err = o.doBeforeUpdateHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
key := makeCacheKey(columns, nil)
|
||||
noticeUpdateCacheMut.RLock()
|
||||
cache, cached := noticeUpdateCache[key]
|
||||
noticeUpdateCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl := columns.UpdateColumnSet(
|
||||
noticeAllColumns,
|
||||
noticePrimaryKeyColumns,
|
||||
)
|
||||
|
||||
if !columns.IsWhitelist() {
|
||||
wl = strmangle.SetComplement(wl, []string{"created_at"})
|
||||
}
|
||||
if len(wl) == 0 {
|
||||
return 0, errors.New("models: unable to update notices, could not build whitelist")
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf("UPDATE \"notices\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 0, wl),
|
||||
strmangle.WhereClause("\"", "\"", 0, noticePrimaryKeyColumns),
|
||||
)
|
||||
cache.valueMapping, err = queries.BindMapping(noticeType, noticeMapping, append(wl, noticePrimaryKeyColumns...))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
var result sql.Result
|
||||
result, err = exec.ExecContext(ctx, cache.query, values...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to update notices row")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by update for notices")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
noticeUpdateCacheMut.Lock()
|
||||
noticeUpdateCache[key] = cache
|
||||
noticeUpdateCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return rowsAff, o.doAfterUpdateHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values.
|
||||
func (q noticeQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
queries.SetUpdate(q.Query, cols)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to update all for notices")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to retrieve rows affected for notices")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values, using an executor.
|
||||
func (o NoticeSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
ln := int64(len(o))
|
||||
if ln == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(cols) == 0 {
|
||||
return 0, errors.New("models: update all requires at least one column argument")
|
||||
}
|
||||
|
||||
colNames := make([]string, len(cols))
|
||||
args := make([]interface{}, len(cols))
|
||||
|
||||
i := 0
|
||||
for name, value := range cols {
|
||||
colNames[i] = name
|
||||
args[i] = value
|
||||
i++
|
||||
}
|
||||
|
||||
// Append all of the primary key values for each column
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), noticePrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("UPDATE \"notices\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 0, colNames),
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, noticePrimaryKeyColumns, len(o)))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to update all in notice slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to retrieve rows affected all in update all notice")
|
||||
}
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Delete deletes a single Notice record with an executor.
|
||||
// Delete will match against the primary key column to find the record to delete.
|
||||
func (o *Notice) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if o == nil {
|
||||
return 0, errors.New("models: no Notice provided for delete")
|
||||
}
|
||||
|
||||
if err := o.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), noticePrimaryKeyMapping)
|
||||
sql := "DELETE FROM \"notices\" WHERE \"id\"=?"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to delete from notices")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by delete for notices")
|
||||
}
|
||||
|
||||
if err := o.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all matching rows.
|
||||
func (q noticeQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if q.Query == nil {
|
||||
return 0, errors.New("models: no noticeQuery provided for delete all")
|
||||
}
|
||||
|
||||
queries.SetDelete(q.Query)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to delete all from notices")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for notices")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all rows in the slice, using an executor.
|
||||
func (o NoticeSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if len(o) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(noticeBeforeDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), noticePrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "DELETE FROM \"notices\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, noticePrimaryKeyColumns, len(o))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to delete all from notice slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for notices")
|
||||
}
|
||||
|
||||
if len(noticeAfterDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Reload refetches the object from the database
|
||||
// using the primary keys with an executor.
|
||||
func (o *Notice) Reload(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
ret, err := FindNotice(ctx, exec, o.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*o = *ret
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReloadAll refetches every row with matching primary key column values
|
||||
// and overwrites the original object slice with the newly updated slice.
|
||||
func (o *NoticeSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
if o == nil || len(*o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
slice := NoticeSlice{}
|
||||
var args []interface{}
|
||||
for _, obj := range *o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), noticePrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "SELECT \"notices\".* FROM \"notices\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, noticePrimaryKeyColumns, len(*o))
|
||||
|
||||
q := queries.Raw(sql, args...)
|
||||
|
||||
err := q.Bind(ctx, exec, &slice)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "models: unable to reload all in NoticeSlice")
|
||||
}
|
||||
|
||||
*o = slice
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NoticeExists checks if the Notice row exists.
|
||||
func NoticeExists(ctx context.Context, exec boil.ContextExecutor, iD int64) (bool, error) {
|
||||
var exists bool
|
||||
sql := "select exists(select 1 from \"notices\" where \"id\"=? limit 1)"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, iD)
|
||||
}
|
||||
row := exec.QueryRowContext(ctx, sql, iD)
|
||||
|
||||
err := row.Scan(&exists)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "models: unable to check if notices exists")
|
||||
}
|
||||
|
||||
return exists, nil
|
||||
}
|
|
@ -0,0 +1,943 @@
|
|||
// Code generated by SQLBoiler 4.4.0 (https://github.com/volatiletech/sqlboiler). DO NOT EDIT.
|
||||
// This file is meant to be re-generated in place and/or deleted at any time.
|
||||
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qmhelper"
|
||||
"github.com/volatiletech/strmangle"
|
||||
)
|
||||
|
||||
// PinnedNotice is an object representing the database table.
|
||||
type PinnedNotice struct {
|
||||
Name string `boil:"name" json:"name" toml:"name" yaml:"name"`
|
||||
NoticeID int64 `boil:"notice_id" json:"notice_id" toml:"notice_id" yaml:"notice_id"`
|
||||
Language string `boil:"language" json:"language" toml:"language" yaml:"language"`
|
||||
|
||||
R *pinnedNoticeR `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
L pinnedNoticeL `boil:"-" json:"-" toml:"-" yaml:"-"`
|
||||
}
|
||||
|
||||
var PinnedNoticeColumns = struct {
|
||||
Name string
|
||||
NoticeID string
|
||||
Language string
|
||||
}{
|
||||
Name: "name",
|
||||
NoticeID: "notice_id",
|
||||
Language: "language",
|
||||
}
|
||||
|
||||
// Generated where
|
||||
|
||||
var PinnedNoticeWhere = struct {
|
||||
Name whereHelperstring
|
||||
NoticeID whereHelperint64
|
||||
Language whereHelperstring
|
||||
}{
|
||||
Name: whereHelperstring{field: "\"pinned_notices\".\"name\""},
|
||||
NoticeID: whereHelperint64{field: "\"pinned_notices\".\"notice_id\""},
|
||||
Language: whereHelperstring{field: "\"pinned_notices\".\"language\""},
|
||||
}
|
||||
|
||||
// PinnedNoticeRels is where relationship names are stored.
|
||||
var PinnedNoticeRels = struct {
|
||||
Notice string
|
||||
}{
|
||||
Notice: "Notice",
|
||||
}
|
||||
|
||||
// pinnedNoticeR is where relationships are stored.
|
||||
type pinnedNoticeR struct {
|
||||
Notice *Notice `boil:"Notice" json:"Notice" toml:"Notice" yaml:"Notice"`
|
||||
}
|
||||
|
||||
// NewStruct creates a new relationship struct
|
||||
func (*pinnedNoticeR) NewStruct() *pinnedNoticeR {
|
||||
return &pinnedNoticeR{}
|
||||
}
|
||||
|
||||
// pinnedNoticeL is where Load methods for each relationship are stored.
|
||||
type pinnedNoticeL struct{}
|
||||
|
||||
var (
|
||||
pinnedNoticeAllColumns = []string{"name", "notice_id", "language"}
|
||||
pinnedNoticeColumnsWithoutDefault = []string{"name", "notice_id", "language"}
|
||||
pinnedNoticeColumnsWithDefault = []string{}
|
||||
pinnedNoticePrimaryKeyColumns = []string{"name", "language"}
|
||||
)
|
||||
|
||||
type (
|
||||
// PinnedNoticeSlice is an alias for a slice of pointers to PinnedNotice.
|
||||
// This should generally be used opposed to []PinnedNotice.
|
||||
PinnedNoticeSlice []*PinnedNotice
|
||||
// PinnedNoticeHook is the signature for custom PinnedNotice hook methods
|
||||
PinnedNoticeHook func(context.Context, boil.ContextExecutor, *PinnedNotice) error
|
||||
|
||||
pinnedNoticeQuery struct {
|
||||
*queries.Query
|
||||
}
|
||||
)
|
||||
|
||||
// Cache for insert, update and upsert
|
||||
var (
|
||||
pinnedNoticeType = reflect.TypeOf(&PinnedNotice{})
|
||||
pinnedNoticeMapping = queries.MakeStructMapping(pinnedNoticeType)
|
||||
pinnedNoticePrimaryKeyMapping, _ = queries.BindMapping(pinnedNoticeType, pinnedNoticeMapping, pinnedNoticePrimaryKeyColumns)
|
||||
pinnedNoticeInsertCacheMut sync.RWMutex
|
||||
pinnedNoticeInsertCache = make(map[string]insertCache)
|
||||
pinnedNoticeUpdateCacheMut sync.RWMutex
|
||||
pinnedNoticeUpdateCache = make(map[string]updateCache)
|
||||
pinnedNoticeUpsertCacheMut sync.RWMutex
|
||||
pinnedNoticeUpsertCache = make(map[string]insertCache)
|
||||
)
|
||||
|
||||
var (
|
||||
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
||||
_ = time.Second
|
||||
// Force qmhelper dependency for where clause generation (which doesn't
|
||||
// always happen)
|
||||
_ = qmhelper.Where
|
||||
)
|
||||
|
||||
var pinnedNoticeBeforeInsertHooks []PinnedNoticeHook
|
||||
var pinnedNoticeBeforeUpdateHooks []PinnedNoticeHook
|
||||
var pinnedNoticeBeforeDeleteHooks []PinnedNoticeHook
|
||||
var pinnedNoticeBeforeUpsertHooks []PinnedNoticeHook
|
||||
|
||||
var pinnedNoticeAfterInsertHooks []PinnedNoticeHook
|
||||
var pinnedNoticeAfterSelectHooks []PinnedNoticeHook
|
||||
var pinnedNoticeAfterUpdateHooks []PinnedNoticeHook
|
||||
var pinnedNoticeAfterDeleteHooks []PinnedNoticeHook
|
||||
var pinnedNoticeAfterUpsertHooks []PinnedNoticeHook
|
||||
|
||||
// doBeforeInsertHooks executes all "before insert" hooks.
|
||||
func (o *PinnedNotice) doBeforeInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeBeforeInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpdateHooks executes all "before Update" hooks.
|
||||
func (o *PinnedNotice) doBeforeUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeBeforeUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeDeleteHooks executes all "before Delete" hooks.
|
||||
func (o *PinnedNotice) doBeforeDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeBeforeDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doBeforeUpsertHooks executes all "before Upsert" hooks.
|
||||
func (o *PinnedNotice) doBeforeUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeBeforeUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterInsertHooks executes all "after Insert" hooks.
|
||||
func (o *PinnedNotice) doAfterInsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeAfterInsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterSelectHooks executes all "after Select" hooks.
|
||||
func (o *PinnedNotice) doAfterSelectHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeAfterSelectHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpdateHooks executes all "after Update" hooks.
|
||||
func (o *PinnedNotice) doAfterUpdateHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeAfterUpdateHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterDeleteHooks executes all "after Delete" hooks.
|
||||
func (o *PinnedNotice) doAfterDeleteHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeAfterDeleteHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// doAfterUpsertHooks executes all "after Upsert" hooks.
|
||||
func (o *PinnedNotice) doAfterUpsertHooks(ctx context.Context, exec boil.ContextExecutor) (err error) {
|
||||
if boil.HooksAreSkipped(ctx) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, hook := range pinnedNoticeAfterUpsertHooks {
|
||||
if err := hook(ctx, exec, o); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddPinnedNoticeHook registers your hook function for all future operations.
|
||||
func AddPinnedNoticeHook(hookPoint boil.HookPoint, pinnedNoticeHook PinnedNoticeHook) {
|
||||
switch hookPoint {
|
||||
case boil.BeforeInsertHook:
|
||||
pinnedNoticeBeforeInsertHooks = append(pinnedNoticeBeforeInsertHooks, pinnedNoticeHook)
|
||||
case boil.BeforeUpdateHook:
|
||||
pinnedNoticeBeforeUpdateHooks = append(pinnedNoticeBeforeUpdateHooks, pinnedNoticeHook)
|
||||
case boil.BeforeDeleteHook:
|
||||
pinnedNoticeBeforeDeleteHooks = append(pinnedNoticeBeforeDeleteHooks, pinnedNoticeHook)
|
||||
case boil.BeforeUpsertHook:
|
||||
pinnedNoticeBeforeUpsertHooks = append(pinnedNoticeBeforeUpsertHooks, pinnedNoticeHook)
|
||||
case boil.AfterInsertHook:
|
||||
pinnedNoticeAfterInsertHooks = append(pinnedNoticeAfterInsertHooks, pinnedNoticeHook)
|
||||
case boil.AfterSelectHook:
|
||||
pinnedNoticeAfterSelectHooks = append(pinnedNoticeAfterSelectHooks, pinnedNoticeHook)
|
||||
case boil.AfterUpdateHook:
|
||||
pinnedNoticeAfterUpdateHooks = append(pinnedNoticeAfterUpdateHooks, pinnedNoticeHook)
|
||||
case boil.AfterDeleteHook:
|
||||
pinnedNoticeAfterDeleteHooks = append(pinnedNoticeAfterDeleteHooks, pinnedNoticeHook)
|
||||
case boil.AfterUpsertHook:
|
||||
pinnedNoticeAfterUpsertHooks = append(pinnedNoticeAfterUpsertHooks, pinnedNoticeHook)
|
||||
}
|
||||
}
|
||||
|
||||
// One returns a single pinnedNotice record from the query.
|
||||
func (q pinnedNoticeQuery) One(ctx context.Context, exec boil.ContextExecutor) (*PinnedNotice, error) {
|
||||
o := &PinnedNotice{}
|
||||
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Bind(ctx, exec, o)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "models: failed to execute a one query for pinned_notices")
|
||||
}
|
||||
|
||||
if err := o.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// All returns all PinnedNotice records from the query.
|
||||
func (q pinnedNoticeQuery) All(ctx context.Context, exec boil.ContextExecutor) (PinnedNoticeSlice, error) {
|
||||
var o []*PinnedNotice
|
||||
|
||||
err := q.Bind(ctx, exec, &o)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "models: failed to assign all query results to PinnedNotice slice")
|
||||
}
|
||||
|
||||
if len(pinnedNoticeAfterSelectHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterSelectHooks(ctx, exec); err != nil {
|
||||
return o, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return o, nil
|
||||
}
|
||||
|
||||
// Count returns the count of all PinnedNotice records in the query.
|
||||
func (q pinnedNoticeQuery) Count(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to count pinned_notices rows")
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// Exists checks if the row exists in the table.
|
||||
func (q pinnedNoticeQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (bool, error) {
|
||||
var count int64
|
||||
|
||||
queries.SetSelect(q.Query, nil)
|
||||
queries.SetCount(q.Query)
|
||||
queries.SetLimit(q.Query, 1)
|
||||
|
||||
err := q.Query.QueryRowContext(ctx, exec).Scan(&count)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "models: failed to check if pinned_notices exists")
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
// Notice pointed to by the foreign key.
|
||||
func (o *PinnedNotice) Notice(mods ...qm.QueryMod) noticeQuery {
|
||||
queryMods := []qm.QueryMod{
|
||||
qm.Where("\"id\" = ?", o.NoticeID),
|
||||
}
|
||||
|
||||
queryMods = append(queryMods, mods...)
|
||||
|
||||
query := Notices(queryMods...)
|
||||
queries.SetFrom(query.Query, "\"notices\"")
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
// LoadNotice allows an eager lookup of values, cached into the
|
||||
// loaded structs of the objects. This is for an N-1 relationship.
|
||||
func (pinnedNoticeL) LoadNotice(ctx context.Context, e boil.ContextExecutor, singular bool, maybePinnedNotice interface{}, mods queries.Applicator) error {
|
||||
var slice []*PinnedNotice
|
||||
var object *PinnedNotice
|
||||
|
||||
if singular {
|
||||
object = maybePinnedNotice.(*PinnedNotice)
|
||||
} else {
|
||||
slice = *maybePinnedNotice.(*[]*PinnedNotice)
|
||||
}
|
||||
|
||||
args := make([]interface{}, 0, 1)
|
||||
if singular {
|
||||
if object.R == nil {
|
||||
object.R = &pinnedNoticeR{}
|
||||
}
|
||||
args = append(args, object.NoticeID)
|
||||
|
||||
} else {
|
||||
Outer:
|
||||
for _, obj := range slice {
|
||||
if obj.R == nil {
|
||||
obj.R = &pinnedNoticeR{}
|
||||
}
|
||||
|
||||
for _, a := range args {
|
||||
if a == obj.NoticeID {
|
||||
continue Outer
|
||||
}
|
||||
}
|
||||
|
||||
args = append(args, obj.NoticeID)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if len(args) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
query := NewQuery(
|
||||
qm.From(`notices`),
|
||||
qm.WhereIn(`notices.id in ?`, args...),
|
||||
)
|
||||
if mods != nil {
|
||||
mods.Apply(query)
|
||||
}
|
||||
|
||||
results, err := query.QueryContext(ctx, e)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to eager load Notice")
|
||||
}
|
||||
|
||||
var resultSlice []*Notice
|
||||
if err = queries.Bind(results, &resultSlice); err != nil {
|
||||
return errors.Wrap(err, "failed to bind eager loaded slice Notice")
|
||||
}
|
||||
|
||||
if err = results.Close(); err != nil {
|
||||
return errors.Wrap(err, "failed to close results of eager load for notices")
|
||||
}
|
||||
if err = results.Err(); err != nil {
|
||||
return errors.Wrap(err, "error occurred during iteration of eager loaded relations for notices")
|
||||
}
|
||||
|
||||
if len(pinnedNoticeAfterSelectHooks) != 0 {
|
||||
for _, obj := range resultSlice {
|
||||
if err := obj.doAfterSelectHooks(ctx, e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(resultSlice) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if singular {
|
||||
foreign := resultSlice[0]
|
||||
object.R.Notice = foreign
|
||||
if foreign.R == nil {
|
||||
foreign.R = ¬iceR{}
|
||||
}
|
||||
foreign.R.PinnedNotice = object
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, local := range slice {
|
||||
for _, foreign := range resultSlice {
|
||||
if local.NoticeID == foreign.ID {
|
||||
local.R.Notice = foreign
|
||||
if foreign.R == nil {
|
||||
foreign.R = ¬iceR{}
|
||||
}
|
||||
foreign.R.PinnedNotice = local
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetNotice of the pinnedNotice to the related item.
|
||||
// Sets o.R.Notice to related.
|
||||
// Adds o to related.R.PinnedNotice.
|
||||
func (o *PinnedNotice) SetNotice(ctx context.Context, exec boil.ContextExecutor, insert bool, related *Notice) error {
|
||||
var err error
|
||||
if insert {
|
||||
if err = related.Insert(ctx, exec, boil.Infer()); err != nil {
|
||||
return errors.Wrap(err, "failed to insert into foreign table")
|
||||
}
|
||||
}
|
||||
|
||||
updateQuery := fmt.Sprintf(
|
||||
"UPDATE \"pinned_notices\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 0, []string{"notice_id"}),
|
||||
strmangle.WhereClause("\"", "\"", 0, pinnedNoticePrimaryKeyColumns),
|
||||
)
|
||||
values := []interface{}{related.ID, o.Name, o.Language}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, updateQuery)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
|
||||
return errors.Wrap(err, "failed to update local table")
|
||||
}
|
||||
|
||||
o.NoticeID = related.ID
|
||||
if o.R == nil {
|
||||
o.R = &pinnedNoticeR{
|
||||
Notice: related,
|
||||
}
|
||||
} else {
|
||||
o.R.Notice = related
|
||||
}
|
||||
|
||||
if related.R == nil {
|
||||
related.R = ¬iceR{
|
||||
PinnedNotice: o,
|
||||
}
|
||||
} else {
|
||||
related.R.PinnedNotice = o
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PinnedNotices retrieves all the records using an executor.
|
||||
func PinnedNotices(mods ...qm.QueryMod) pinnedNoticeQuery {
|
||||
mods = append(mods, qm.From("\"pinned_notices\""))
|
||||
return pinnedNoticeQuery{NewQuery(mods...)}
|
||||
}
|
||||
|
||||
// FindPinnedNotice retrieves a single record by ID with an executor.
|
||||
// If selectCols is empty Find will return all columns.
|
||||
func FindPinnedNotice(ctx context.Context, exec boil.ContextExecutor, name string, language string, selectCols ...string) (*PinnedNotice, error) {
|
||||
pinnedNoticeObj := &PinnedNotice{}
|
||||
|
||||
sel := "*"
|
||||
if len(selectCols) > 0 {
|
||||
sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
|
||||
}
|
||||
query := fmt.Sprintf(
|
||||
"select %s from \"pinned_notices\" where \"name\"=? AND \"language\"=?", sel,
|
||||
)
|
||||
|
||||
q := queries.Raw(query, name, language)
|
||||
|
||||
err := q.Bind(ctx, exec, pinnedNoticeObj)
|
||||
if err != nil {
|
||||
if errors.Cause(err) == sql.ErrNoRows {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return nil, errors.Wrap(err, "models: unable to select from pinned_notices")
|
||||
}
|
||||
|
||||
return pinnedNoticeObj, nil
|
||||
}
|
||||
|
||||
// Insert a single record using an executor.
|
||||
// See boil.Columns.InsertColumnSet documentation to understand column list inference for inserts.
|
||||
func (o *PinnedNotice) Insert(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) error {
|
||||
if o == nil {
|
||||
return errors.New("models: no pinned_notices provided for insertion")
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
if err := o.doBeforeInsertHooks(ctx, exec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nzDefaults := queries.NonZeroDefaultSet(pinnedNoticeColumnsWithDefault, o)
|
||||
|
||||
key := makeCacheKey(columns, nzDefaults)
|
||||
pinnedNoticeInsertCacheMut.RLock()
|
||||
cache, cached := pinnedNoticeInsertCache[key]
|
||||
pinnedNoticeInsertCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl, returnColumns := columns.InsertColumnSet(
|
||||
pinnedNoticeAllColumns,
|
||||
pinnedNoticeColumnsWithDefault,
|
||||
pinnedNoticeColumnsWithoutDefault,
|
||||
nzDefaults,
|
||||
)
|
||||
|
||||
cache.valueMapping, err = queries.BindMapping(pinnedNoticeType, pinnedNoticeMapping, wl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.retMapping, err = queries.BindMapping(pinnedNoticeType, pinnedNoticeMapping, returnColumns)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(wl) != 0 {
|
||||
cache.query = fmt.Sprintf("INSERT INTO \"pinned_notices\" (\"%s\") %%sVALUES (%s)%%s", strings.Join(wl, "\",\""), strmangle.Placeholders(dialect.UseIndexPlaceholders, len(wl), 1, 1))
|
||||
} else {
|
||||
cache.query = "INSERT INTO \"pinned_notices\" %sDEFAULT VALUES%s"
|
||||
}
|
||||
|
||||
var queryOutput, queryReturning string
|
||||
|
||||
if len(cache.retMapping) != 0 {
|
||||
cache.retQuery = fmt.Sprintf("SELECT \"%s\" FROM \"pinned_notices\" WHERE %s", strings.Join(returnColumns, "\",\""), strmangle.WhereClause("\"", "\"", 0, pinnedNoticePrimaryKeyColumns))
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf(cache.query, queryOutput, queryReturning)
|
||||
}
|
||||
|
||||
value := reflect.Indirect(reflect.ValueOf(o))
|
||||
vals := queries.ValuesFromMapping(value, cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, vals)
|
||||
}
|
||||
_, err = exec.ExecContext(ctx, cache.query, vals...)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "models: unable to insert into pinned_notices")
|
||||
}
|
||||
|
||||
var identifierCols []interface{}
|
||||
|
||||
if len(cache.retMapping) == 0 {
|
||||
goto CacheNoHooks
|
||||
}
|
||||
|
||||
identifierCols = []interface{}{
|
||||
o.Name,
|
||||
o.Language,
|
||||
}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.retQuery)
|
||||
fmt.Fprintln(writer, identifierCols...)
|
||||
}
|
||||
err = exec.QueryRowContext(ctx, cache.retQuery, identifierCols...).Scan(queries.PtrsFromMapping(value, cache.retMapping)...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "models: unable to populate default values for pinned_notices")
|
||||
}
|
||||
|
||||
CacheNoHooks:
|
||||
if !cached {
|
||||
pinnedNoticeInsertCacheMut.Lock()
|
||||
pinnedNoticeInsertCache[key] = cache
|
||||
pinnedNoticeInsertCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return o.doAfterInsertHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// Update uses an executor to update the PinnedNotice.
|
||||
// See boil.Columns.UpdateColumnSet documentation to understand column list inference for updates.
|
||||
// Update does not automatically update the record in case of default values. Use .Reload() to refresh the records.
|
||||
func (o *PinnedNotice) Update(ctx context.Context, exec boil.ContextExecutor, columns boil.Columns) (int64, error) {
|
||||
var err error
|
||||
if err = o.doBeforeUpdateHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
key := makeCacheKey(columns, nil)
|
||||
pinnedNoticeUpdateCacheMut.RLock()
|
||||
cache, cached := pinnedNoticeUpdateCache[key]
|
||||
pinnedNoticeUpdateCacheMut.RUnlock()
|
||||
|
||||
if !cached {
|
||||
wl := columns.UpdateColumnSet(
|
||||
pinnedNoticeAllColumns,
|
||||
pinnedNoticePrimaryKeyColumns,
|
||||
)
|
||||
|
||||
if !columns.IsWhitelist() {
|
||||
wl = strmangle.SetComplement(wl, []string{"created_at"})
|
||||
}
|
||||
if len(wl) == 0 {
|
||||
return 0, errors.New("models: unable to update pinned_notices, could not build whitelist")
|
||||
}
|
||||
|
||||
cache.query = fmt.Sprintf("UPDATE \"pinned_notices\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 0, wl),
|
||||
strmangle.WhereClause("\"", "\"", 0, pinnedNoticePrimaryKeyColumns),
|
||||
)
|
||||
cache.valueMapping, err = queries.BindMapping(pinnedNoticeType, pinnedNoticeMapping, append(wl, pinnedNoticePrimaryKeyColumns...))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, cache.query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
var result sql.Result
|
||||
result, err = exec.ExecContext(ctx, cache.query, values...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to update pinned_notices row")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by update for pinned_notices")
|
||||
}
|
||||
|
||||
if !cached {
|
||||
pinnedNoticeUpdateCacheMut.Lock()
|
||||
pinnedNoticeUpdateCache[key] = cache
|
||||
pinnedNoticeUpdateCacheMut.Unlock()
|
||||
}
|
||||
|
||||
return rowsAff, o.doAfterUpdateHooks(ctx, exec)
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values.
|
||||
func (q pinnedNoticeQuery) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
queries.SetUpdate(q.Query, cols)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to update all for pinned_notices")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to retrieve rows affected for pinned_notices")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// UpdateAll updates all rows with the specified column values, using an executor.
|
||||
func (o PinnedNoticeSlice) UpdateAll(ctx context.Context, exec boil.ContextExecutor, cols M) (int64, error) {
|
||||
ln := int64(len(o))
|
||||
if ln == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(cols) == 0 {
|
||||
return 0, errors.New("models: update all requires at least one column argument")
|
||||
}
|
||||
|
||||
colNames := make([]string, len(cols))
|
||||
args := make([]interface{}, len(cols))
|
||||
|
||||
i := 0
|
||||
for name, value := range cols {
|
||||
colNames[i] = name
|
||||
args[i] = value
|
||||
i++
|
||||
}
|
||||
|
||||
// Append all of the primary key values for each column
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), pinnedNoticePrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("UPDATE \"pinned_notices\" SET %s WHERE %s",
|
||||
strmangle.SetParamNames("\"", "\"", 0, colNames),
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, pinnedNoticePrimaryKeyColumns, len(o)))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to update all in pinnedNotice slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to retrieve rows affected all in update all pinnedNotice")
|
||||
}
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Delete deletes a single PinnedNotice record with an executor.
|
||||
// Delete will match against the primary key column to find the record to delete.
|
||||
func (o *PinnedNotice) Delete(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if o == nil {
|
||||
return 0, errors.New("models: no PinnedNotice provided for delete")
|
||||
}
|
||||
|
||||
if err := o.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), pinnedNoticePrimaryKeyMapping)
|
||||
sql := "DELETE FROM \"pinned_notices\" WHERE \"name\"=? AND \"language\"=?"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args...)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to delete from pinned_notices")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by delete for pinned_notices")
|
||||
}
|
||||
|
||||
if err := o.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all matching rows.
|
||||
func (q pinnedNoticeQuery) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if q.Query == nil {
|
||||
return 0, errors.New("models: no pinnedNoticeQuery provided for delete all")
|
||||
}
|
||||
|
||||
queries.SetDelete(q.Query)
|
||||
|
||||
result, err := q.Query.ExecContext(ctx, exec)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to delete all from pinned_notices")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for pinned_notices")
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// DeleteAll deletes all rows in the slice, using an executor.
|
||||
func (o PinnedNoticeSlice) DeleteAll(ctx context.Context, exec boil.ContextExecutor) (int64, error) {
|
||||
if len(o) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
if len(pinnedNoticeBeforeDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doBeforeDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var args []interface{}
|
||||
for _, obj := range o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), pinnedNoticePrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "DELETE FROM \"pinned_notices\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, pinnedNoticePrimaryKeyColumns, len(o))
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, args)
|
||||
}
|
||||
result, err := exec.ExecContext(ctx, sql, args...)
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: unable to delete all from pinnedNotice slice")
|
||||
}
|
||||
|
||||
rowsAff, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return 0, errors.Wrap(err, "models: failed to get rows affected by deleteall for pinned_notices")
|
||||
}
|
||||
|
||||
if len(pinnedNoticeAfterDeleteHooks) != 0 {
|
||||
for _, obj := range o {
|
||||
if err := obj.doAfterDeleteHooks(ctx, exec); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rowsAff, nil
|
||||
}
|
||||
|
||||
// Reload refetches the object from the database
|
||||
// using the primary keys with an executor.
|
||||
func (o *PinnedNotice) Reload(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
ret, err := FindPinnedNotice(ctx, exec, o.Name, o.Language)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*o = *ret
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReloadAll refetches every row with matching primary key column values
|
||||
// and overwrites the original object slice with the newly updated slice.
|
||||
func (o *PinnedNoticeSlice) ReloadAll(ctx context.Context, exec boil.ContextExecutor) error {
|
||||
if o == nil || len(*o) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
slice := PinnedNoticeSlice{}
|
||||
var args []interface{}
|
||||
for _, obj := range *o {
|
||||
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), pinnedNoticePrimaryKeyMapping)
|
||||
args = append(args, pkeyArgs...)
|
||||
}
|
||||
|
||||
sql := "SELECT \"pinned_notices\".* FROM \"pinned_notices\" WHERE " +
|
||||
strmangle.WhereClauseRepeated(string(dialect.LQ), string(dialect.RQ), 0, pinnedNoticePrimaryKeyColumns, len(*o))
|
||||
|
||||
q := queries.Raw(sql, args...)
|
||||
|
||||
err := q.Bind(ctx, exec, &slice)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "models: unable to reload all in PinnedNoticeSlice")
|
||||
}
|
||||
|
||||
*o = slice
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PinnedNoticeExists checks if the PinnedNotice row exists.
|
||||
func PinnedNoticeExists(ctx context.Context, exec boil.ContextExecutor, name string, language string) (bool, error) {
|
||||
var exists bool
|
||||
sql := "select exists(select 1 from \"pinned_notices\" where \"name\"=? AND \"language\"=? limit 1)"
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, sql)
|
||||
fmt.Fprintln(writer, name, language)
|
||||
}
|
||||
row := exec.QueryRowContext(ctx, sql, name, language)
|
||||
|
||||
err := row.Scan(&exists)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "models: unable to check if pinned_notices exists")
|
||||
}
|
||||
|
||||
return exists, nil
|
||||
}
|
|
@ -23,6 +23,9 @@ type Database struct {
|
|||
|
||||
AllowList admindb.AllowListService
|
||||
Aliases admindb.AliasService
|
||||
|
||||
PinnedNotices admindb.PinnedNoticesService
|
||||
Notices admindb.NoticesService
|
||||
}
|
||||
|
||||
// Open looks for a database file 'fname'
|
||||
|
@ -55,11 +58,13 @@ func Open(r repo.Interface) (*Database, error) {
|
|||
}
|
||||
|
||||
admindb := &Database{
|
||||
db: db,
|
||||
AuthWithSSB: AuthWithSSB{db},
|
||||
AuthFallback: AuthFallback{db},
|
||||
AllowList: AllowList{db},
|
||||
Aliases: Aliases{db},
|
||||
db: db,
|
||||
AuthWithSSB: AuthWithSSB{db},
|
||||
AuthFallback: AuthFallback{db},
|
||||
AllowList: AllowList{db},
|
||||
Aliases: Aliases{db},
|
||||
PinnedNotices: PinnedNotices{db},
|
||||
Notices: Notices{db},
|
||||
}
|
||||
|
||||
return admindb, nil
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb/sqlite/models"
|
||||
)
|
||||
|
||||
// make sure to implement interfaces correctly
|
||||
var _ admindb.PinnedNoticesService = (*PinnedNotices)(nil)
|
||||
|
||||
type PinnedNotices struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (pndb PinnedNotices) Set(name admindb.PinnedNoticeName, pageID int64, lang string) error {
|
||||
if !name.Valid() {
|
||||
return fmt.Errorf("fixed pages: invalid page name: %s", name)
|
||||
}
|
||||
|
||||
return fmt.Errorf("TODO: set fixed page %s to %d:%s", name, pageID, lang)
|
||||
}
|
||||
|
||||
// make sure to implement interfaces correctly
|
||||
var _ admindb.NoticesService = (*Notices)(nil)
|
||||
|
||||
type Notices struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (ndb Notices) GetByID(ctx context.Context, id int64) (admindb.Notice, error) {
|
||||
var n admindb.Notice
|
||||
|
||||
dbEntry, err := models.FindNotice(ctx, ndb.db, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return n, admindb.ErrNotFound
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// convert models type to admindb type
|
||||
n.ID = dbEntry.ID
|
||||
n.Title = dbEntry.Title
|
||||
n.Language = dbEntry.Language
|
||||
n.Content = dbEntry.Content
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
func (ndb Notices) RemoveID(ctx context.Context, id int64) error {
|
||||
dbEntry, err := models.FindNotice(ctx, ndb.db, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return admindb.ErrNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = dbEntry.Delete(ctx, ndb.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ndb Notices) Save(ctx context.Context, p *admindb.Notice) error {
|
||||
if p.ID == 0 {
|
||||
var newEntry models.Notice
|
||||
newEntry.Title = p.Title
|
||||
newEntry.Content = p.Content
|
||||
newEntry.Language = p.Language
|
||||
err := newEntry.Insert(ctx, ndb.db, boil.Whitelist("title", "content", "language"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
p.ID = newEntry.ID
|
||||
return nil
|
||||
}
|
||||
|
||||
var existing models.Notice
|
||||
existing.ID = p.ID
|
||||
existing.Title = p.Title
|
||||
existing.Content = p.Content
|
||||
existing.Language = p.Language
|
||||
_, err := existing.Update(ctx, ndb.db, boil.Whitelist("title", "content", "language"))
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return admindb.ErrNotFound
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package sqlite
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/internal/repo"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNoticesCRUD(t *testing.T) {
|
||||
r := require.New(t)
|
||||
ctx := context.Background()
|
||||
|
||||
testRepo := filepath.Join("testrun", t.Name())
|
||||
os.RemoveAll(testRepo)
|
||||
|
||||
tr := repo.New(testRepo)
|
||||
|
||||
db, err := Open(tr)
|
||||
r.NoError(err)
|
||||
|
||||
// boil.DebugWriter = os.Stderr
|
||||
// boil.DebugMode = true
|
||||
|
||||
t.Run("not found", func(t *testing.T) {
|
||||
r := require.New(t)
|
||||
|
||||
_, err = db.Notices.GetByID(ctx, 9999)
|
||||
r.Error(err)
|
||||
r.EqualError(err, admindb.ErrNotFound.Error())
|
||||
|
||||
err = db.Notices.RemoveID(ctx, 9999)
|
||||
r.Error(err)
|
||||
r.EqualError(err, admindb.ErrNotFound.Error())
|
||||
})
|
||||
|
||||
t.Run("new and update", func(t *testing.T) {
|
||||
r := require.New(t)
|
||||
var n admindb.Notice
|
||||
|
||||
n.Title = fmt.Sprintf("Test notice %d", rand.Int())
|
||||
n.Content = `# This is **not** a test!`
|
||||
n.Language = "en-GB"
|
||||
|
||||
err := db.Notices.Save(ctx, &n)
|
||||
r.NoError(err, "failed to save")
|
||||
r.NotEqual(0, n.ID, "should have a fresh id")
|
||||
|
||||
got, err := db.Notices.GetByID(ctx, n.ID)
|
||||
r.NoError(err, "failed to get saved entry")
|
||||
r.Equal(n.Title, got.Title)
|
||||
r.Equal(n.ID, got.ID)
|
||||
r.Equal(n.Language, got.Language)
|
||||
|
||||
oldID := n.ID
|
||||
n.Title = fmt.Sprintf("Updated test notice %d", rand.Int())
|
||||
err = db.Notices.Save(ctx, &n)
|
||||
r.NoError(err, "failed to save")
|
||||
r.Equal(oldID, n.ID, "should have the same ID")
|
||||
|
||||
// be gone
|
||||
err = db.Notices.RemoveID(ctx, oldID)
|
||||
r.NoError(err)
|
||||
|
||||
_, err = db.Notices.GetByID(ctx, oldID)
|
||||
r.Error(err)
|
||||
r.EqualError(err, admindb.ErrNotFound.Error())
|
||||
})
|
||||
}
|
|
@ -62,3 +62,31 @@ func (r *DBFeedRef) Scan(src interface{}) error {
|
|||
func (r DBFeedRef) Value() (driver.Value, error) {
|
||||
return driver.Value(r.Ref()), nil
|
||||
}
|
||||
|
||||
// PinnedNoticeName holds a name of a well known part of the page with a fixed location.
|
||||
// These also double as the i18n labels.
|
||||
type PinnedNoticeName string
|
||||
|
||||
// These are the well known names that the room page will display
|
||||
const (
|
||||
NoticeDescription PinnedNoticeName = "NoticeDescription"
|
||||
NoticeNews PinnedNoticeName = "NoticeNews"
|
||||
NoticePrivacyPolicy PinnedNoticeName = "NoticePrivacyPolicy"
|
||||
NoticeCodeOfConduct PinnedNoticeName = "NoticeCodeOfConduct"
|
||||
)
|
||||
|
||||
// Valid returns true if the page name is well known.
|
||||
func (fpn PinnedNoticeName) Valid() bool {
|
||||
return fpn == NoticeNews ||
|
||||
fpn == NoticeDescription ||
|
||||
fpn == NoticePrivacyPolicy ||
|
||||
fpn == NoticeCodeOfConduct
|
||||
}
|
||||
|
||||
// Notice holds the title and content of a page that is user generated
|
||||
type Notice struct {
|
||||
ID int64
|
||||
Title string
|
||||
Content string
|
||||
Language string
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ func runroomsrv() error {
|
|||
db.AuthWithSSB,
|
||||
db.AuthFallback,
|
||||
db.AllowList,
|
||||
db.Notices,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create HTTPdashboard handler: %w", err)
|
||||
|
|
2
go.mod
2
go.mod
|
@ -18,7 +18,7 @@ require (
|
|||
github.com/nicksnyder/go-i18n/v2 v2.1.2
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0
|
||||
github.com/stretchr/testify v1.6.1
|
||||
github.com/unrolled/secure v1.0.8
|
||||
github.com/vcraescu/go-paginator/v2 v2.0.0
|
||||
|
|
6
go.sum
6
go.sum
|
@ -347,8 +347,11 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
|||
github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.4.0 h1:LUa41nrWTQNGhzdsZ5lTnkwbNjj6rXTdazA1cSdjkOY=
|
||||
github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
|
@ -357,9 +360,8 @@ github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxr
|
|||
github.com/shurcooL/go v0.0.0-20190121191506-3fef8c783dec/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go v0.0.0-20190330031554-6713ea532688/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b h1:4kg1wyftSKxLtnPAvcRWakIPpokB9w780/KwrNLnfPA=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190527155220-6a4d4a70508b/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
|
||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||
|
|
|
@ -151,7 +151,7 @@ func (h allowListH) removeConfirm(rw http.ResponseWriter, req *http.Request) (in
|
|||
func (h allowListH) remove(rw http.ResponseWriter, req *http.Request) {
|
||||
err := req.ParseForm()
|
||||
if err != nil {
|
||||
err = weberrors.ErrBadRequest{Where: "ID", Details: err}
|
||||
err = weberrors.ErrBadRequest{Where: "Form data", Details: err}
|
||||
// TODO "flash" errors
|
||||
http.Redirect(rw, req, redirectTo, http.StatusFound)
|
||||
return
|
||||
|
|
|
@ -17,14 +17,23 @@ import (
|
|||
var HTMLTemplates = []string{
|
||||
"admin/dashboard.tmpl",
|
||||
"admin/menu.tmpl",
|
||||
|
||||
"admin/allow-list.tmpl",
|
||||
"admin/allow-list-remove-confirm.tmpl",
|
||||
|
||||
"admin/notice-edit.tmpl",
|
||||
}
|
||||
|
||||
// Handler supplies the elevated access pages to known users.
|
||||
// It is not registering on the mux router like other pages to clean up the authorize flow.
|
||||
func Handler(r *render.Renderer, roomState *roomstate.Manager, al admindb.AllowListService) http.Handler {
|
||||
func Handler(
|
||||
r *render.Renderer,
|
||||
roomState *roomstate.Manager,
|
||||
al admindb.AllowListService,
|
||||
ndb admindb.NoticesService,
|
||||
) http.Handler {
|
||||
mux := &http.ServeMux{}
|
||||
// TODO: configure 404 handler
|
||||
|
||||
mux.HandleFunc("/dashboard", r.HTML("admin/dashboard.tmpl", func(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
lst := roomState.List()
|
||||
|
@ -47,6 +56,13 @@ func Handler(r *render.Renderer, roomState *roomstate.Manager, al admindb.AllowL
|
|||
mux.HandleFunc("/members/remove/confirm", r.HTML("admin/allow-list-remove-confirm.tmpl", ah.removeConfirm))
|
||||
mux.HandleFunc("/members/remove", ah.remove)
|
||||
|
||||
var nh = noticeHandler{
|
||||
r: r,
|
||||
db: ndb,
|
||||
}
|
||||
mux.HandleFunc("/notice/edit", r.HTML("admin/notice-edit.tmpl", nh.edit))
|
||||
mux.HandleFunc("/notice/save", nh.save)
|
||||
|
||||
return customStripPrefix("/admin", mux)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package admin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/csrf"
|
||||
"github.com/russross/blackfriday/v2"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
weberrors "github.com/ssb-ngi-pointer/go-ssb-room/web/errors"
|
||||
"go.mindeco.de/http/render"
|
||||
)
|
||||
|
||||
type noticeHandler struct {
|
||||
r *render.Renderer
|
||||
|
||||
db admindb.NoticesService
|
||||
}
|
||||
|
||||
func (nh noticeHandler) edit(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
id, err := strconv.ParseInt(req.URL.Query().Get("id"), 10, 64)
|
||||
if err != nil {
|
||||
err = weberrors.ErrBadRequest{Where: "ID", Details: err}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
n, err := nh.db.GetByID(req.Context(), id)
|
||||
if err != nil {
|
||||
if errors.Is(err, admindb.ErrNotFound) {
|
||||
http.Redirect(rw, req, redirectTo, http.StatusFound)
|
||||
return nil, ErrRedirected
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// https://github.com/russross/blackfriday/issues/575
|
||||
fixedContent := strings.Replace(n.Content, "\r\n", "\n", -1)
|
||||
|
||||
contentBytes := []byte(fixedContent)
|
||||
preview := blackfriday.Run(contentBytes)
|
||||
|
||||
return map[string]interface{}{
|
||||
"Notice": n,
|
||||
"ContentPreview": template.HTML(preview),
|
||||
// "Debug": string(preview),
|
||||
// "DebugHex": hex.Dump(contentBytes),
|
||||
csrf.TemplateTag: csrf.TemplateField(req),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (nh noticeHandler) save(rw http.ResponseWriter, req *http.Request) {
|
||||
err := req.ParseForm()
|
||||
if err != nil {
|
||||
err = weberrors.ErrBadRequest{Where: "form data", Details: err}
|
||||
nh.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
redirect := req.FormValue("redirect")
|
||||
if redirect == "" {
|
||||
redirect = "/"
|
||||
}
|
||||
|
||||
var n admindb.Notice
|
||||
n.ID, err = strconv.ParseInt(req.FormValue("id"), 10, 64)
|
||||
if err != nil {
|
||||
err = weberrors.ErrBadRequest{Where: "id", Details: err}
|
||||
nh.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
n.Title = req.FormValue("title")
|
||||
|
||||
n.Content = req.FormValue("content")
|
||||
// https://github.com/russross/blackfriday/issues/575
|
||||
n.Content = strings.Replace(n.Content, "\r\n", "\n", -1)
|
||||
|
||||
err = nh.db.Save(req.Context(), &n)
|
||||
if err != nil {
|
||||
nh.r.Error(rw, req, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: update langauge
|
||||
|
||||
http.Redirect(rw, req, redirect, http.StatusTemporaryRedirect)
|
||||
}
|
|
@ -25,6 +25,13 @@ import (
|
|||
"github.com/ssb-ngi-pointer/go-ssb-room/web/router"
|
||||
)
|
||||
|
||||
var HTMLTempaltes = []string{
|
||||
"landing/index.tmpl",
|
||||
"landing/about.tmpl",
|
||||
"notice.tmpl",
|
||||
"error.tmpl",
|
||||
}
|
||||
|
||||
// New initializes the whole web stack for rooms, with all the sub-modules and routing.
|
||||
func New(
|
||||
logger logging.Interface,
|
||||
|
@ -33,6 +40,7 @@ func New(
|
|||
as admindb.AuthWithSSBService,
|
||||
fs admindb.AuthFallbackService,
|
||||
al admindb.AllowListService,
|
||||
ns admindb.NoticesService,
|
||||
) (http.Handler, error) {
|
||||
m := router.CompleteApp()
|
||||
|
||||
|
@ -47,11 +55,7 @@ func New(
|
|||
render.SetLogger(logger),
|
||||
render.BaseTemplates("base.tmpl", "menu.tmpl"),
|
||||
render.AddTemplates(concatTemplates(
|
||||
[]string{
|
||||
"landing/index.tmpl",
|
||||
"landing/about.tmpl",
|
||||
"error.tmpl",
|
||||
},
|
||||
HTMLTempaltes,
|
||||
news.HTMLTemplates,
|
||||
roomsAuth.HTMLTemplates,
|
||||
admin.HTMLTemplates,
|
||||
|
@ -189,12 +193,16 @@ func New(
|
|||
news.Handler(m, r)
|
||||
roomsAuth.Handler(m, r, a)
|
||||
|
||||
adminHandler := a.Authenticate(admin.Handler(r, roomState, al))
|
||||
adminHandler := a.Authenticate(admin.Handler(r, roomState, al, ns))
|
||||
mainMux.Handle("/admin/", adminHandler)
|
||||
|
||||
m.Get(router.CompleteIndex).Handler(r.StaticHTML("landing/index.tmpl"))
|
||||
m.Get(router.CompleteAbout).Handler(r.StaticHTML("landing/about.tmpl"))
|
||||
|
||||
var nr noticeRenderer
|
||||
nr.notices = ns
|
||||
m.Get(router.CompleteNotice).Handler(r.HTML("notice.tmpl", nr.render))
|
||||
|
||||
m.PathPrefix("/assets/").Handler(http.StripPrefix("/assets/", http.FileServer(web.Assets)))
|
||||
|
||||
m.NotFoundHandler = r.HTML("error.tmpl", func(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/russross/blackfriday/v2"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/web/errors"
|
||||
)
|
||||
|
||||
type noticeRenderer struct {
|
||||
notices admindb.NoticesService
|
||||
}
|
||||
|
||||
type noticeData struct {
|
||||
ID int64
|
||||
Title, Language string
|
||||
Content template.HTML
|
||||
}
|
||||
|
||||
func (pr noticeRenderer) render(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
noticeID, err := strconv.ParseInt(req.URL.Query().Get("id"), 10, 64)
|
||||
if err != nil {
|
||||
return nil, errors.ErrBadRequest{Where: "notice ID", Details: err}
|
||||
}
|
||||
|
||||
notice, err := pr.notices.GetByID(req.Context(), noticeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
markdown := blackfriday.Run([]byte(notice.Content), blackfriday.WithNoExtensions())
|
||||
|
||||
return noticeData{
|
||||
ID: noticeID,
|
||||
Title: notice.Title,
|
||||
Content: template.HTML(markdown),
|
||||
Language: notice.Language,
|
||||
}, nil
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
Confirm = "Confirm"
|
||||
Save = "Save"
|
||||
Preview = "Preview"
|
||||
PageNotFound = "The requested page was not found."
|
||||
|
||||
LandingTitle = "ohai my room"
|
||||
|
@ -33,6 +35,8 @@ description = "Number of members"
|
|||
one = "1 member"
|
||||
other = "{{.Count}} members"
|
||||
|
||||
NoticeEditTitle = "Edit Notice"
|
||||
|
||||
[ListCount]
|
||||
description = "generic list"
|
||||
one = "There is one item on the List"
|
||||
|
|
|
@ -13,6 +13,9 @@ const (
|
|||
AdminAllowListAdd = "admin:allow-list:add"
|
||||
AdminAllowListRemoveConfirm = "admin:allow-list:remove:confirm"
|
||||
AdminAllowListRemove = "admin:allow-list:remove"
|
||||
|
||||
AdminNoticeEdit = "admin:notice:edit"
|
||||
AdminNoticeSave = "admin:notice:save"
|
||||
)
|
||||
|
||||
// Admin constructs a mux.Router containing the routes for the admin dashboard and settings pages
|
||||
|
@ -29,5 +32,8 @@ func Admin(m *mux.Router) *mux.Router {
|
|||
m.Path("/members/remove/confirm").Methods("GET").Name(AdminAllowListRemoveConfirm)
|
||||
m.Path("/members/remove").Methods("POST").Name(AdminAllowListRemove)
|
||||
|
||||
m.Path("/notice/edit").Methods("GET").Name(AdminNoticeEdit)
|
||||
m.Path("/notice/save").Methods("POST").Name(AdminNoticeSave)
|
||||
|
||||
return m
|
||||
}
|
||||
|
|
|
@ -8,8 +8,9 @@ import (
|
|||
|
||||
// constant names for the named routes
|
||||
const (
|
||||
CompleteIndex = "complete:index"
|
||||
CompleteAbout = "complete:about"
|
||||
CompleteIndex = "complete:index"
|
||||
CompleteAbout = "complete:about"
|
||||
CompleteNotice = "complete:notice"
|
||||
)
|
||||
|
||||
// CompleteApp constructs a mux.Router containing the routes for batch Complete html frontend
|
||||
|
@ -22,6 +23,7 @@ func CompleteApp() *mux.Router {
|
|||
|
||||
m.Path("/").Methods("GET").Name(CompleteIndex)
|
||||
m.Path("/about").Methods("GET").Name(CompleteAbout)
|
||||
m.Path("/notice").Methods("GET").Name(CompleteNotice)
|
||||
|
||||
return m
|
||||
}
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
{{ define "title" }}{{i18n "NoticeEditTitle"}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div id="page-header">
|
||||
<h1 id="welcome" class="text-lg">{{i18n "NoticeEditTitle"}}: <small>{{.Notice.Title}}<small></h1>
|
||||
</div>
|
||||
<div class="">
|
||||
<form method="POST" action={{urlTo "admin:notice:save" }} class="flex flex-row items-end">
|
||||
{{ .csrfField }}
|
||||
<input
|
||||
type="hidden"
|
||||
name="id"
|
||||
value="{{.Notice.ID}}">
|
||||
<input
|
||||
type="hidden"
|
||||
name="redirect"
|
||||
value="{{urlTo "admin:notice:edit" "id" .Notice.ID}}">
|
||||
<div class="w-96 grid grid-cols-2 gap-x-4 gap-y-1 mr-4">
|
||||
<label>Title</label>
|
||||
<input
|
||||
type="text"
|
||||
name="title"
|
||||
value="{{.Notice.Title}}"
|
||||
class="shadow rounded border border-transparent h-8 p-1 focus:outline-none focus:ring-2 focus:ring-pink-400 focus:border-transparent">
|
||||
<textarea
|
||||
name="content"
|
||||
id="notice-content"
|
||||
rows="10"
|
||||
cols="20"
|
||||
class="resize border rounded-md"
|
||||
>{{.Notice.Content}}</textarea>
|
||||
<p class="text:red">TODO: language dropdown</p>
|
||||
</div>
|
||||
<button
|
||||
type="submit"
|
||||
class="shadow rounded px-4 h-8 text-gray-100 bg-pink-600 hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-600 focus:ring-opacity-50"
|
||||
>{{i18n "Save"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<h1>{{i18n "Preview"}}</h1>
|
||||
{{.ContentPreview}}
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div>
|
||||
<h1>Debug</h1>
|
||||
<pre>{{.Debug}}</pre>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h1>Debug Input</h1>
|
||||
<pre>{{.DebugHex}}</pre>
|
||||
</div>
|
||||
-->
|
||||
|
||||
{{end}}
|
|
@ -40,5 +40,4 @@
|
|||
suspendisse in est ante in. Imperdiet nulla malesuada pellentesque elit. Ut faucibus pulvinar elementum integer enim
|
||||
neque. Consequat semper viverra nam libero justo laoreet.</p>
|
||||
</div>
|
||||
</div> <!-- /row -->
|
||||
{{end}}
|
|
@ -0,0 +1,18 @@
|
|||
{{ define "title" }}{{.Title}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div class="container mx-auto">
|
||||
<h1 class="text-lg">{{.Title}}</h1>
|
||||
|
||||
{{.Content}}
|
||||
|
||||
<br>
|
||||
<span>{{.Language}}</span>
|
||||
|
||||
{{if is_logged_in}}
|
||||
<a
|
||||
href="{{urlTo "admin:notice:edit" "id" .ID}}"
|
||||
class="shadow rounded px-4 h-8 text-gray-100 bg-pink-600 hover:bg-pink-700 focus:outline-none focus:ring-2 focus:ring-pink-600 focus:ring-opacity-50"
|
||||
>{{i18n "NoticeEditTitle"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
Loading…
Reference in New Issue