/* * Wiki - A wiki with editor * Copyright (c) 2021-2021 Peter Stuifzand * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package main import ( "encoding/json" "fmt" "os" "path/filepath" ) type BlockRepository interface { Save(id string, block Block) error Load(id string) (Block, error) } type blockSaveMessage struct { id string block Block } type blockRepo struct { dirname string saveC chan blockSaveMessage errC chan error } func saveBlock(dirname, id string, block Block) error { f, err := os.OpenFile(filepath.Join(dirname, BlocksDirectory, id), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return err } defer f.Close() enc := json.NewEncoder(f) enc.SetIndent("", " ") err = enc.Encode(&block) if err != nil { return err } return nil } func NewBlockRepo(dirname string) BlockRepository { saveC := make(chan blockSaveMessage, 1) errC := make(chan error) go func() { for msg := range saveC { err := saveBlock(dirname, msg.id, msg.block) errC <- err } }() return &blockRepo{ dirname: dirname, saveC: saveC, errC: errC, } } func (br *blockRepo) Save(id string, block Block) error { br.saveC <- blockSaveMessage{id, block} err := <-br.errC return err } func (br *blockRepo) Load(id string) (Block, error) { f, err := os.Open(filepath.Join(br.dirname, BlocksDirectory, id)) if err != nil { return Block{}, fmt.Errorf("%q: %w", id, BlockNotFound) } defer f.Close() var block Block err = json.NewDecoder(f).Decode(&block) if err != nil { return Block{}, fmt.Errorf("%q: %w", id, err) } return block, nil }