list, set and get pinned notices
This commit is contained in:
parent
e5a07fd8bc
commit
1ec3e8b064
|
@ -48,14 +48,19 @@ type AllowListService interface {
|
|||
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 {
|
||||
// List returns a list of all the pinned notices with their corrosponding notices and languges
|
||||
List(context.Context) (PinnedNotices, error)
|
||||
|
||||
// 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
|
||||
Set(ctx context.Context, name PinnedNoticeName, id int64) error
|
||||
|
||||
// Get returns a single notice for a name and a language
|
||||
Get(ctx context.Context, name PinnedNoticeName, language string) (*Notice, error)
|
||||
}
|
||||
|
||||
// NoticesService is the low level store to manage single notices
|
||||
type NoticesService interface {
|
||||
// GetByID returns the page for that ID or an error
|
||||
GetByID(context.Context, int64) (Notice, error)
|
||||
|
|
|
@ -2,18 +2,47 @@
|
|||
package mockdb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
)
|
||||
|
||||
type FakePinnedNoticesService struct {
|
||||
SetStub func(admindb.PinnedNoticeName, int64, string) error
|
||||
GetStub func(context.Context, admindb.PinnedNoticeName, string) (*admindb.Notice, error)
|
||||
getMutex sync.RWMutex
|
||||
getArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 admindb.PinnedNoticeName
|
||||
arg3 string
|
||||
}
|
||||
getReturns struct {
|
||||
result1 *admindb.Notice
|
||||
result2 error
|
||||
}
|
||||
getReturnsOnCall map[int]struct {
|
||||
result1 *admindb.Notice
|
||||
result2 error
|
||||
}
|
||||
ListStub func(context.Context) (admindb.PinnedNotices, error)
|
||||
listMutex sync.RWMutex
|
||||
listArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
}
|
||||
listReturns struct {
|
||||
result1 admindb.PinnedNotices
|
||||
result2 error
|
||||
}
|
||||
listReturnsOnCall map[int]struct {
|
||||
result1 admindb.PinnedNotices
|
||||
result2 error
|
||||
}
|
||||
SetStub func(context.Context, admindb.PinnedNoticeName, int64) error
|
||||
setMutex sync.RWMutex
|
||||
setArgsForCall []struct {
|
||||
arg1 admindb.PinnedNoticeName
|
||||
arg2 int64
|
||||
arg3 string
|
||||
arg1 context.Context
|
||||
arg2 admindb.PinnedNoticeName
|
||||
arg3 int64
|
||||
}
|
||||
setReturns struct {
|
||||
result1 error
|
||||
|
@ -25,13 +54,143 @@ type FakePinnedNoticesService struct {
|
|||
invocationsMutex sync.RWMutex
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) Set(arg1 admindb.PinnedNoticeName, arg2 int64, arg3 string) error {
|
||||
func (fake *FakePinnedNoticesService) Get(arg1 context.Context, arg2 admindb.PinnedNoticeName, arg3 string) (*admindb.Notice, error) {
|
||||
fake.getMutex.Lock()
|
||||
ret, specificReturn := fake.getReturnsOnCall[len(fake.getArgsForCall)]
|
||||
fake.getArgsForCall = append(fake.getArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 admindb.PinnedNoticeName
|
||||
arg3 string
|
||||
}{arg1, arg2, arg3})
|
||||
stub := fake.GetStub
|
||||
fakeReturns := fake.getReturns
|
||||
fake.recordInvocation("Get", []interface{}{arg1, arg2, arg3})
|
||||
fake.getMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1, arg2, arg3)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) GetCallCount() int {
|
||||
fake.getMutex.RLock()
|
||||
defer fake.getMutex.RUnlock()
|
||||
return len(fake.getArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) GetCalls(stub func(context.Context, admindb.PinnedNoticeName, string) (*admindb.Notice, error)) {
|
||||
fake.getMutex.Lock()
|
||||
defer fake.getMutex.Unlock()
|
||||
fake.GetStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) GetArgsForCall(i int) (context.Context, admindb.PinnedNoticeName, string) {
|
||||
fake.getMutex.RLock()
|
||||
defer fake.getMutex.RUnlock()
|
||||
argsForCall := fake.getArgsForCall[i]
|
||||
return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) GetReturns(result1 *admindb.Notice, result2 error) {
|
||||
fake.getMutex.Lock()
|
||||
defer fake.getMutex.Unlock()
|
||||
fake.GetStub = nil
|
||||
fake.getReturns = struct {
|
||||
result1 *admindb.Notice
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) GetReturnsOnCall(i int, result1 *admindb.Notice, result2 error) {
|
||||
fake.getMutex.Lock()
|
||||
defer fake.getMutex.Unlock()
|
||||
fake.GetStub = nil
|
||||
if fake.getReturnsOnCall == nil {
|
||||
fake.getReturnsOnCall = make(map[int]struct {
|
||||
result1 *admindb.Notice
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.getReturnsOnCall[i] = struct {
|
||||
result1 *admindb.Notice
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) List(arg1 context.Context) (admindb.PinnedNotices, error) {
|
||||
fake.listMutex.Lock()
|
||||
ret, specificReturn := fake.listReturnsOnCall[len(fake.listArgsForCall)]
|
||||
fake.listArgsForCall = append(fake.listArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
}{arg1})
|
||||
stub := fake.ListStub
|
||||
fakeReturns := fake.listReturns
|
||||
fake.recordInvocation("List", []interface{}{arg1})
|
||||
fake.listMutex.Unlock()
|
||||
if stub != nil {
|
||||
return stub(arg1)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) ListCallCount() int {
|
||||
fake.listMutex.RLock()
|
||||
defer fake.listMutex.RUnlock()
|
||||
return len(fake.listArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) ListCalls(stub func(context.Context) (admindb.PinnedNotices, error)) {
|
||||
fake.listMutex.Lock()
|
||||
defer fake.listMutex.Unlock()
|
||||
fake.ListStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) ListArgsForCall(i int) context.Context {
|
||||
fake.listMutex.RLock()
|
||||
defer fake.listMutex.RUnlock()
|
||||
argsForCall := fake.listArgsForCall[i]
|
||||
return argsForCall.arg1
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) ListReturns(result1 admindb.PinnedNotices, result2 error) {
|
||||
fake.listMutex.Lock()
|
||||
defer fake.listMutex.Unlock()
|
||||
fake.ListStub = nil
|
||||
fake.listReturns = struct {
|
||||
result1 admindb.PinnedNotices
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) ListReturnsOnCall(i int, result1 admindb.PinnedNotices, result2 error) {
|
||||
fake.listMutex.Lock()
|
||||
defer fake.listMutex.Unlock()
|
||||
fake.ListStub = nil
|
||||
if fake.listReturnsOnCall == nil {
|
||||
fake.listReturnsOnCall = make(map[int]struct {
|
||||
result1 admindb.PinnedNotices
|
||||
result2 error
|
||||
})
|
||||
}
|
||||
fake.listReturnsOnCall[i] = struct {
|
||||
result1 admindb.PinnedNotices
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) Set(arg1 context.Context, arg2 admindb.PinnedNoticeName, arg3 int64) 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 context.Context
|
||||
arg2 admindb.PinnedNoticeName
|
||||
arg3 int64
|
||||
}{arg1, arg2, arg3})
|
||||
stub := fake.SetStub
|
||||
fakeReturns := fake.setReturns
|
||||
|
@ -52,13 +211,13 @@ func (fake *FakePinnedNoticesService) SetCallCount() int {
|
|||
return len(fake.setArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetCalls(stub func(admindb.PinnedNoticeName, int64, string) error) {
|
||||
func (fake *FakePinnedNoticesService) SetCalls(stub func(context.Context, admindb.PinnedNoticeName, int64) error) {
|
||||
fake.setMutex.Lock()
|
||||
defer fake.setMutex.Unlock()
|
||||
fake.SetStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakePinnedNoticesService) SetArgsForCall(i int) (admindb.PinnedNoticeName, int64, string) {
|
||||
func (fake *FakePinnedNoticesService) SetArgsForCall(i int) (context.Context, admindb.PinnedNoticeName, int64) {
|
||||
fake.setMutex.RLock()
|
||||
defer fake.setMutex.RUnlock()
|
||||
argsForCall := fake.setArgsForCall[i]
|
||||
|
@ -91,6 +250,10 @@ func (fake *FakePinnedNoticesService) SetReturnsOnCall(i int, result1 error) {
|
|||
func (fake *FakePinnedNoticesService) Invocations() map[string][][]interface{} {
|
||||
fake.invocationsMutex.RLock()
|
||||
defer fake.invocationsMutex.RUnlock()
|
||||
fake.getMutex.RLock()
|
||||
defer fake.getMutex.RUnlock()
|
||||
fake.listMutex.RLock()
|
||||
defer fake.listMutex.RUnlock()
|
||||
fake.setMutex.RLock()
|
||||
defer fake.setMutex.RUnlock()
|
||||
copiedInvocations := map[string][][]interface{}{}
|
||||
|
|
|
@ -35,19 +35,17 @@ type FakeNoticesService struct {
|
|||
removeIDReturnsOnCall map[int]struct {
|
||||
result1 error
|
||||
}
|
||||
SaveStub func(context.Context, admindb.Notice) (int64, error)
|
||||
SaveStub func(context.Context, *admindb.Notice) error
|
||||
saveMutex sync.RWMutex
|
||||
saveArgsForCall []struct {
|
||||
arg1 context.Context
|
||||
arg2 admindb.Notice
|
||||
arg2 *admindb.Notice
|
||||
}
|
||||
saveReturns struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
result1 error
|
||||
}
|
||||
saveReturnsOnCall map[int]struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
result1 error
|
||||
}
|
||||
invocations map[string][][]interface{}
|
||||
invocationsMutex sync.RWMutex
|
||||
|
@ -180,12 +178,12 @@ func (fake *FakeNoticesService) RemoveIDReturnsOnCall(i int, result1 error) {
|
|||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) Save(arg1 context.Context, arg2 admindb.Notice) (int64, error) {
|
||||
func (fake *FakeNoticesService) Save(arg1 context.Context, arg2 *admindb.Notice) error {
|
||||
fake.saveMutex.Lock()
|
||||
ret, specificReturn := fake.saveReturnsOnCall[len(fake.saveArgsForCall)]
|
||||
fake.saveArgsForCall = append(fake.saveArgsForCall, struct {
|
||||
arg1 context.Context
|
||||
arg2 admindb.Notice
|
||||
arg2 *admindb.Notice
|
||||
}{arg1, arg2})
|
||||
stub := fake.SaveStub
|
||||
fakeReturns := fake.saveReturns
|
||||
|
@ -195,9 +193,9 @@ func (fake *FakeNoticesService) Save(arg1 context.Context, arg2 admindb.Notice)
|
|||
return stub(arg1, arg2)
|
||||
}
|
||||
if specificReturn {
|
||||
return ret.result1, ret.result2
|
||||
return ret.result1
|
||||
}
|
||||
return fakeReturns.result1, fakeReturns.result2
|
||||
return fakeReturns.result1
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveCallCount() int {
|
||||
|
@ -206,43 +204,40 @@ func (fake *FakeNoticesService) SaveCallCount() int {
|
|||
return len(fake.saveArgsForCall)
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveCalls(stub func(context.Context, admindb.Notice) (int64, error)) {
|
||||
func (fake *FakeNoticesService) SaveCalls(stub func(context.Context, *admindb.Notice) error) {
|
||||
fake.saveMutex.Lock()
|
||||
defer fake.saveMutex.Unlock()
|
||||
fake.SaveStub = stub
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveArgsForCall(i int) (context.Context, admindb.Notice) {
|
||||
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) {
|
||||
func (fake *FakeNoticesService) SaveReturns(result1 error) {
|
||||
fake.saveMutex.Lock()
|
||||
defer fake.saveMutex.Unlock()
|
||||
fake.SaveStub = nil
|
||||
fake.saveReturns = struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) SaveReturnsOnCall(i int, result1 int64, result2 error) {
|
||||
func (fake *FakeNoticesService) SaveReturnsOnCall(i int, result1 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
|
||||
result1 error
|
||||
})
|
||||
}
|
||||
fake.saveReturnsOnCall[i] = struct {
|
||||
result1 int64
|
||||
result2 error
|
||||
}{result1, result2}
|
||||
result1 error
|
||||
}{result1}
|
||||
}
|
||||
|
||||
func (fake *FakeNoticesService) Invocations() map[string][][]interface{} {
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
-- +migrate Up
|
||||
CREATE TABLE pins (
|
||||
id integer NOT NULL PRIMARY KEY,
|
||||
name text NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE notices (
|
||||
id integer PRIMARY KEY AUTOINCREMENT NOT NULL,
|
||||
title text NOT NULL,
|
||||
|
@ -6,17 +12,24 @@ CREATE TABLE notices (
|
|||
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),
|
||||
-- n:m relation table
|
||||
CREATE TABLE pin_notices (
|
||||
notice_id integer NOT NULL,
|
||||
pin_id integer NOT NULL,
|
||||
|
||||
-- make sure the notices exist
|
||||
FOREIGN KEY ( notice_id ) REFERENCES notices( "id" )
|
||||
PRIMARY KEY (notice_id, pin_id),
|
||||
|
||||
FOREIGN KEY ( notice_id ) REFERENCES notices( "id" ),
|
||||
FOREIGN KEY ( pin_id ) REFERENCES pins( "id" )
|
||||
);
|
||||
|
||||
-- TODO: find a better way to insert the defaults
|
||||
INSERT INTO pins (name) VALUES
|
||||
('NoticeDescription'),
|
||||
('NoticeNews'),
|
||||
('NoticeCodeOfConduct'),
|
||||
('NoticePrivacyPolicy');
|
||||
|
||||
INSERT INTO notices (title, content, language) VALUES
|
||||
('Description', 'Basic description of this Room.', 'en-GB'),
|
||||
('News', 'Some recent updates...', 'en-GB'),
|
||||
|
@ -31,14 +44,15 @@ INSERT INTO notices (title, content, language) VALUES
|
|||
('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');
|
||||
INSERT INTO pin_notices (notice_id, pin_id) VALUES
|
||||
(1, 1),
|
||||
(2, 2),
|
||||
(3, 3),
|
||||
(4, 4),
|
||||
(5, 4),
|
||||
(6, 1);
|
||||
|
||||
-- +migrate Down
|
||||
DROP TABLE notices;
|
||||
DROP TABLE pinned_notices;
|
||||
DROP TABLE pins;
|
||||
DROP TABLE pin_notices;
|
|
@ -4,13 +4,15 @@
|
|||
package models
|
||||
|
||||
var TableNames = struct {
|
||||
AllowList string
|
||||
AuthFallback string
|
||||
Notices string
|
||||
PinnedNotices string
|
||||
AllowList string
|
||||
AuthFallback string
|
||||
Notices string
|
||||
PinNotices string
|
||||
Pins string
|
||||
}{
|
||||
AllowList: "allow_list",
|
||||
AuthFallback: "auth_fallback",
|
||||
Notices: "notices",
|
||||
PinnedNotices: "pinned_notices",
|
||||
AllowList: "allow_list",
|
||||
AuthFallback: "auth_fallback",
|
||||
Notices: "notices",
|
||||
PinNotices: "pin_notices",
|
||||
Pins: "pins",
|
||||
}
|
||||
|
|
|
@ -59,14 +59,14 @@ var NoticeWhere = struct {
|
|||
|
||||
// NoticeRels is where relationship names are stored.
|
||||
var NoticeRels = struct {
|
||||
PinnedNotice string
|
||||
Pins string
|
||||
}{
|
||||
PinnedNotice: "PinnedNotice",
|
||||
Pins: "Pins",
|
||||
}
|
||||
|
||||
// noticeR is where relationships are stored.
|
||||
type noticeR struct {
|
||||
PinnedNotice *PinnedNotice `boil:"PinnedNotice" json:"PinnedNotice" toml:"PinnedNotice" yaml:"PinnedNotice"`
|
||||
Pins PinSlice `boil:"Pins" json:"Pins" toml:"Pins" yaml:"Pins"`
|
||||
}
|
||||
|
||||
// NewStruct creates a new relationship struct
|
||||
|
@ -359,23 +359,31 @@ func (q noticeQuery) Exists(ctx context.Context, exec boil.ContextExecutor) (boo
|
|||
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),
|
||||
// Pins retrieves all the pin's Pins with an executor.
|
||||
func (o *Notice) Pins(mods ...qm.QueryMod) pinQuery {
|
||||
var queryMods []qm.QueryMod
|
||||
if len(mods) != 0 {
|
||||
queryMods = append(queryMods, mods...)
|
||||
}
|
||||
|
||||
queryMods = append(queryMods, mods...)
|
||||
queryMods = append(queryMods,
|
||||
qm.InnerJoin("\"pin_notices\" on \"pins\".\"id\" = \"pin_notices\".\"pin_id\""),
|
||||
qm.Where("\"pin_notices\".\"notice_id\"=?", o.ID),
|
||||
)
|
||||
|
||||
query := PinnedNotices(queryMods...)
|
||||
queries.SetFrom(query.Query, "\"pinned_notices\"")
|
||||
query := Pins(queryMods...)
|
||||
queries.SetFrom(query.Query, "\"pins\"")
|
||||
|
||||
if len(queries.GetSelect(query.Query)) == 0 {
|
||||
queries.SetSelect(query.Query, []string{"\"pins\".*"})
|
||||
}
|
||||
|
||||
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 {
|
||||
// LoadPins allows an eager lookup of values, cached into the
|
||||
// loaded structs of the objects. This is for a 1-M or N-M relationship.
|
||||
func (noticeL) LoadPins(ctx context.Context, e boil.ContextExecutor, singular bool, maybeNotice interface{}, mods queries.Applicator) error {
|
||||
var slice []*Notice
|
||||
var object *Notice
|
||||
|
||||
|
@ -413,8 +421,10 @@ func (noticeL) LoadPinnedNotice(ctx context.Context, e boil.ContextExecutor, sin
|
|||
}
|
||||
|
||||
query := NewQuery(
|
||||
qm.From(`pinned_notices`),
|
||||
qm.WhereIn(`pinned_notices.notice_id in ?`, args...),
|
||||
qm.Select("\"pins\".id, \"pins\".name, \"a\".\"notice_id\""),
|
||||
qm.From("\"pins\""),
|
||||
qm.InnerJoin("\"pin_notices\" as \"a\" on \"pins\".\"id\" = \"a\".\"pin_id\""),
|
||||
qm.WhereIn("\"a\".\"notice_id\" in ?", args...),
|
||||
)
|
||||
if mods != nil {
|
||||
mods.Apply(query)
|
||||
|
@ -422,50 +432,62 @@ func (noticeL) LoadPinnedNotice(ctx context.Context, e boil.ContextExecutor, sin
|
|||
|
||||
results, err := query.QueryContext(ctx, e)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to eager load PinnedNotice")
|
||||
return errors.Wrap(err, "failed to eager load pins")
|
||||
}
|
||||
|
||||
var resultSlice []*PinnedNotice
|
||||
if err = queries.Bind(results, &resultSlice); err != nil {
|
||||
return errors.Wrap(err, "failed to bind eager loaded slice PinnedNotice")
|
||||
var resultSlice []*Pin
|
||||
|
||||
var localJoinCols []int64
|
||||
for results.Next() {
|
||||
one := new(Pin)
|
||||
var localJoinCol int64
|
||||
|
||||
err = results.Scan(&one.ID, &one.Name, &localJoinCol)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to scan eager loaded results for pins")
|
||||
}
|
||||
if err = results.Err(); err != nil {
|
||||
return errors.Wrap(err, "failed to plebian-bind eager loaded slice pins")
|
||||
}
|
||||
|
||||
resultSlice = append(resultSlice, one)
|
||||
localJoinCols = append(localJoinCols, localJoinCol)
|
||||
}
|
||||
|
||||
if err = results.Close(); err != nil {
|
||||
return errors.Wrap(err, "failed to close results of eager load for pinned_notices")
|
||||
return errors.Wrap(err, "failed to close results in eager load on pins")
|
||||
}
|
||||
if err = results.Err(); err != nil {
|
||||
return errors.Wrap(err, "error occurred during iteration of eager loaded relations for pinned_notices")
|
||||
return errors.Wrap(err, "error occurred during iteration of eager loaded relations for pins")
|
||||
}
|
||||
|
||||
if len(noticeAfterSelectHooks) != 0 {
|
||||
if len(pinAfterSelectHooks) != 0 {
|
||||
for _, obj := range resultSlice {
|
||||
if err := obj.doAfterSelectHooks(ctx, e); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(resultSlice) == 0 {
|
||||
if singular {
|
||||
object.R.Pins = resultSlice
|
||||
for _, foreign := range resultSlice {
|
||||
if foreign.R == nil {
|
||||
foreign.R = &pinR{}
|
||||
}
|
||||
foreign.R.Notices = append(foreign.R.Notices, object)
|
||||
}
|
||||
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
|
||||
for i, foreign := range resultSlice {
|
||||
localJoinCol := localJoinCols[i]
|
||||
for _, local := range slice {
|
||||
if local.ID == localJoinCol {
|
||||
local.R.Pins = append(local.R.Pins, foreign)
|
||||
if foreign.R == nil {
|
||||
foreign.R = &pinnedNoticeR{}
|
||||
foreign.R = &pinR{}
|
||||
}
|
||||
foreign.R.Notice = local
|
||||
foreign.R.Notices = append(foreign.R.Notices, local)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
@ -474,57 +496,146 @@ func (noticeL) LoadPinnedNotice(ctx context.Context, e boil.ContextExecutor, sin
|
|||
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 {
|
||||
// AddPins adds the given related objects to the existing relationships
|
||||
// of the notice, optionally inserting them as new records.
|
||||
// Appends related to o.R.Pins.
|
||||
// Sets related.R.Notices appropriately.
|
||||
func (o *Notice) AddPins(ctx context.Context, exec boil.ContextExecutor, insert bool, related ...*Pin) 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")
|
||||
for _, rel := range related {
|
||||
if insert {
|
||||
if err = rel.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}
|
||||
}
|
||||
|
||||
for _, rel := range related {
|
||||
query := "insert into \"pin_notices\" (\"notice_id\", \"pin_id\") values (?, ?)"
|
||||
values := []interface{}{o.ID, rel.ID}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, updateQuery)
|
||||
fmt.Fprintln(writer, query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
if _, err = exec.ExecContext(ctx, updateQuery, values...); err != nil {
|
||||
return errors.Wrap(err, "failed to update foreign table")
|
||||
_, err = exec.ExecContext(ctx, query, values...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to insert into join table")
|
||||
}
|
||||
|
||||
related.NoticeID = o.ID
|
||||
|
||||
}
|
||||
|
||||
if o.R == nil {
|
||||
o.R = ¬iceR{
|
||||
PinnedNotice: related,
|
||||
Pins: related,
|
||||
}
|
||||
} else {
|
||||
o.R.PinnedNotice = related
|
||||
o.R.Pins = append(o.R.Pins, related...)
|
||||
}
|
||||
|
||||
if related.R == nil {
|
||||
related.R = &pinnedNoticeR{
|
||||
Notice: o,
|
||||
for _, rel := range related {
|
||||
if rel.R == nil {
|
||||
rel.R = &pinR{
|
||||
Notices: NoticeSlice{o},
|
||||
}
|
||||
} else {
|
||||
rel.R.Notices = append(rel.R.Notices, o)
|
||||
}
|
||||
} else {
|
||||
related.R.Notice = o
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetPins removes all previously related items of the
|
||||
// notice replacing them completely with the passed
|
||||
// in related items, optionally inserting them as new records.
|
||||
// Sets o.R.Notices's Pins accordingly.
|
||||
// Replaces o.R.Pins with related.
|
||||
// Sets related.R.Notices's Pins accordingly.
|
||||
func (o *Notice) SetPins(ctx context.Context, exec boil.ContextExecutor, insert bool, related ...*Pin) error {
|
||||
query := "delete from \"pin_notices\" where \"notice_id\" = ?"
|
||||
values := []interface{}{o.ID}
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
_, err := exec.ExecContext(ctx, query, values...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to remove relationships before set")
|
||||
}
|
||||
|
||||
removePinsFromNoticesSlice(o, related)
|
||||
if o.R != nil {
|
||||
o.R.Pins = nil
|
||||
}
|
||||
return o.AddPins(ctx, exec, insert, related...)
|
||||
}
|
||||
|
||||
// RemovePins relationships from objects passed in.
|
||||
// Removes related items from R.Pins (uses pointer comparison, removal does not keep order)
|
||||
// Sets related.R.Notices.
|
||||
func (o *Notice) RemovePins(ctx context.Context, exec boil.ContextExecutor, related ...*Pin) error {
|
||||
var err error
|
||||
query := fmt.Sprintf(
|
||||
"delete from \"pin_notices\" where \"notice_id\" = ? and \"pin_id\" in (%s)",
|
||||
strmangle.Placeholders(dialect.UseIndexPlaceholders, len(related), 2, 1),
|
||||
)
|
||||
values := []interface{}{o.ID}
|
||||
for _, rel := range related {
|
||||
values = append(values, rel.ID)
|
||||
}
|
||||
|
||||
if boil.IsDebug(ctx) {
|
||||
writer := boil.DebugWriterFrom(ctx)
|
||||
fmt.Fprintln(writer, query)
|
||||
fmt.Fprintln(writer, values)
|
||||
}
|
||||
_, err = exec.ExecContext(ctx, query, values...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to remove relationships before set")
|
||||
}
|
||||
removePinsFromNoticesSlice(o, related)
|
||||
if o.R == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, rel := range related {
|
||||
for i, ri := range o.R.Pins {
|
||||
if rel != ri {
|
||||
continue
|
||||
}
|
||||
|
||||
ln := len(o.R.Pins)
|
||||
if ln > 1 && i < ln-1 {
|
||||
o.R.Pins[i] = o.R.Pins[ln-1]
|
||||
}
|
||||
o.R.Pins = o.R.Pins[:ln-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removePinsFromNoticesSlice(o *Notice, related []*Pin) {
|
||||
for _, rel := range related {
|
||||
if rel.R == nil {
|
||||
continue
|
||||
}
|
||||
for i, ri := range rel.R.Notices {
|
||||
if o.ID != ri.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
ln := len(rel.R.Notices)
|
||||
if ln > 1 && i < ln-1 {
|
||||
rel.R.Notices[i] = rel.R.Notices[ln-1]
|
||||
}
|
||||
rel.R.Notices = rel.R.Notices[:ln-1]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Notices retrieves all the records using an executor.
|
||||
func Notices(mods ...qm.QueryMod) noticeQuery {
|
||||
mods = append(mods, qm.From("\"notices\""))
|
||||
|
|
|
@ -1,943 +0,0 @@
|
|||
// 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
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -5,9 +5,10 @@ import (
|
|||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
|
||||
"github.com/friendsofgo/errors"
|
||||
"github.com/volatiletech/sqlboiler/v4/boil"
|
||||
"github.com/volatiletech/sqlboiler/v4/queries/qm"
|
||||
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb"
|
||||
"github.com/ssb-ngi-pointer/go-ssb-room/admindb/sqlite/models"
|
||||
)
|
||||
|
@ -19,12 +20,96 @@ 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)
|
||||
// List returns a sortable map of all the pinned notices
|
||||
func (pn PinnedNotices) List(ctx context.Context) (admindb.PinnedNotices, error) {
|
||||
|
||||
// get all the pins and eager-load the related notices
|
||||
lst, err := models.Pins(qm.Load("Notices")).All(ctx, pn.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fmt.Errorf("TODO: set fixed page %s to %d:%s", name, pageID, lang)
|
||||
// prepare a map for them
|
||||
var pinnedMap = make(admindb.PinnedNotices, len(lst))
|
||||
|
||||
for _, entry := range lst {
|
||||
|
||||
// skip a pin if it has no entries
|
||||
noticeCount := len(entry.R.Notices)
|
||||
if noticeCount == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
name := admindb.PinnedNoticeName(entry.Name)
|
||||
|
||||
// get the exisint map entry or create a new slice
|
||||
notices, has := pinnedMap[name]
|
||||
if !has {
|
||||
notices = make([]admindb.Notice, 0, noticeCount)
|
||||
}
|
||||
|
||||
// add all the related notice to the slice
|
||||
for _, n := range entry.R.Notices {
|
||||
relatedNotice := admindb.Notice{
|
||||
ID: n.ID,
|
||||
Title: n.Title,
|
||||
Content: n.Content,
|
||||
Language: n.Language,
|
||||
}
|
||||
notices = append(notices, relatedNotice)
|
||||
}
|
||||
|
||||
// update the map
|
||||
pinnedMap[name] = notices
|
||||
}
|
||||
|
||||
return pinnedMap, nil
|
||||
}
|
||||
|
||||
func (pn PinnedNotices) Get(ctx context.Context, name admindb.PinnedNoticeName, lang string) (*admindb.Notice, error) {
|
||||
p, err := models.Pins(
|
||||
qm.Where("name = ?", name),
|
||||
qm.Load("Notices", qm.Where("language = ?", lang)),
|
||||
).One(ctx, pn.db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if n := len(p.R.Notices); n != 1 {
|
||||
return nil, fmt.Errorf("pinnedNotice: expected 1 notice but got %d", n)
|
||||
}
|
||||
|
||||
modelNotice := p.R.Notices[0]
|
||||
|
||||
return &admindb.Notice{
|
||||
ID: modelNotice.ID,
|
||||
Title: modelNotice.Title,
|
||||
Content: modelNotice.Content,
|
||||
Language: modelNotice.Language,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (pn PinnedNotices) Set(ctx context.Context, name admindb.PinnedNoticeName, noticeID int64) error {
|
||||
if !name.Valid() {
|
||||
return fmt.Errorf("pinned notice: invalid notice name: %s", name)
|
||||
}
|
||||
|
||||
n, err := models.FindNotice(ctx, pn.db, noticeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p, err := models.Pins(qm.Where("name = ?", name)).One(ctx, pn.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = p.AddNotices(ctx, pn.db, false, n)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// make sure to implement interfaces correctly
|
||||
|
@ -34,28 +119,28 @@ type Notices struct {
|
|||
db *sql.DB
|
||||
}
|
||||
|
||||
func (ndb Notices) GetByID(ctx context.Context, id int64) (admindb.Notice, error) {
|
||||
var n admindb.Notice
|
||||
func (n Notices) GetByID(ctx context.Context, id int64) (admindb.Notice, error) {
|
||||
var notice admindb.Notice
|
||||
|
||||
dbEntry, err := models.FindNotice(ctx, ndb.db, id)
|
||||
dbEntry, err := models.FindNotice(ctx, n.db, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return n, admindb.ErrNotFound
|
||||
return notice, admindb.ErrNotFound
|
||||
}
|
||||
return n, err
|
||||
return notice, err
|
||||
}
|
||||
|
||||
// convert models type to admindb type
|
||||
n.ID = dbEntry.ID
|
||||
n.Title = dbEntry.Title
|
||||
n.Language = dbEntry.Language
|
||||
n.Content = dbEntry.Content
|
||||
notice.ID = dbEntry.ID
|
||||
notice.Title = dbEntry.Title
|
||||
notice.Language = dbEntry.Language
|
||||
notice.Content = dbEntry.Content
|
||||
|
||||
return n, nil
|
||||
return notice, nil
|
||||
}
|
||||
|
||||
func (ndb Notices) RemoveID(ctx context.Context, id int64) error {
|
||||
dbEntry, err := models.FindNotice(ctx, ndb.db, id)
|
||||
func (n Notices) RemoveID(ctx context.Context, id int64) error {
|
||||
dbEntry, err := models.FindNotice(ctx, n.db, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return admindb.ErrNotFound
|
||||
|
@ -63,7 +148,7 @@ func (ndb Notices) RemoveID(ctx context.Context, id int64) error {
|
|||
return err
|
||||
}
|
||||
|
||||
_, err = dbEntry.Delete(ctx, ndb.db)
|
||||
_, err = dbEntry.Delete(ctx, n.db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -71,13 +156,13 @@ func (ndb Notices) RemoveID(ctx context.Context, id int64) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ndb Notices) Save(ctx context.Context, p *admindb.Notice) error {
|
||||
func (n 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"))
|
||||
err := newEntry.Insert(ctx, n.db, boil.Whitelist("title", "content", "language"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -90,7 +175,7 @@ func (ndb Notices) Save(ctx context.Context, p *admindb.Notice) error {
|
|||
existing.Title = p.Title
|
||||
existing.Content = p.Content
|
||||
existing.Language = p.Language
|
||||
_, err := existing.Update(ctx, ndb.db, boil.Whitelist("title", "content", "language"))
|
||||
_, err := existing.Update(ctx, n.db, boil.Whitelist("title", "content", "language"))
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return admindb.ErrNotFound
|
||||
|
|
|
@ -73,3 +73,93 @@ func TestNoticesCRUD(t *testing.T) {
|
|||
r.EqualError(err, admindb.ErrNotFound.Error())
|
||||
})
|
||||
}
|
||||
|
||||
func TestPinnedNotices(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)
|
||||
|
||||
t.Run("defaults", func(t *testing.T) {
|
||||
allTheNotices, err := db.PinnedNotices.List(ctx)
|
||||
r.NoError(err)
|
||||
|
||||
type expectedNotices struct {
|
||||
Name admindb.PinnedNoticeName
|
||||
Count int
|
||||
}
|
||||
|
||||
cases := []expectedNotices{
|
||||
{admindb.NoticeDescription, 2},
|
||||
{admindb.NoticeNews, 1},
|
||||
{admindb.NoticePrivacyPolicy, 2},
|
||||
{admindb.NoticeCodeOfConduct, 1},
|
||||
}
|
||||
|
||||
for i, tcase := range cases {
|
||||
desc, has := allTheNotices[tcase.Name]
|
||||
r.True(has, "case %d failed - notice %s not in map", i, tcase.Name)
|
||||
r.Len(desc, tcase.Count, "case %d failed - wrong number of notices for %s", i, tcase.Name)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("validity", func(t *testing.T) {
|
||||
var empty admindb.Notice
|
||||
// no id
|
||||
err = db.PinnedNotices.Set(ctx, admindb.NoticeNews, empty.ID)
|
||||
r.Error(err)
|
||||
|
||||
// not-null id
|
||||
empty.ID = 999
|
||||
err = db.PinnedNotices.Set(ctx, admindb.NoticeNews, empty.ID)
|
||||
r.Error(err)
|
||||
|
||||
// invalid notice name
|
||||
err = db.PinnedNotices.Set(ctx, "unknown", empty.ID)
|
||||
r.Error(err)
|
||||
})
|
||||
|
||||
t.Run("add new localization", func(t *testing.T) {
|
||||
var notice admindb.Notice
|
||||
notice.Title = "política de privacidad"
|
||||
notice.Content = "solo una prueba"
|
||||
notice.Language = "es"
|
||||
|
||||
// save the new notice
|
||||
err = db.Notices.Save(ctx, ¬ice)
|
||||
r.NoError(err)
|
||||
|
||||
// set it
|
||||
err = db.PinnedNotices.Set(ctx, admindb.NoticePrivacyPolicy, notice.ID)
|
||||
r.NoError(err)
|
||||
|
||||
// retreive it
|
||||
ret, err := db.PinnedNotices.Get(ctx, admindb.NoticePrivacyPolicy, notice.Language)
|
||||
r.NoError(err)
|
||||
r.Equal(notice, *ret, "notices are not the same")
|
||||
|
||||
// see that it's in the list
|
||||
allTheNotices, err := db.PinnedNotices.List(ctx)
|
||||
r.NoError(err)
|
||||
|
||||
notices, has := allTheNotices[admindb.NoticePrivacyPolicy]
|
||||
r.True(has)
|
||||
r.Len(notices, 3)
|
||||
|
||||
has = false
|
||||
for _, n := range notices {
|
||||
if n.Title == notice.Title {
|
||||
has = true
|
||||
break
|
||||
}
|
||||
}
|
||||
r.True(has, "did not find new notice in list()")
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
refs "go.mindeco.de/ssb-refs"
|
||||
)
|
||||
|
@ -83,6 +84,8 @@ func (fpn PinnedNoticeName) Valid() bool {
|
|||
fpn == NoticeCodeOfConduct
|
||||
}
|
||||
|
||||
type PinnedNotices map[PinnedNoticeName][]Notice
|
||||
|
||||
// Notice holds the title and content of a page that is user generated
|
||||
type Notice struct {
|
||||
ID int64
|
||||
|
@ -90,3 +93,38 @@ type Notice struct {
|
|||
Content string
|
||||
Language string
|
||||
}
|
||||
|
||||
type PinnedNotice struct {
|
||||
Name PinnedNoticeName
|
||||
Notices []Notice
|
||||
}
|
||||
|
||||
type SortedPinnedNotices []PinnedNotice
|
||||
|
||||
// Sorted returns a sorted list of the map, by the key names
|
||||
func (pn PinnedNotices) Sorted() SortedPinnedNotices {
|
||||
|
||||
lst := make(SortedPinnedNotices, 0, len(pn))
|
||||
|
||||
for name, notices := range pn {
|
||||
lst = append(lst, PinnedNotice{
|
||||
Name: name,
|
||||
Notices: notices,
|
||||
})
|
||||
}
|
||||
|
||||
sort.Sort(lst)
|
||||
return lst
|
||||
}
|
||||
|
||||
var _ sort.Interface = (SortedPinnedNotices)(nil)
|
||||
|
||||
func (byName SortedPinnedNotices) Len() int { return len(byName) }
|
||||
|
||||
func (byName SortedPinnedNotices) Less(i, j int) bool {
|
||||
return byName[i].Name < byName[j].Name
|
||||
}
|
||||
|
||||
func (byName SortedPinnedNotices) Swap(i, j int) {
|
||||
byName[i], byName[j] = byName[j], byName[i]
|
||||
}
|
||||
|
|
|
@ -218,6 +218,7 @@ func runroomsrv() error {
|
|||
db.AuthFallback,
|
||||
db.AllowList,
|
||||
db.Notices,
|
||||
db.PinnedNotices,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create HTTPdashboard handler: %w", err)
|
||||
|
|
|
@ -28,7 +28,8 @@ import (
|
|||
var HTMLTempaltes = []string{
|
||||
"landing/index.tmpl",
|
||||
"landing/about.tmpl",
|
||||
"notice.tmpl",
|
||||
"notice/list.tmpl",
|
||||
"notice/show.tmpl",
|
||||
"error.tmpl",
|
||||
}
|
||||
|
||||
|
@ -41,6 +42,7 @@ func New(
|
|||
fs admindb.AuthFallbackService,
|
||||
al admindb.AllowListService,
|
||||
ns admindb.NoticesService,
|
||||
ps admindb.PinnedNoticesService,
|
||||
) (http.Handler, error) {
|
||||
m := router.CompleteApp()
|
||||
|
||||
|
@ -199,9 +201,11 @@ func New(
|
|||
m.Get(router.CompleteIndex).Handler(r.StaticHTML("landing/index.tmpl"))
|
||||
m.Get(router.CompleteAbout).Handler(r.StaticHTML("landing/about.tmpl"))
|
||||
|
||||
var nr noticeRenderer
|
||||
var nr noticeHandler
|
||||
nr.notices = ns
|
||||
m.Get(router.CompleteNotice).Handler(r.HTML("notice.tmpl", nr.render))
|
||||
nr.pinned = ps
|
||||
m.Get(router.CompleteNoticeList).Handler(r.HTML("notice/list.tmpl", nr.list))
|
||||
m.Get(router.CompleteNoticeShow).Handler(r.HTML("notice/show.tmpl", nr.show))
|
||||
|
||||
m.PathPrefix("/assets/").Handler(http.StripPrefix("/assets/", http.FileServer(web.Assets)))
|
||||
|
||||
|
|
|
@ -11,30 +11,43 @@ import (
|
|||
"github.com/ssb-ngi-pointer/go-ssb-room/web/errors"
|
||||
)
|
||||
|
||||
type noticeRenderer struct {
|
||||
type noticeHandler struct {
|
||||
pinned admindb.PinnedNoticesService
|
||||
notices admindb.NoticesService
|
||||
}
|
||||
|
||||
type noticeData struct {
|
||||
func (h noticeHandler) list(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
|
||||
lst, err := h.pinned.List(req.Context())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return struct {
|
||||
Entries admindb.SortedPinnedNotices
|
||||
}{lst.Sorted()}, nil
|
||||
}
|
||||
|
||||
type noticeShowData struct {
|
||||
ID int64
|
||||
Title, Language string
|
||||
Content template.HTML
|
||||
}
|
||||
|
||||
func (pr noticeRenderer) render(rw http.ResponseWriter, req *http.Request) (interface{}, error) {
|
||||
func (h noticeHandler) show(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)
|
||||
notice, err := h.notices.GetByID(req.Context(), noticeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
markdown := blackfriday.Run([]byte(notice.Content), blackfriday.WithNoExtensions())
|
||||
|
||||
return noticeData{
|
||||
return noticeShowData{
|
||||
ID: noticeID,
|
||||
Title: notice.Title,
|
||||
Content: template.HTML(markdown),
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
Confirm = "Confirm"
|
||||
Save = "Save"
|
||||
Preview = "Preview"
|
||||
GenericConfirm = "Yes"
|
||||
GenericGoBack = "Back"
|
||||
GenericSave = "Save"
|
||||
GenericPreview = "Preview"
|
||||
|
||||
PageNotFound = "The requested page was not found."
|
||||
|
||||
LandingTitle = "ohai my room"
|
||||
|
@ -15,9 +17,6 @@ AuthFallbackTitle = "The place of last resort"
|
|||
AuthSignIn = "Sign in"
|
||||
AuthSignOut = "Sign out"
|
||||
|
||||
GenericConfirm = "Yes"
|
||||
GenericGoBack = "Back"
|
||||
|
||||
AdminDashboardWelcome = "Welcome to your dashboard"
|
||||
AdminDashboardTitle = "Room Admin Dashboard"
|
||||
|
||||
|
@ -30,13 +29,14 @@ AdminAllowListRemoveConfirmTitle = "Confirm member removal"
|
|||
|
||||
NavAdminDashboard = "Dashboard"
|
||||
|
||||
NoticeEditTitle = "Edit Notice"
|
||||
NoticeList = "List of notices"
|
||||
|
||||
[MemberCount]
|
||||
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"
|
||||
|
|
|
@ -8,9 +8,11 @@ import (
|
|||
|
||||
// constant names for the named routes
|
||||
const (
|
||||
CompleteIndex = "complete:index"
|
||||
CompleteAbout = "complete:about"
|
||||
CompleteNotice = "complete:notice"
|
||||
CompleteIndex = "complete:index"
|
||||
CompleteAbout = "complete:about"
|
||||
|
||||
CompleteNoticeShow = "complete:notice:show"
|
||||
CompleteNoticeList = "complete:notice:list"
|
||||
)
|
||||
|
||||
// CompleteApp constructs a mux.Router containing the routes for batch Complete html frontend
|
||||
|
@ -23,7 +25,8 @@ func CompleteApp() *mux.Router {
|
|||
|
||||
m.Path("/").Methods("GET").Name(CompleteIndex)
|
||||
m.Path("/about").Methods("GET").Name(CompleteAbout)
|
||||
m.Path("/notice").Methods("GET").Name(CompleteNotice)
|
||||
m.Path("/notice/show").Methods("GET").Name(CompleteNoticeShow)
|
||||
m.Path("/notice/list").Methods("GET").Name(CompleteNoticeList)
|
||||
|
||||
return m
|
||||
}
|
||||
|
|
|
@ -33,11 +33,11 @@
|
|||
<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>
|
||||
>{{i18n "GenericSave"}}</button>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<h1>{{i18n "Preview"}}</h1>
|
||||
<h1>{{i18n "GenericPreview"}}</h1>
|
||||
{{.ContentPreview}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{{ define "title" }}{{i18n "NoticeList"}}{{ end }}
|
||||
{{ define "content" }}
|
||||
<div class="container mx-auto">
|
||||
<h1 class="text-lg">{{i18n "NoticeList"}}</h1>
|
||||
|
||||
<ul id="theList">
|
||||
{{range .Entries}}
|
||||
<li>
|
||||
|
||||
<a href="{{urlTo "complete:notice:show" "id" .ID}}">
|
||||
Title: {{.Title}}
|
||||
</a>
|
||||
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
{{end}}
|
Loading…
Reference in New Issue