-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMemBashed.bash
216 lines (186 loc) · 6.13 KB
/
MemBashed.bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#!/bin/bash
#
# A very crude interface to MemCached from the commandline.
#
# Made with a great deal of inspiration from the following sources:
# - https://gist.github.com/ri0day/1538831
# - https://gist.github.com/goodevilgenius/11375877
# - cheatsheet http://lzone.de/cheat-sheet/memcached
#
# The first one gave me a way to use break after the server has answered.
# The version from goodevilgenius helpen in making an abstraction MC.
# The third really is what I needed after reading the docs at
# https://github.com/memcached/memcached/blob/master/doc/protocol.txt
# Check if the environment variable's have been set
# if not use the following defaults
if [ -z $TTL ]; then export TTL=3600; fi
if [ -z $PORT ]; then export PORT=11211; fi
if [ -z $MEMCACHED_HOST ]; then export MEMCACHED_HOST="127.0.0.1"; fi
if [ ! $_ != $0 ]; then
echo "loading MemBashed functions"
if [ $SHELL != "*bash" ]; then
echo "You are not using bash, but ${SHELL}. Some shells do "
echo "not support the used /dev/tcp pseudo device."
exit;
fi
fi
#
# STORE functions
#
function m_send {
# MemBashed m_send: makes file descriptor with connection to
# Memcached and sends command through it
# Arguments ::
# 1: Message to send to MemCached
exec 3<>/dev/tcp/$MEMCACHED_HOST/$PORT
echo -en "$1\r\n">&3
# The incr and decr functions don't return anything
if [[ "$1" =~ ^(incr|decr).* ]]; then return; fi
# Read from file descriptor 3 until we see \r. We pass the
# line before that into the loop. If it matches we have a
# MemCached status otherwise just print the line and move
# on to the next.
while read -u 3 -d $'\r' lastline
do
# break on MemCached status to get controlflow back
if [ "$lastline" == "DELETED" -o \
"$lastline" == "END" -o \
"$lastline" == "OK" -o \
"$lastline" == "EXISTS" -o \
"$lastline" == "STORED" ]; then
break;
elif [ "$lastline" == "ERROR" -o \
"$lastline" == "NOT_STORED" -o \
"$lastline" == "NOT_FOUND" ]; then
echo $lastline 1>&2;
break;
elif [[ "$lastline" == VERSION* ]]; then
echo $lastline
break;
fi
echo $lastline
done
}
function m_set {
# MemBashed set; "set" means "store this data"
# Arguments ::
# 1: Key
# 2: 16 or 32 bit flags
# 3: TTL
# 4: Lenght in bytes
# 5: Data
KEY=$1
DATA=$2
CHR=$(echo -n $DATA|wc -c)
m_send "set ${KEY} 0 ${TTL} ${CHR}\r\n${DATA}"
}
function m_add {
# MemBashed add; "add" means "store this data, but only if the server *doesn't* already
# hold data for this key".
KEY=$1
DATA=$2
CHR=$(echo -n $DATA|wc -c)
m_send "add ${KEY} 0 ${TTL} ${CHR}\r\n${DATA}"
}
function m_replace {
# MemBashed replace: "replace" means "store this data, but only if the server *does*
# already hold data for this key".
KEY=$1
DATA=$2
CHR=$(echo -n $DATA|wc -c)
m_send "replace ${KEY} 0 ${TTL} ${CHR}\r\n${DATA}"
}
function m_append {
# MemBashed append: "append" means "add this data to an existing key after existing data".
#
KEY=$1
DATA=$2
CHR=$(echo -n $DATA|wc -c)
m_send "append ${KEY} 0 ${TTL} ${CHR}\r\n${DATA}"
}
function m_prepend {
# MemBashed prepend: "prepend" means "add this data to an existing key before existing data".
#
KEY=$1
DATA=$2
CHR=$(echo -n $DATA| wc -c)
m_send "prepend ${KEY} 0 ${TTL} ${CHR}\r\n${DATA}"
}
function m_cas {
# MemBashed cas: "cas" is a check and set operation which means "store this data but
# only if no one else has updated since I last fetched it."
echo Not yet implemented.;
}
#
# RETRIEVE
#
function m_get {
# MemBashed get; gets value from the store
# Argument ::
# 1: Key
m_send "get ${@}" | sed -n '1d;p;n'
m_send "quit"
}
function m_gets {
# MemBashed get; gets value from the store
# Argument ::
# *: Key
m_send "gets ${@}"
}
#
# UPDATE
#
function m_decr {
# MemBashed decr: "decr" is used to change data for some item
# in-place, decrementing it.
KEY=$1
INT=$2
m_send "decr ${KEY} ${INT}"
}
function m_incr {
# MemBashed incr: "incr" is used to change data for some item
# in-place, increasing it.
KEY=$1
INT=$2
m_send "incr ${KEY} ${INT} noreply"
m_send "quit"
}
function m_touch {
# MemBashed touch: The "touch" command is used to update the expiration
# time of an existing item without fetching it.
KEY=$1
EXP=$2
m_send "touch ${KEY} ${EXP}"
}
#
# DELETION
#
function m_delete {
# MemBashed delete; deletes am item from the store
# Argument ::
# *: Key
KEY=$1
m_send "delete ${KEY}"
}
function m_flush_all {
# MemBashed delete; deletes am item from the store
m_send "flush_all"
}
#
# SERVER
#
# MemBashed version: returns server version
function m_version {
m_send "version";
}
# MemBashed stats; return stats from MemCached
function m_stats { m_send "stats"; }
function m_stats_items { m_send "stats items"; }
function m_stats_slabs { m_send "stats slabs"; }
function m_stats_malloc { m_send "stats malloc"; }
function m_custom_cmd {
# MemBashed mcustom_cmd: send raw message to Memcached
# Arguments ::
# 1: Raw message to send
m_send "$@"
}