Skip to content

Instantly share code, notes, and snippets.

@lecram
Last active August 27, 2021 07:05
Show Gist options
  • Star 45 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save lecram/4280027 to your computer and use it in GitHub Desktop.
Save lecram/4280027 to your computer and use it in GitHub Desktop.
This is a toy one-file application to manage persistent key-value string data. The file is *both* the application and its data. When you run any of the commands described in `escher.py --help`, 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 d…
#! /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=
@mattrobenolt
Copy link

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.

@chewxy
Copy link

chewxy commented Dec 14, 2012

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.

@mdda
Copy link

mdda commented Dec 14, 2012

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.

@shenanigans
Copy link

I thought you were just supposed to say "Hadoop" three times and drop your wallet on the floor?

@shabda
Copy link

shabda commented Dec 14, 2012

@chewxy

, chuck redis in and mongodb or something.

Chuck Norris in and mongodb or something.

@Ivanca
Copy link

Ivanca commented Dec 14, 2012

I can see why you are programmers and not comedians.

@kennethreitz
Copy link

Haha, I wrote one of these myself, several years ago:

https://gist.github.com/477550

@lecram
Copy link
Author

lecram commented Dec 14, 2012

@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?

@saml
Copy link

saml commented Dec 15, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment