{ "info": { "author": "Sebastian Wehrmann", "author_email": "sw@gocept.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Database" ], "description": "===========\nObjectQuery\n===========\n\nObjectQuery is licensed under ZPL 2.1.\n\nCopyright 2007-2009 by `gocept gmbh & co. kg`_.\n\nObjectQuery enables you to query for persistent objects (e.g. objects in the\nZODB). This is done with a XPath-like language named Regular Path Expressions\n(RPE). ObjectQuery also includes indexstructures for performance reasons.\n\nIt uses SimpleParse_ to parse the RPE-query.\n\n\nPlease report bugs to `gocept project portal`_.\n\n.. _gocept gmbh & co. kg: http://www.gocept.com/\n.. _gocept project portal: https://intra.gocept.com/projects/projects/show/objectquery\n.. _SimpleParse: http://pypi.python.org/pypi/SimpleParse/\n\n\n==============================================\nQuerying objects with regular path expressions\n==============================================\n\nInitialization\n==============\n\nFirst load the test database. For more information about that, please have a\nlook inside objects.py.\n\n >>> from gocept.objectquery.tests.objects import *\n >>> import ZODB.MappingStorage\n >>> import ZODB\n >>> from gocept.objectquery.collection import ObjectCollection\n >>> storage = ZODB.MappingStorage.MappingStorage()\n >>> db = ZODB.DB(storage)\n >>> conn = db.open()\n >>> dbroot = conn.root()\n >>> dbroot['_oq_collection'] = objects = ObjectCollection(conn)\n >>> import transaction\n >>> import gocept.objectquery.indexsupport\n >>> index_synch = gocept.objectquery.indexsupport.IndexSynchronizer()\n >>> transaction.manager.registerSynch(index_synch)\n\n >>> p_orwell = Person(name=\"George Orwell\")\n >>> p_lotze = Person(name=\"Thomas Lotze\")\n >>> p_goethe = Person(name=\"Johann Wolfgang von Goethe\")\n >>> p_weitershausen = Person(name=\"Philipp von Weitershausen\")\n\n >>> b_1984 = Book(author=p_orwell,\n ... title=\"1984\",\n ... written=1990,\n ... isbn=3548234100)\n >>> b_plone = Book(author=p_lotze,\n ... title=\"Plone-Benutzerhandbuch\",\n ... written=2008,\n ... isbn=3939471038)\n >>> b_faust = Book(author=p_goethe,\n ... title=\"Faust\",\n ... written=1811,\n ... isbn=3406552501)\n >>> b_farm = Book(author=p_orwell,\n ... title=\"Farm der Tiere\",\n ... written=2002,\n ... isbn=3257201184)\n >>> b_zope = Book(author=p_weitershausen,\n ... title=\"Web Component Development with Zope 3\",\n ... written=2007,\n ... isbn=3540338071)\n\n >>> l_halle = Library(location=\"Halle\",\n ... books=[b_1984, b_plone, b_farm, b_zope])\n >>> l_berlin = Library(location=\"Berlin\",\n ... books=[b_1984, b_plone, b_faust, b_farm, b_zope])\n >>> l_chester = Library(location=\"Chester\",\n ... books=[b_1984, b_faust, b_farm])\n\n >>> dbroot['librarydb'] = persistent.list.PersistentList()\n >>> dbroot['librarydb'].extend([l_halle, l_berlin, l_chester])\n\n >>> librarydb = dbroot['librarydb']\n >>> transaction.commit()\n\n >>> from pprint import pprint\n\nCreate QueryProcessor and initialize the ObjectCollection\n=========================================================\n\nYou create a QueryProcessor like this:\n\n >>> from gocept.objectquery.pathexpressions import RPEQueryParser\n >>> from gocept.objectquery.processor import QueryProcessor\n >>> parser = RPEQueryParser()\n >>> query = QueryProcessor(parser, objects)\n >>> query\n \n\nSome example usecases\n---------------------\n\nRoot joins:\n\n >>> r = query('/PersistentList/Library')\n >>> sorted(elem.location for elem in r)\n ['Berlin', 'Chester', 'Halle']\n\nSearch for the authors of all Books named \"Faust\":\n\n >>> r = query('/PersistentList/Library/Book[@title=\"Faust\"]/Person')\n >>> sorted(elem.name for elem in r)\n ['Johann Wolfgang von Goethe']\n\nSearch for all books written after year 2000:\n\n >>> r = query('/PersistentList/Library/Book[@written>=2000]')\n >>> len(r)\n 3\n >>> pprint(sorted(elem.title for elem in r))\n ['Farm der Tiere',\n 'Plone-Benutzerhandbuch',\n 'Web Component Development with Zope 3']\n\nSearch for all authors of books written after year 2000:\n\n >>> r = query('/PersistentList/Library/Book[@written>=2000]/Person')\n >>> len(r)\n 3\n >>> pprint(sorted(elem.name for elem in r))\n ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']\n\nSearch for all Books, that have are located in Halle and have been written in\n2007:\n\n >>> r = query('/PersistentList/Library[@location=\"Halle\"]/Book[@written==2007]')\n >>> sorted((elem.title, elem.isbn) for elem in r)\n [('Web Component Development with Zope 3', 3540338071L)]\n\nHandle Wildcards correctly:\n\n >>> r = query('/PersistentList/Library/_/Person')\n >>> pprint(sorted(elem.name for elem in r))\n ['George Orwell',\n 'Johann Wolfgang von Goethe',\n 'Philipp von Weitershausen',\n 'Thomas Lotze']\n\nInstead of only providing the classname, it is also possible to provide the\nclass with its full module:\n\n >>> r = query('/PersistentList/gocept.objectquery.tests.objects.Library')\n >>> pprint([library.location for library in r])\n ['Halle', 'Berlin', 'Chester']\n >>> query('/PersistentList/gocept.objectquery.tests.objects2.Library')\n []\n\nWhat about precedence:\n\n >>> r = query('/PersistentList/Library[@location=\"Halle\"]/Book/Person')\n >>> pprint(sorted(elem.name for elem in r))\n ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']\n\n >>> r = query('(/PersistentList/Library[@location=\"Halle\"]/Book)/Person')\n >>> pprint(sorted(elem.name for elem in r))\n ['George Orwell', 'Philipp von Weitershausen', 'Thomas Lotze']\n\n >>> r = query('/PersistentList/Library[@location=\"Halle\"]/(Book/Person)')\n >>> len(r)\n 0\n >>> r = query('(/PersistentList/Library/Book[@title=\"Faust\"])/(Book/Person)')\n >>> sorted(elem.name for elem in r)\n ['Johann Wolfgang von Goethe']\n\nBut pay attention. If you change the query from ..\"]/(Book.. to ..\"](/Book..\nyou get an Library-Result with location in \"Halle\". This is, because the\nsubquery (in brakets) returns no results:\n\n >>> r = query('/PersistentList/Library[@location=\"Halle\"](/Book/Person)')\n >>> len(r)\n 1\n >>> r[0].location\n 'Halle'\n\nUnions:\n\n >>> r = query('(/PersistentList/Library[@location=\"Halle\"])|(Book/Person)')\n >>> len(r)\n 5\n >>> pprint(sorted(elem for elem in r))\n [,\n ,\n ,\n ,\n ]\n\n >>> r = query('(/PersistentList/Library)|(Book[@written=1990])')\n >>> len(r)\n 4\n >>> pprint(sorted(elem for elem in r))\n [,\n ,\n ,\n ]\n\n >>> transaction.commit()\n\nKleene Closure\n--------------\n\nFirst we need a new database:\n\n >>> doc1 = Document()\n >>> doc2 = Document()\n >>> doc3 = Document()\n >>> fol4 = Folder([doc2])\n >>> fol3 = Folder([doc1])\n >>> fol2 = Folder([fol3])\n >>> fol1 = Folder([fol2])\n >>> plo1 = Plone([fol1, fol4, doc3])\n >>> root = Root([plo1])\n\n >>> dbroot['test'] = root\n >>> transaction.commit()\n\nNow there should be one Plone object under root:\n\n >>> r = query('/Root/Plone')\n >>> len(r) == 1 and r[0] == plo1\n True\n\n >>> r = query('/Root/Plone/Folder/Document')\n >>> len(r)\n 1\n >>> r[0] == doc2\n True\n\nGet all Documents which are under any number of Folders:\n\n >>> r = query('/Root/Plone/Folder*/Document')\n >>> r[0] != r[1] != r[2] and isinstance(r[0], Document)\n True\n\n >>> r = query('Plone/Folder*/Document')\n >>> r[0] != r[1] != r[2] and isinstance(r[0], Document)\n True\n\n >>> r = query('Folder*/Document')\n >>> r[0] != r[1] != r[2] and isinstance(r[0], Document)\n True\n\nGet all Documents which are under one or zero number of Folders:\n\n >>> r = query('/Root/Plone/Folder?/Document')\n >>> len(r) == 2 and (r[0] == doc2 or r[1] == doc2) and (r[0] == doc3 or r[1] == doc3) and r[0] != r[1]\n True\n\n >>> r = query('Folder?/Document')\n >>> len(r) == 3 and r[0] != r[1] != r[2]\n True\n\nGet all Documents which are under one or more number of Folders:\n\n >>> r = query('/Root/Plone/Folder+/Document')\n >>> len(r) == 2 and (r[0] == doc1 or r[1] == doc1) and (r[0] == doc2 or r[1] == doc2) and r[0] != r[1]\n True\n\n >>> r = query('Folder+/Document')\n >>> len(r) == 2 and (r[0] == doc1 or r[1] == doc1) and (r[0] == doc2 or r[1] == doc2) and r[0] != r[1]\n True\n\nYou may also query absolute path lengths:\n\n >>> len(query('Plone/Document'))\n 1\n >>> len(query('Plone/Folder/Document'))\n 1\n >>> len(query('Plone/Folder/Folder/Document'))\n 0\n >>> len(query('Plone/Folder/Folder/Folder/Document'))\n 1\n\nFurthermore, it is possible to query all Documents, which are located under 2\nor more Folders:\n\n >>> r = query('Plone/Folder+/Folder/Document')\n >>> len(r) == 1 and r[0] == doc1\n True\n\n >>> r = query('Plone/Folder/Folder+/Document')\n >>> len(r) == 1 and r[0] == doc1\n True\n\nA special case is the combination of wildcard and '*' closure:\n\n >>> r = query('Plone/_*/Document')\n >>> len(r) == 3\n True\n\n\n=======\nCHANGES\n=======\n\n\n0.1b1 (2009-08-13)\n==================\n\n- Add support for windows by adding a SimpleParse egg.\n- Use sw.objectinspection instead of `ObjectParser` to inspect objects for\n attributes and children. This brings much more flexibility in inspecting\n custom objects.\n\n\n0.1b (2009-07-23)\n=================\n\n- Small API refactorings (#5780)\n- Add support for querying for classes of a given module (#5778).\n- Add support for querying for base classes of objects (#4880).\n\n\n0.1a2 (2009-06-17)\n==================\n\n- Better handling of unpersistent objects.\n\n\n0.1a1 (2009-06-05)\n==================\n\n- Stop ignoring callable objects (e.g. a Plone site) for indexing, just once\n ignore methods.\n\n- Do not break during indexing if added object is not added to the ZODB\n (doesn't have the `_p_oid` attribute). Those objects are ignored for now\n and not added to the index structures. \n\n- Add ``rindex`` method for adding objects to the collection recursively.\n\n- Add SimpleParse as a 3rdparty egg because it can't be retrieved from pypi\n for some months now.\n\n\n0.1pre (2009-02-04)\n===================\n\n - first alpha release\n\n\n0.1pre (2008-08-19)\n===================\n\n - initial functionality based on the work from the `diploma thesis`_\n\n\n.. _diploma thesis: http://archiv.tu-chemnitz.de/pub/2008/0081/data/diplomarbeit.pdf", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://intra.gocept.com/projects/projects/show/objectquery", "keywords": null, "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "gocept.objectquery", "package_url": "https://pypi.org/project/gocept.objectquery/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/gocept.objectquery/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://intra.gocept.com/projects/projects/show/objectquery" }, "release_url": "https://pypi.org/project/gocept.objectquery/0.1b1/", "requires_dist": null, "requires_python": null, "summary": "A framework for indexing and querying the ZODB", "version": "0.1b1" }, "last_serial": 792570, "releases": { "0.1a": [ { "comment_text": "", "digests": { "md5": "f66a17590ffcfcb680a17a785b9ba7c9", "sha256": "e4d85f97cc90bfdce115348ea350a130d7a759b6b59a0555c59803db6efc0925" }, "downloads": -1, "filename": "gocept.objectquery-0.1a.tar.gz", "has_sig": false, "md5_digest": "f66a17590ffcfcb680a17a785b9ba7c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24926, "upload_time": "2009-02-04T11:55:02", "url": "https://files.pythonhosted.org/packages/ab/68/9c32d78b443454259a0e3bcb507973ec5dc57df64e2386c43555d0c186aa/gocept.objectquery-0.1a.tar.gz" } ], "0.1a1": [ { "comment_text": "", "digests": { "md5": "cf8d76d77cdb4d1ecbca342579615290", "sha256": "04fed2624834838303eaca65a785d8486f4df837c734708c72d614dc54b6ca60" }, "downloads": -1, "filename": "gocept.objectquery-0.1a1.tar.gz", "has_sig": false, "md5_digest": "cf8d76d77cdb4d1ecbca342579615290", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 411990, "upload_time": "2009-06-05T20:45:08", "url": "https://files.pythonhosted.org/packages/ad/23/06f6004ed9d94f50ebc5451a904eac5337a61fc52ebd529aed7d8e7f75d2/gocept.objectquery-0.1a1.tar.gz" } ], "0.1a2": [ { "comment_text": "", "digests": { "md5": "af7b59d173824db919f93524292daa85", "sha256": "7ae1723a58dbc833b4354a7f26b57bf59c61956d6054d7b362f0919eca2bde8f" }, "downloads": -1, "filename": "gocept.objectquery-0.1a2.tar.gz", "has_sig": false, "md5_digest": "af7b59d173824db919f93524292daa85", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 412369, "upload_time": "2009-06-18T08:09:08", "url": "https://files.pythonhosted.org/packages/75/2e/cb59a6c64f0186c8a0bcbdd1f76a62469c174586d23ed05a08280ace9219/gocept.objectquery-0.1a2.tar.gz" } ], "0.1b": [ { "comment_text": "", "digests": { "md5": "6c5301406c912d75a5c872aae80dbf40", "sha256": "1c7424cff7cea45afe2f62106abb17361b0e6516fcf9148c08487375ee4f44fb" }, "downloads": -1, "filename": "gocept.objectquery-0.1b.tar.gz", "has_sig": false, "md5_digest": "6c5301406c912d75a5c872aae80dbf40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 411861, "upload_time": "2009-07-23T16:34:59", "url": "https://files.pythonhosted.org/packages/c6/d3/edcecd22fba607c166894095553e6ff45b4bd6805003e0052b1a08962525/gocept.objectquery-0.1b.tar.gz" } ], "0.1b1": [ { "comment_text": "", "digests": { "md5": "e9e7593b6e28c4e43784265507946c41", "sha256": "c1b23e3119d251d35cf318bd4187b8d45a4b6269664b4c59bc353c384da13b89" }, "downloads": -1, "filename": "gocept.objectquery-0.1b1.tar.gz", "has_sig": true, "md5_digest": "e9e7593b6e28c4e43784265507946c41", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 793241, "upload_time": "2009-08-13T16:33:10", "url": "https://files.pythonhosted.org/packages/75/c3/f56a22f34675c1c620bd2d927aa6d232fbb230f6c7d94fb6f193af0bf7fe/gocept.objectquery-0.1b1.tar.gz" } ], "0.1dev": [] }, "urls": [ { "comment_text": "", "digests": { "md5": "e9e7593b6e28c4e43784265507946c41", "sha256": "c1b23e3119d251d35cf318bd4187b8d45a4b6269664b4c59bc353c384da13b89" }, "downloads": -1, "filename": "gocept.objectquery-0.1b1.tar.gz", "has_sig": true, "md5_digest": "e9e7593b6e28c4e43784265507946c41", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 793241, "upload_time": "2009-08-13T16:33:10", "url": "https://files.pythonhosted.org/packages/75/c3/f56a22f34675c1c620bd2d927aa6d232fbb230f6c7d94fb6f193af0bf7fe/gocept.objectquery-0.1b1.tar.gz" } ] }