Changeset 577
- Timestamp:
- 12/22/2011 02:33:53 (5 months ago)
- File:
-
- 1 edited
-
trunk/libfiledb.sh.in (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/libfiledb.sh.in
r576 r577 25 25 # $Id$ 26 26 # 27 # libfiledb.sh is a command-line toolfor file-backed key-value stores.27 # libfiledb.sh is a shell library for file-backed key-value stores. 28 28 # 29 # libfiledb.sh uses the null character as its internal delimiter, so null 30 # characters are stripped from keys and values before being inserted into 31 # the database. 29 # libfiledb.sh does not do any locking -- locking must be managed by the 30 # caller as appropriate. 31 # 32 # The on-disk storage format uses the tab character as the field delimiter 33 # and the new line character as the record delimiter. Tab characters are 34 # accepted in keys and values. 32 35 33 FILEDB_VERSION="1.0" 34 OS_UNAME=`/usr/bin/uname` 35 CONFLOCK="@pkglibexecdir@/conflock" 36 37 # Purpose: Runs sed differently based on the running OS 38 # Inputs: Arguments to sed 39 # Prints: Output of sed 40 # Returns: 0 on success, 2 on error 41 os_sed() 36 # Purpose: Load a filedb into an array 37 # Inputs: filedb, array 38 # Prints: N/A 39 # Returns: 0 if the filedb was loaded into the array, 1 on error 40 filedb_load() 42 41 { 43 case ${OS_UNAME} in 44 FreeBSD) 45 /usr/bin/sed -i '' "$@" || return 2;; 46 Linux) 47 /bin/sed -i "$@" || return 2;; 48 *) 49 return 2;; 50 esac 51 52 return 0 53 } 54 55 # Purpose: Create a filedb 56 # Inputs: filedb 57 # Prints: N/A 58 # Returns: 0 if the filedb was created, 2 on error 59 filedb_create() 60 { 61 if [ $# -ne 1 ]; then 62 return 2 42 if [ -z "${1-}" -o -z "${2-}" ]; then 43 return 1 63 44 fi 64 45 65 46 local filedb="$1" 47 local array="$2" 66 48 67 local lock_type 49 local key 50 local value 68 51 69 lock_type=`filedb_lock "${filedb}"` || return 2 52 [ -r "${filedb}" ] && 53 [ -v "${array}" ] && 54 local IFS=" " 55 while read -r key value; do 56 eval "`echo "${array}"`[`echo -e "${key}"`]=`echo -e "${value}"`" 57 done <"${filedb}" && 58 return 0 70 59 71 ! [ -f "${filedb}" ] && 72 touch "${filedb}" && 73 filedb_set_value "${filedb}" "filedb:version" "${FILEDB_VERSION}" && 74 filedb_unlock "${filedb}" "${lock_type}" && 75 return 0 76 77 filedb_unlock "${filedb}" "${lock_type}" 78 return 2 60 return 1 79 61 } 80 62 81 # Purpose: Recursively locka filedb82 # Inputs: filedb83 # Prints: "recursive" or "original" depending on the type of lock acquired84 # Returns: 0 if the filedb was locked, 2on error85 filedb_ lock()63 # Purpose: Write an array into a filedb 64 # Inputs: array, filedb 65 # Prints: N/A 66 # Returns: 0 if the array was written into the filedb, 1 on error 67 filedb_write() 86 68 { 87 if [ $# -ne 1]; then88 return 269 if [ -z "${1-}" -o -z "${2-}" ]; then 70 return 1 89 71 fi 90 72 91 local filedb="$1" 73 local array="$1" 74 local filedb="$2" 92 75 93 local lock_type 94 95 # If this process already has the lock, this is a recursive lock 96 if filedb_is_locked "${filedb}"; then 97 lock_type="recursive" 98 else 99 lock_type="original" 100 fi 101 102 "${CONFLOCK}" lock $$ "${filedb}.lock" || return 2 103 104 echo "${lock_type}" 105 return 0 106 } 107 108 # Purpose: Recursively lock a filedb if it exists 109 # Inputs: filedb 110 # Prints: "recursive" or "original" depending on the type of lock acquired 111 # Returns: 0 if the filedb was locked, 2 on error 112 filedb_lock_if_exists() 113 { 114 if [ $# -ne 1 ]; then 115 return 2 116 fi 117 118 local filedb="$1" 119 120 local lock_type 121 122 lock_type=`filedb_lock "${filedb}"` || return 2 123 124 [ -f "${filedb}" ] && 125 echo "${lock_type}" && 126 return 0 127 128 filedb_unlock "${filedb}" "${lock_type}" 129 return 2 130 } 131 132 # Purpose: Unlock a filedb 133 # Inputs: filedb, lock type 134 # Prints: N/A 135 # Returns: 0 if the filedb was unlocked, 2 on error 136 filedb_unlock() 137 { 138 if [ $# -ne 2 ]; then 139 return 2 140 fi 141 142 local filedb="$1" 143 local lock_type="$2" 144 145 case "${lock_type}" in 146 recursive) 147 return 0;; 148 original) 149 "${CONFLOCK}" unlock $$ "${filedb}.lock" || return 2;; 150 *) 151 return 2;; 152 esac 153 154 return 0 155 } 156 157 # Purpose: Test whether a filedb is locked 158 # Inputs: filedb 159 # Prints: N/A 160 # Returns: 0 if the filedb is locked, 1 if the filedb is not locked, 2 on error 161 filedb_is_locked() 162 { 163 if [ $# -ne 1 ]; then 164 return 2 165 fi 166 167 local filedb="$1" 168 169 local rv 170 171 "${CONFLOCK}" haslock $$ "${filedb}.lock" 172 rv=$? 173 174 case ${rv} in 175 0|1) 176 return ${rv};; 177 *) 178 return 2;; 179 esac 180 } 181 182 # Purpose: Get the list of keys 183 # Inputs: filedb 184 # Prints: The list of keys 185 # Returns: 0 on success, 2 on error 186 filedb_get_keys() 187 { 188 if [ $# -ne 1 ]; then 189 return 2 190 fi 191 192 local filedb="$1" 193 194 local lock_type 195 196 lock_type=`filedb_lock_if_exists "${filedb}"` || return 2 197 198 awk -F '\0' '{print $1}' "${filedb}" && 199 filedb_unlock "${filedb}" "${lock_type}" && 200 return 0 201 202 filedb_unlock "${filedb}" "${lock_type}" 203 return 2 204 } 205 206 # Purpose: Get the list of values 207 # Inputs: filedb 208 # Prints: The list of values 209 # Returns: 0 on success, 2 on error 210 filedb_get_values() 211 { 212 if [ $# -ne 1 ]; then 213 return 2 214 fi 215 216 local filedb="$1" 217 218 local lock_type 219 220 lock_type=`filedb_lock_if_exists "${filedb}"` || return 2 221 222 awk -F '\0' '{print $2}' "${filedb}" && 223 filedb_unlock "${filedb}" "${lock_type}" && 224 return 0 225 226 filedb_unlock "${filedb}" "${lock_type}" 227 return 2 228 } 229 230 # Purpose: Test whether a key exists 231 # Inputs: filedb, key 232 # Prints: N/A 233 # Returns: 0 if the key exists, 1 if the key does not exist, 2 on error 234 filedb_key_exists() 235 { 236 if [ $# -ne 2 ]; then 237 return 2 238 fi 239 240 local filedb="$1" 241 local key=`echo "$2" | tr -d '\0'` 242 243 local lock_type 244 local rv 245 246 lock_type=`filedb_lock_if_exists "${filedb}"` || return 2 247 248 awk -F '\0' '{if ($1 == "'"${key}"'") {_assert_exit = 1; exit}}; END {if (_assert_exit) exit 0; exit 1}' "${filedb}" 249 rv=$? 250 251 case ${rv} in 252 0|1) 253 filedb_unlock "${filedb}" "${lock_type}" || return 2 254 return ${rv};; 255 esac 256 257 filedb_unlock "${filedb}" "${lock_type}" 258 return 2 259 } 260 261 # Purpose: Get the value for a key 262 # Inputs: filedb, key 263 # Prints: The value for the key 264 # Returns: 0 if the value was retrieved, 2 on error 265 filedb_get_value() 266 { 267 if [ $# -ne 2 ]; then 268 return 2 269 fi 270 271 local filedb="$1" 272 local key=`echo "$2" | tr -d '\0'` 273 274 local lock_type 76 local i 77 local key 275 78 local value 276 79 277 lock_type=`filedb_lock_if_exists "${filedb}"` || return 2 80 [ -w "${filedb}" -o -w "`dirname "${filedb}"`" ] && 81 [ -v "${array}" ] && 82 eval 'for i in "'"\${!${array}"'[@]}"; do 83 echo "${i}" 84 done' | while read key; do 85 eval 'value="'"\${${array}[${key}]}"'"' 86 echo -nE "${key%% *}" 87 while [ "${key}" != "${key#* }" ]; do 88 key="${key#* }" 89 echo -nE "\\t${key%% *}" 90 done 91 echo -n " " 92 echo -nE "${value%% *}" 93 while [ "${value}" != "${value#* }" ]; do 94 value="${value#* }" 95 echo -nE "\\t${value%% *}" 96 done 97 echo 98 done > "${filedb}" && 99 return 0 278 100 279 filedb_key_exists "${filedb}" "${key}" && 280 value=`awk -F '\0' '{if ($1 == "'"${key}"'") print $2}' "${filedb}"` && 281 echo "${value}" && 282 filedb_unlock "${filedb}" "${lock_type}" && 283 return 0 284 285 filedb_unlock "${filedb}" "${lock_type}" 286 return 2 101 return 1 287 102 } 288 289 # Purpose: Delete a key290 # Inputs: filedb, key291 # Prints: N/A292 # Returns: 0 if the key was deleted, 2 on error293 filedb_delete_key()294 {295 if [ $# -ne 2 ]; then296 return 2297 fi298 299 local filedb="$1"300 local key=`echo "$2" | tr -d '\0'`301 302 local lock_type303 local line304 305 lock_type=`filedb_lock_if_exists "${filedb}"` || return 2306 307 line=`awk -F '\0' '{if ($1 == "'"${key}"'") print NR}' "${filedb}"` &&308 [ -n "${line}" ] &&309 os_sed "${line} d" "${filedb}" &&310 filedb_unlock "${filedb}" "${lock_type}" &&311 return 0312 313 filedb_unlock "${filedb}" "${lock_type}"314 return 2315 }316 317 # Purpose: Set a value for a key318 # Inputs: filedb, key, value319 # Prints: N/A320 # Returns: 0 if the value was set, 2 on error321 filedb_set_value()322 {323 if [ $# -ne 3 ]; then324 return 2325 fi326 327 local filedb="$1"328 local key=`echo "$2" | tr -d '\0'`329 local value=`echo "$3" | tr -d '\0'`330 331 local lock_type332 local rv333 334 lock_type=`filedb_lock_if_exists "${filedb}"` || return 2335 336 filedb_key_exists "${filedb}" "${key}"337 rv=$?338 339 case ${rv} in340 0)341 if ! filedb_delete_key "${filedb}" "${key}"; then342 filedb_unlock "${filedb}" "${lock_type}"343 return 2344 fi;;345 1)346 :;;347 *)348 filedb_unlock "${filedb}" "${lock_type}"349 return 2;;350 esac351 352 printf "${key}\\000${value}\\n" >> "${filedb}" &&353 filedb_unlock "${filedb}" "${lock_type}" &&354 return 0355 356 filedb_unlock "${filedb}" "${lock_type}"357 return 2358 }
Note: See TracChangeset
for help on using the changeset viewer.
