)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":10046,"name":"Henrique Truta","email":"henrique@lsd.ufcg.edu.br","username":"henriquetruta"},"change_message_id":"09e41a1dd32cd1c33b3cc345271e4a85080fdc91","unresolved":false,"context_lines":[{"line_number":7,"context_line":"SQLAlchemy column type for materialized path"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The column type converting array of strings to a flat string to store in the"},{"line_number":10,"context_line":"database, ang from the flat string to an array of strings on retrieval."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Implements bp materialized-path-column"},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"5a710552_766f0693","line":10,"updated":"2015-12-14 18:18:29.000000000","message":"nit: and","commit_id":"4526f26502eb8db5a3072ed94127e7420f928f8b"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"1593e464c087b05b85eaf02b6a20f55e9cbf38c7","unresolved":false,"context_lines":[{"line_number":10,"context_line":"in the database, and from the flat string to an array of strings on"},{"line_number":11,"context_line":"retrieval."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Implements bp materialized-path-column"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I490c0f728532939d92110b08f130b5cd0a07034e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"7a5de9d1_5f9e7357","line":13,"range":{"start_line":13,"start_character":14,"end_line":13,"end_character":38},"updated":"2016-01-27 21:58:37.000000000","message":"so there is no spec (i can find for this). I think there is a perfectly legitimate case for this to improve performance of assignments in hierarchies. Maybe raise a defect to that affect and ties this set to that?","commit_id":"b7a913e7296b04ce176394000ed9e4c7d110af30"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"81c0bdb5e9fe8e6b6c469b2918798a889e5f40cf","unresolved":false,"context_lines":[{"line_number":10,"context_line":"in the database, and from the flat string to an array of strings on"},{"line_number":11,"context_line":"retrieval."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"Implements bp materialized-path-column"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I490c0f728532939d92110b08f130b5cd0a07034e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":13,"id":"7a5de9d1_b400e9ab","line":13,"range":{"start_line":13,"start_character":14,"end_line":13,"end_character":38},"in_reply_to":"7a5de9d1_5f9e7357","updated":"2016-01-28 17:41:51.000000000","message":"The spec for the following blueprint materialize-project-hierarchy is http://specs.openstack.org/openstack/keystone-specs/specs/backlog/materialize-project-hierarchy.html\n\nThis patch implements the very basic abstraction allowing to store required data in the right way.","commit_id":"b7a913e7296b04ce176394000ed9e4c7d110af30"}],"keystone/common/sql/core.py":[{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"7a1ebc068099b2f4f168ae3f969d9d4bfb6707ab","unresolved":false,"context_lines":[{"line_number":434,"context_line":"class MaterializedPathType(sql_types.TypeDecorator):"},{"line_number":435,"context_line":"    \"\"\"Column type to store string array as a flat string\"\"\""},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    DELIMITER \u003d \u0027/\u0027"},{"line_number":438,"context_line":"    impl \u003d sql.Text"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"    def process_bind_param(self, value, dialect):"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa69d971_43ba15e3","line":437,"range":{"start_line":437,"start_character":4,"end_line":437,"end_character":19},"updated":"2015-12-30 21:18:12.000000000","message":"So I assume at some point in the patch chain we will require the url_safeness to be set to \"strict\"...which means than we know the \u0027/\u0027 can\u0027t be in a project or domain name...?","commit_id":"7ab45049c35ee50e478f9b22a6d2cd2da201ffdb"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"a558b4f015549e5aa3123d79684b590b0217e270","unresolved":false,"context_lines":[{"line_number":434,"context_line":"class MaterializedPathType(sql_types.TypeDecorator):"},{"line_number":435,"context_line":"    \"\"\"Column type to store string array as a flat string\"\"\""},{"line_number":436,"context_line":""},{"line_number":437,"context_line":"    DELIMITER \u003d \u0027/\u0027"},{"line_number":438,"context_line":"    impl \u003d sql.Text"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"    def process_bind_param(self, value, dialect):"}],"source_content_type":"text/x-python","patch_set":11,"id":"da6ed579_f0b5f17d","line":437,"range":{"start_line":437,"start_character":4,"end_line":437,"end_character":19},"in_reply_to":"fa69d971_43ba15e3","updated":"2016-01-18 16:39:25.000000000","message":"Good point, I think I should add this check right in this patch.","commit_id":"7ab45049c35ee50e478f9b22a6d2cd2da201ffdb"}],"keystone/tests/unit/common/test_sql_core.py":[{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"be330abd0791c7e27527f48c55c27b5c2bdd9860","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import six"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from sqlalchemy.ext import declarative"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystone.common import sql"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_885b132e","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":0},"updated":"2015-12-17 22:40:27.000000000","message":"no whitespace needed between `six` and `from sqlalchemy.ext import declarative`\n\nboth of them are third party dependencies.","commit_id":"89c8a9dec594686dbdc80faad74350c63aa72719"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"8c5dbc5e8e12740564904b0ff05fcc0b66956681","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"import six"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"from sqlalchemy.ext import declarative"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"from keystone.common import sql"}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_6c92dba1","line":14,"range":{"start_line":14,"start_character":0,"end_line":14,"end_character":0},"in_reply_to":"3a7e1126_885b132e","updated":"2015-12-22 13:11:11.000000000","message":"Done","commit_id":"89c8a9dec594686dbdc80faad74350c63aa72719"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"be330abd0791c7e27527f48c55c27b5c2bdd9860","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    def setUp(self):"},{"line_number":71,"context_line":"        super(TestMaterializedPathColumn, self).setUp()"},{"line_number":72,"context_line":"        self.useFixture(database.Database())"},{"line_number":73,"context_line":"        self.load_backends()"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        ExampleWithPathColumn.__table__.create(sql.get_engine())"},{"line_number":76,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_6b834105","line":73,"range":{"start_line":73,"start_character":13,"end_line":73,"end_character":26},"updated":"2015-12-17 22:40:27.000000000","message":"remove this line, you needn\u0027t load backends here. If this was needed by the follow-up patches add this line in the follow up.","commit_id":"89c8a9dec594686dbdc80faad74350c63aa72719"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"8c5dbc5e8e12740564904b0ff05fcc0b66956681","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    def setUp(self):"},{"line_number":71,"context_line":"        super(TestMaterializedPathColumn, self).setUp()"},{"line_number":72,"context_line":"        self.useFixture(database.Database())"},{"line_number":73,"context_line":"        self.load_backends()"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"        ExampleWithPathColumn.__table__.create(sql.get_engine())"},{"line_number":76,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_4cc35f8b","line":73,"range":{"start_line":73,"start_character":13,"end_line":73,"end_character":26},"in_reply_to":"3a7e1126_6b834105","updated":"2015-12-22 13:11:11.000000000","message":"Done","commit_id":"89c8a9dec594686dbdc80faad74350c63aa72719"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"be330abd0791c7e27527f48c55c27b5c2bdd9860","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        self.assertFalse(node.path1)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def test_path_column_stores_array_as_string_and_returns_array(self):"},{"line_number":98,"context_line":"        \"\"\"Stored and returned value are lists, background type is string\"\"\""},{"line_number":99,"context_line":"        node \u003d self._create_node()"},{"line_number":100,"context_line":"        example \u003d [utils.new_uuid(), utils.new_uuid()]"},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_ab4b6986","line":98,"range":{"start_line":98,"start_character":22,"end_line":98,"end_character":30},"updated":"2015-12-17 22:40:27.000000000","message":"Stored as a flat string but returned value is list?","commit_id":"89c8a9dec594686dbdc80faad74350c63aa72719"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"8c5dbc5e8e12740564904b0ff05fcc0b66956681","unresolved":false,"context_lines":[{"line_number":95,"context_line":"        self.assertFalse(node.path1)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def test_path_column_stores_array_as_string_and_returns_array(self):"},{"line_number":98,"context_line":"        \"\"\"Stored and returned value are lists, background type is string\"\"\""},{"line_number":99,"context_line":"        node \u003d self._create_node()"},{"line_number":100,"context_line":"        example \u003d [utils.new_uuid(), utils.new_uuid()]"},{"line_number":101,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"3a7e1126_acf683f7","line":98,"range":{"start_line":98,"start_character":22,"end_line":98,"end_character":30},"in_reply_to":"3a7e1126_ab4b6986","updated":"2015-12-22 13:11:11.000000000","message":"yes","commit_id":"89c8a9dec594686dbdc80faad74350c63aa72719"},{"author":{"_account_id":13063,"name":"WEI CHEN","email":"dave.jungler@gmail.com","username":"wei.d.chen"},"change_message_id":"1ec99ff66c14b1c815de50895bebf64f170366f2","unresolved":false,"context_lines":[{"line_number":93,"context_line":"        self.assertFalse(node.path1)"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"    def test_path_column_stores_array_as_string_and_returns_array(self):"},{"line_number":96,"context_line":"        \"\"\"Stored and returned values are lists, background type is string\"\"\""},{"line_number":97,"context_line":"        node \u003d self._create_node()"},{"line_number":98,"context_line":"        example \u003d [utils.new_uuid(), utils.new_uuid()]"},{"line_number":99,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_6f92cda1","line":96,"range":{"start_line":96,"start_character":0,"end_line":96,"end_character":77},"updated":"2015-12-22 13:31:02.000000000","message":"it makes me think the stored value is list but it actually a flat string, suggest to reword the docstring here.","commit_id":"37516dc3a46d1900e63ff5b86e38e044dc911dea"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"02bc283f1551984819bb4abbf1736400f1b28a15","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            node.path1 \u003d node.path1 + [utils.new_uuid()]"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        instance \u003d self.session.query(ExampleWithPathColumn).one()"},{"line_number":130,"context_line":"        self.assertEqual(example2, instance.path2)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa69d971_a300b1ab","line":130,"range":{"start_line":130,"start_character":8,"end_line":130,"end_character":50},"updated":"2015-12-30 21:15:23.000000000","message":"for completeness, it might be good to check that path1 has been updated","commit_id":"7ab45049c35ee50e478f9b22a6d2cd2da201ffdb"},{"author":{"_account_id":13055,"name":"Alexander Makarov","email":"ajiekcahdp.makapob@gmail.com","username":"amakarov"},"change_message_id":"a558b4f015549e5aa3123d79684b590b0217e270","unresolved":false,"context_lines":[{"line_number":127,"context_line":"            node.path1 \u003d node.path1 + [utils.new_uuid()]"},{"line_number":128,"context_line":""},{"line_number":129,"context_line":"        instance \u003d self.session.query(ExampleWithPathColumn).one()"},{"line_number":130,"context_line":"        self.assertEqual(example2, instance.path2)"}],"source_content_type":"text/x-python","patch_set":11,"id":"da6ed579_1070c5db","line":130,"range":{"start_line":130,"start_character":8,"end_line":130,"end_character":50},"in_reply_to":"fa69d971_a300b1ab","updated":"2016-01-18 16:39:25.000000000","message":"Done","commit_id":"7ab45049c35ee50e478f9b22a6d2cd2da201ffdb"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"69fb87acd3862c1ca18e44d72675eab25271c4c1","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # Tests"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    @staticmethod"},{"line_number":87,"context_line":"    def _create_node():"},{"line_number":88,"context_line":"        \"\"\"Test node creation shortcut\"\"\""},{"line_number":89,"context_line":"        node \u003d ExampleWithPathColumn(id\u003dutils.new_uuid())"},{"line_number":90,"context_line":"        return node"}],"source_content_type":"text/x-python","patch_set":13,"id":"7a5de9d1_31cf2bb2","line":87,"range":{"start_line":87,"start_character":8,"end_line":87,"end_character":20},"updated":"2016-01-27 22:18:30.000000000","message":"I find the term \"node\" confusing here...what\u0027s the rationale for that?","commit_id":"b7a913e7296b04ce176394000ed9e4c7d110af30"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"1593e464c087b05b85eaf02b6a20f55e9cbf38c7","unresolved":false,"context_lines":[{"line_number":92,"context_line":"    def test_create_node(self):"},{"line_number":93,"context_line":"        \"\"\"Created node has empty path\"\"\""},{"line_number":94,"context_line":"        node \u003d self._create_node()"},{"line_number":95,"context_line":"        self.assertFalse(node.path1)"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    def test_path_column_stores_array_as_string_and_returns_array(self):"},{"line_number":98,"context_line":"        \"\"\"Value is represented as list, stored as string\"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a5de9d1_df3103ee","line":95,"range":{"start_line":95,"start_character":8,"end_line":95,"end_character":36},"updated":"2016-01-27 21:58:37.000000000","message":"for completness, you might as well check node.path2 as well","commit_id":"b7a913e7296b04ce176394000ed9e4c7d110af30"},{"author":{"_account_id":5707,"name":"Henry Nash","email":"henryn@linux.vnet.ibm.com","username":"henry-nash"},"change_message_id":"1593e464c087b05b85eaf02b6a20f55e9cbf38c7","unresolved":false,"context_lines":[{"line_number":104,"context_line":"            node.path1 \u003d example"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        rows \u003d self.session.connection().execute("},{"line_number":107,"context_line":"            sql.sql.text(\"select id, path1 from examplewithpathcolumn\")"},{"line_number":108,"context_line":"        )"},{"line_number":109,"context_line":"        self.assertIsInstance(list(rows)[0][\u0027path1\u0027], six.text_type)"},{"line_number":110,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"7a5de9d1_df48235e","line":107,"range":{"start_line":107,"start_character":12,"end_line":107,"end_character":71},"updated":"2016-01-27 21:58:37.000000000","message":"is there a reason to execute raw sql here? we try and avoid that...","commit_id":"b7a913e7296b04ce176394000ed9e4c7d110af30"}]}
