-
-
Save lecram/4280027 to your computer and use it in GitHub Desktop.
#! /usr/bin/env python | |
"""{escher} -- one-file key-value storage. | |
What? | |
This is a toy application to manage persistent key-value string data. | |
The file {escher} is *both* the application and its data. | |
When you run any of the commands below, the file will be executed and, | |
after data change, it will rewrite itself with updated data. | |
You can copy the file with whatever name to create multiple datasets. | |
Remember that the data will be copied with the file. Each file must | |
be readable, writable, and executable. | |
Why? | |
I don't know; this is probably useless. | |
Usage: | |
Listing current keys: | |
$ {escher} | |
Getting the value of the foo key: | |
$ {escher} foo | |
(NOTE: If foo is not in the dataset, exit code will be 1.) | |
Setting the value of foo to bar: | |
$ {escher} foo bar | |
Removing the key foo: | |
$ {escher} foo "" | |
(NOTE: If foo is not in the dataset, exit code will be 1.) | |
Removing everything: | |
$ {escher} --clean | |
Printing this help message: | |
$ {escher} --help | |
""" | |
from __future__ import print_function | |
import sys | |
import os | |
import pickle | |
import zlib | |
import base64 | |
__doc__ = __doc__.format(escher=os.path.basename(__file__)) | |
sep = "--//--" | |
f = open(__file__, "r") | |
esc, her = f.read().split(repr(sep), 1) | |
f.close() | |
data = pickle.loads(zlib.decompress(base64.b64decode(her[1:].strip()))) | |
args = sys.argv[1:] | |
print([ | |
lambda : "\n".join(sorted(data.keys())) if data else | |
sys.exit(), | |
lambda key : __doc__ if key == "--help" else | |
not data.clear() and "X *" if key == "--clean" else | |
data.get(key, False) or | |
sys.exit("Error: key not found."), | |
lambda key, value : not data.update([(key, value)]) and | |
" ".join([key, "<-", value]) if value else | |
data.pop(key, True) and "X " + key if key in data else | |
sys.exit("Error: key not found."), | |
lambda fu, ti, le : print("Error: invalid argument list.") or sys.exit(2) | |
][min(len(args), 3)](*args[:3])) | |
her = base64.b64encode(zlib.compress(pickle.dumps(data, 2))).decode('ascii') | |
out = repr(sep).join([esc, "\n#" + her + "\n"]) | |
with open(__file__, "w") as f: f.write(out) | |
'--//--' | |
#eJxrYKotZNADAAaFAZ8= |
Clearly it needs more node.js and eventloop/reactor style programming to make it webscale. Also while we're at it, chuck redis in and mongodb or something. Then it'll be webscale.
One thing I found when using this to replace my MongoDB installation is that it doesn't like '}' characters in the values (or keys). Pity. I don't see how this can get to be webscale without javascript compatibility.
I thought you were just supposed to say "Hadoop" three times and drop your wallet on the floor?
I can see why you are programmers and not comedians.
Haha, I wrote one of these myself, several years ago:
@mdda
I couldn't reproduce any problem with '}' characters. Perhaps your shell uses then for substitution? Did you try enclosing the arguments in quotes? Can you show an example that doesn't work so I can try to fix it?
@mattrobenolt
web scale version:
https://gist.github.com/4291690
There seems to be some issue when running with some concurrency. I did a quick test run with:
seq 5000 | xargs -P100 -I% python escher.py foo% %
and the file got corrupt.I conclude that this, sir, is not in fact, web scale.