]> git.plutz.net Git - cgilite/blobdiff - storage.sh
introduce simple DBM module
[cgilite] / storage.sh
index f53fe7f9ed027cfc0dce4cb38661655832c269da..a8484b0514891fe3e7d6f3cfdbb55fba655cb61a 100755 (executable)
@@ -127,3 +127,95 @@ UNSTRING(){
   printf '%s' "$out"
 }
 
+DBM() {
+  local file="$1" cmd="$2"
+  local k v key value
+  shift 2;
+
+  case "$cmd" in
+    check|contains)
+      key="$(STRING "$1")"
+      while read -r k v; do if [ "$k" = "$key" ]; then
+        return 0
+      fi; done <"$file" 2>&-
+      return 1
+      ;;
+    get)
+      key="$(STRING "$1")"
+      while read -r k v; do if [ "$k" = "$key" ]; then
+        UNSTRING "$v"
+        return 0
+      fi; done <"$file" 2>&-
+      return 1
+      ;;
+    set|store)
+      key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      { while read -r k v; do
+          [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+        printf '%s\t%s\n' "$key" "$value"
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+    add|insert)
+      k="$1" key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      if DBM "$file" check "$k"; then
+        RELEASE "$file"
+        return 1
+      else
+        printf '%s\t%s\n' "$key" "$value" >>"${file}"
+        RELEASE "$file"
+        return 0
+      fi
+      ;;
+    update|replace)
+      k="$1" key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      if ! DBM check "$k"; then
+        RELEASE "$file"
+        return 1
+      fi
+      { while read -r k v; do
+          [ "$k" = "$key" ] \
+          && printf '%s\t%s\n' "$key" "$value" \
+          || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+    append)
+      key="$(STRING "$1")" value="$(STRING "$2")"
+      LOCK "$file" || return 1
+      if ! DBM check "$1"; then
+        RELEASE "$file"
+        return 1
+      fi
+      { while read -r k v; do
+          [ "$k" = "$key" ] \
+          && printf '%s\t%s\n' "$key" "$v$value" \
+          || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+    delete|remove)
+      key="$(STRING "$1")"
+      LOCK "$file" || return 1
+      { while read -r k v; do
+          [ "$k" = "$key" ] || printf '%s\t%s\n' "$k" "$v"
+        done <"$file" 2>&-
+      } >"${file}.$$.tmp"
+      mv "${file}.$$.tmp" "${file}"
+      RELEASE "$file"
+      return 0
+      ;;
+  esac
+}