)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"881d04f0eaee1b36715c943c5fc4f00de9bf8ce5","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Make user to nonlocal_user a 1:1 relationship"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"The table relationship between \u0027user\u0027 and \u0027nonlocal_user\u0027 should be"},{"line_number":10,"context_line":"1 to 1, which is consistent with \u0027user\u0027 to \u0027local_user\u0027. However, it\u0027s"},{"line_number":11,"context_line":"mistakenly 1 to many. This patch fixes this by making the user_id column"},{"line_number":12,"context_line":"unique."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Closes-Bug: #1649412"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"1a6eadb0_94005e03","line":11,"range":{"start_line":10,"start_character":57,"end_line":11,"end_character":21},"updated":"2016-12-14 11:19:13.000000000","message":"Is there a chance there are multiple \u0027nonlocal users\u0027 to a single \u0027user\u0027 in the database ? I am just making sure because we do not address that in the migration.\n\nIf not please document that at least in the commit message saying why the migrations are straightforward.","commit_id":"805785bd375edad47ed34435fc2a0e6cbf3a7cf6"}],"keystone/common/sql/contract_repo/versions/011_contract_user_id_unique_for_nonlocal_user.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6b8b40232e05ca3871366c6e96e9304868d02acf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"1a6eadb0_4e9952c3","updated":"2016-12-16 17:12:21.000000000","message":"why was this added to the contract repo? we\u0027re adding a new contraint, shouldn\u0027t that go in the expand repo? http://docs.openstack.org/developer/keystone/devref/development_best_practices.html#database-migrations","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"a9b6d438052e979833662005be612448c5f096bc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"1a6eadb0_ae99067b","in_reply_to":"1a6eadb0_4e9952c3","updated":"2016-12-16 17:16:03.000000000","message":"Hmm... I think of constraints as a form of contraction, as we\u0027re limiting data options. And this kind of operation typically has to go after a migration; not before (expand).","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"},{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"471112ff756abb3d94d03b30f1ca4eac2f4dfeb0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"1a6eadb0_5199f3c2","in_reply_to":"1a6eadb0_ae99067b","updated":"2016-12-16 17:37:09.000000000","message":"that\u0027s my understanding as well (Ron\u0027s)","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"}],"keystone/tests/unit/identity/test_backends.py":[{"author":{"_account_id":11022,"name":"Rodrigo Duarte Sousa","email":"rodrigodsousa@gmail.com","username":"rodrigods"},"change_message_id":"f4a7de84e68415723a8ce2654cf9057ecef79652","unresolved":false,"context_lines":[{"line_number":1351,"context_line":"        user_ref \u003d self._get_user_ref(new_nonlocal_user[\u0027id\u0027])"},{"line_number":1352,"context_line":"        self.assertIsNone(user_ref.local_user)"},{"line_number":1353,"context_line":""},{"line_number":1354,"context_line":"    def test_nonlocal_user_unique_user_id_constraint(self):"},{"line_number":1355,"context_line":"        user_ref \u003d unit.new_user_ref(domain_id\u003dCONF.identity.default_domain_id)"},{"line_number":1356,"context_line":"        user1 \u003d self.shadow_users_api.create_nonlocal_user(user_ref)"},{"line_number":1357,"context_line":"        # create 2nd user with the same user_id"}],"source_content_type":"text/x-python","patch_set":6,"id":"1a6eadb0_2b1bd61c","line":1354,"range":{"start_line":1354,"start_character":8,"end_line":1354,"end_character":52},"updated":"2016-12-13 15:49:51.000000000","message":"this test passes even if we remove the changes in this patch...","commit_id":"c12b70d7a5c8279f50a9dfdb7c8287ade8022808"},{"author":{"_account_id":17860,"name":"Samuel de Medeiros Queiroz","email":"samueldmq@gmail.com","username":"samueldmq"},"change_message_id":"b3a16f89ca099e52e5dc3c51b7266ce5918ea19e","unresolved":false,"context_lines":[{"line_number":1360,"context_line":"            \u0027name\u0027: uuid.uuid4().hex,"},{"line_number":1361,"context_line":"            \u0027user_id\u0027: user[\u0027id\u0027]"},{"line_number":1362,"context_line":"        }"},{"line_number":1363,"context_line":"        self.assertRaises(sql.DBDuplicateEntry, self._add_nonlocal_user,"},{"line_number":1364,"context_line":"                          nonlocal_user)"},{"line_number":1365,"context_line":""},{"line_number":1366,"context_line":"    def _add_nonlocal_user(self, nonlocal_user):"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a6eadb0_37b6a23d","line":1363,"range":{"start_line":1363,"start_character":48,"end_line":1363,"end_character":71},"updated":"2016-12-14 14:47:33.000000000","message":"any reason we do not call self.shadow_users_api.create_nonlocal_user ?","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"}],"keystone/tests/unit/test_sql_upgrade.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6b8b40232e05ca3871366c6e96e9304868d02acf","unresolved":false,"context_lines":[{"line_number":295,"context_line":"        table \u003d sqlalchemy.Table(table_name, self.metadata, autoload\u003dTrue)"},{"line_number":296,"context_line":"        return index_name in [idx.name for idx in table.indexes]"},{"line_number":297,"context_line":""},{"line_number":298,"context_line":"    def does_unique_constraint_exist(self, table_name, column_name):"},{"line_number":299,"context_line":"        inspector \u003d reflection.Inspector.from_engine(self.engine)"},{"line_number":300,"context_line":"        constraints \u003d inspector.get_unique_constraints(table_name)"},{"line_number":301,"context_line":"        for c in constraints:"}],"source_content_type":"text/x-python","patch_set":8,"id":"1a6eadb0_ae4f4632","line":298,"range":{"start_line":298,"start_character":8,"end_line":298,"end_character":36},"updated":"2016-12-16 17:12:21.000000000","message":"see comment below","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"6b8b40232e05ca3871366c6e96e9304868d02acf","unresolved":false,"context_lines":[{"line_number":442,"context_line":"                return True"},{"line_number":443,"context_line":"        return False"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def does_constraint_exist(self, table_name, constraint_name):"},{"line_number":446,"context_line":"        table \u003d sqlalchemy.Table(table_name, self.metadata, autoload\u003dTrue)"},{"line_number":447,"context_line":"        return constraint_name in [con.name for con in table.constraints]"},{"line_number":448,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"1a6eadb0_0e403a06","line":445,"range":{"start_line":445,"start_character":8,"end_line":445,"end_character":29},"updated":"2016-12-16 17:12:21.000000000","message":"we already had a function for to check constraints?","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"},{"author":{"_account_id":18338,"name":"Ron De Rose","email":"ronald.de.rose@intel.com","username":"derosenet"},"change_message_id":"b01212ba9a7da0122ba74b25a2521847de11dedb","unresolved":false,"context_lines":[{"line_number":442,"context_line":"                return True"},{"line_number":443,"context_line":"        return False"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def does_constraint_exist(self, table_name, constraint_name):"},{"line_number":446,"context_line":"        table \u003d sqlalchemy.Table(table_name, self.metadata, autoload\u003dTrue)"},{"line_number":447,"context_line":"        return constraint_name in [con.name for con in table.constraints]"},{"line_number":448,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"1a6eadb0_4e579257","line":445,"range":{"start_line":445,"start_character":8,"end_line":445,"end_character":29},"in_reply_to":"1a6eadb0_0e403a06","updated":"2016-12-16 17:23:28.000000000","message":"This checks all constraints; not specifically uniqueconstraints.","commit_id":"e3f55e7b54250f46f8ade623fe9d62586cf780be"}]}
