aboutsummaryrefslogtreecommitdiff
path: root/storage/filter/filter.go
diff options
context:
space:
mode:
Diffstat (limited to 'storage/filter/filter.go')
-rw-r--r--storage/filter/filter.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/storage/filter/filter.go b/storage/filter/filter.go
new file mode 100644
index 0000000..52ecbfd
--- /dev/null
+++ b/storage/filter/filter.go
@@ -0,0 +1,77 @@
+package filter
+
+import (
+ "bytes"
+ "code.laria.me/petrific/objects"
+ "code.laria.me/petrific/storage"
+ "errors"
+ "os/exec"
+)
+
+type Filter interface {
+ Transform([]byte) ([]byte, error)
+}
+
+type PipeFilter []string
+
+var emptyCommand = errors.New("Need at least one argument for pipeFilter")
+
+func (pf PipeFilter) Transform(b []byte) ([]byte, error) {
+ if len(pf) == 0 {
+ return []byte{}, emptyCommand
+ }
+
+ cmd := exec.Command(pf[0], pf[1:]...)
+
+ buf := new(bytes.Buffer)
+ cmd.Stdout = buf
+ cmd.Stdin = bytes.NewReader(b)
+
+ if err := cmd.Run(); err != nil {
+ return []byte{}, err
+ }
+
+ return buf.Bytes(), nil
+}
+
+type FilterStorage struct {
+ Base storage.Storage
+ Decode, Encode Filter
+}
+
+func (filt FilterStorage) Get(id objects.ObjectId) ([]byte, error) {
+ data, err := filt.Base.Get(id)
+ if err != nil {
+ return data, err
+ }
+
+ if filt.Decode == nil {
+ return data, nil
+ }
+
+ return filt.Decode.Transform(data)
+}
+
+func (filt FilterStorage) Has(id objects.ObjectId) (bool, error) {
+ return filt.Base.Has(id)
+}
+
+func (filt FilterStorage) Set(id objects.ObjectId, typ objects.ObjectType, raw []byte) error {
+ if filt.Encode != nil {
+ var err error
+ raw, err = filt.Encode.Transform(raw)
+ if err != nil {
+ return err
+ }
+ }
+
+ return filt.Base.Set(id, typ, raw)
+}
+
+func (filt FilterStorage) List(typ objects.ObjectType) ([]objects.ObjectId, error) {
+ return filt.Base.List(typ)
+}
+
+func (filt FilterStorage) Close() error {
+ return filt.Base.Close()
+}