added experimental thin tag implementation over sql...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2011-11-16 02:11:32 +04:00
parent 2b0ed6492f
commit 86cab29e3c
2 changed files with 136 additions and 0 deletions

View File

@ -30,6 +30,12 @@ Concepts
URL URL
structure structure
configuration (archive-wide)
general settings
actions
scripts
remote refs
clone settings
index (metadata) index (metadata)
data data

130
sqlitetags.py Executable file
View File

@ -0,0 +1,130 @@
#=======================================================================
__version__ = '''0.0.01'''
__sub_version__ = '''20111116021012'''
__copyright__ = '''(c) Alex A. Naanou 2011'''
#-----------------------------------------------------------------------
import sqlite3
import uuid
import pli.objutils as objutils
import pli.pattern.proxy.utils as putils
from pli.logictypes import ANY
import tags
#-----------------------------------------------------------------------
class SQLiteTagset(tags.AbstractTagSet):
'''
'''
##!!! this is not persistent yet...
objutils.createonaccess('_objects', dict)
def __init__(self, path):
'''
'''
self._db = sqlite3.connect(path)
self._db.execute('create table if not exists tags(tag text, object text)')
self._db.commit()
putils.proxymethods((
'commit',
), '_db')
def tag(self, obj, *tags, **opts):
'''
'''
db = self._db
objs = self._objects.items()
if (ANY, obj) not in self._objects:
gid = str(uuid.uuid4())
self._objects[gid] = obj
else:
gid = objs[objs.index((ANY, obj))][0]
for tag in tags:
# check if such a tag exists...
if len(db.execute('select * from tags where tag=? and object=?', (tag, gid)).fetchall()) > 0:
continue
db.execute('insert into tags values (?, ?)', (tag, gid))
if not opts.get('NOCOMMIT', False):
db.commit()
##!!!
def untag(self, obj, *tags, **opts):
'''
'''
##!!!
if not opts.get('NOCOMMIT', False):
db.commit()
def any(self, *tags, **opts):
'''
'''
db = self._db
objs = self._objects
# build the query...
query = ' or '.join(['tag=?']*len(tags))
gids = db.execute('select distinct object from tags where ' + query, tags).fetchall()
if opts.get('RETURN_GIDS', False):
return gids
return set([ objs[gid[0]] for gid in gids ])
# XXX rethink -- this makes one .any(...) request per tag which is
# bad if we have allot of tags...
def all(self, *tags, **opts):
'''
'''
db = self._db
objs = self._objects
##!!! this is not good, need to make a direct SQL select version of this...
res = self.any(tags[0])
for tag in tags[1:]:
res.intersection_update(self.any(tag))
return res
# XXX need to think more about this -- try to make it one request...
def none(self, *tags, **opts):
'''
'''
db = self._db
objs = self._objects
fail = [ e[0] for e in self.any(RETURN_GIDS=True, *tags) ]
# build the query...
query = ' and '.join(['(not object=?)']*len(fail))
gids = db.execute('select distinct object from tags where ' + query, fail).fetchall()
if opts.get('RETURN_GIDS', False):
return gids
return set([ objs[gid[0]] for gid in gids ])
#-----------------------------------------------------------------------
if __name__ == '__main__':
from pprint import pprint
ts = SQLiteTagset('test/sqlitetags.db')
for i in xrange(1000):
ts.tag(i, *str(i), NOCOMMIT=True)
ts.commit()
# any number that has either 1 or 9 digits
## pprint(ts.any(*'19'))
# any number that has only 1 and 9 digits
pprint(ts.all(*'19'))
# any number not containing any of 012345678 digits
pprint(ts.none(*'012345678'))
#=======================================================================
# vim:set ts=4 sw=4 nowrap :