diff --git a/ImageGrid.otl b/ImageGrid.otl index a2a5991b..8c39ce1d 100755 --- a/ImageGrid.otl +++ b/ImageGrid.otl @@ -30,6 +30,12 @@ Concepts URL structure + configuration (archive-wide) + general settings + actions + scripts + remote refs + clone settings index (metadata) data diff --git a/sqlitetags.py b/sqlitetags.py new file mode 100755 index 00000000..00297ce2 --- /dev/null +++ b/sqlitetags.py @@ -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 :